二阶非齐次微分方程竖式解法(基本型)求解器(不支持复数运算)

221 阅读2分钟

「这是我参与2022首次更文挑战的第16天,活动详情查看:2022首次更文挑战

修改版

以前大一的时候数学老师叫我们写的一个解法器,当然这个可不是人家pytorch的梯度实现。

TIPS

算法使用python编写,基本上除了GUI库,不使用任何第三方数学库. 关于竖式解法请参考如下视频: 链接:pan.baidu.com/s/1Vynxkqse… 提取码:6666

代码

代码部分不多比比,很多变量都是直接使用中文拼音写的,不存在看不懂的问题.如果看不懂,请仔细查看上面的解法链接,或者复习python.

#coding = 'utf-8'
import tkinter as tk
class Root(object):
    def __init__(self,root):
        self.root = root
        self.root.title("二阶非齐竖式基本微分方程求解器")
        self.root.geometry("350x250")
        self.root.resizable(width=False,height=False)
        self.tips = tk.StringVar()
    def Label(self):
        Label_IN = tk.Label(self.root,text="Input a integer:",fg='red',font=("宋体",10))
        Label_IN.place(x=20,y=20,width=110,heigh=20)
        tips_code = '''目前不支持复数求解,按照示例格式输入方程:\ny''+-3*y'+0*y=e^2*x*(6*x^3+-15*x^2+0*x+0),英文符号'''
        Label_TIPS = tk.Label(self.root,font=("宋体",10),text=tips_code,justify='left',fg='red')
        Label_TIPS.place(x=0,y=205,width=350,height=40)
    def B_E_Menu(self):
        self.IN_Get = tk.Entry(self.root,font=('宋体', 12),fg='gray',relief='solid',textvariable=self.tips)
        self.IN_Get.place(x=130,y=20,height=25,width=200)
        self.Show_AN = tk.Label(self.root,fg='red',font=("宋体",10),bg='blue')
        self.Show_AN.place(x=0,y=50,height=80,width=350)
        self.Check_B = tk.Button(self.root,text='Check',font=("宋体",12))
        self.Check_B.place(x=90,y=180,height=20,width=60)
        self.Quit_B = tk.Button(self.root,text='Quit',font=("宋体",12))
        self.Quit_B.place(x=180,y=180,height=20,width=60)
class Tools(object):
    def QiuDao_F(self,nn):
        if "*" in nn and "^" in nn:
            l1 = nn.split('*')[0]
            l2 = nn.split('^')[1]
            get_s = str(float(l1)*float(l2))+'*x'+'^'+str(float(l2)-1)
            return get_s
        else:
            if '*' in nn:
                get_s = nn.split('*')[0]
                return get_s

            elif '^' in nn:
                l2 = nn.split('^')[1]
                get_s = l2+'*x^'+str(float(l2)-1)
                return get_s
            elif nn == 'x':
                return '1'
            else:
                return '0'

    def JianDao_F(self,a,b):
        if '*' in a and '*' in b:
            l1 = a.split('*')[0]

            l2 = b.split('*')[0]
            l3 = str(float(l1)-float(l2))+'*'+a.split('*')[1]
            return l3
        else:
            return str(float(a)-float(b))
    def ChuDao_F(self,x,lmd):
        if 'x'==x:
            return str(1/lmd)
        if '*' in x:
            l1 = x.split('*')
            l2 = '{:,.2f}'.format(float(l1[0])/lmd)
            get_s = l2+'*'+l1[1]
            return get_s
        else:
            return '{:,.2f}'.format(float(x)/lmd)


    def GET_GO(self,Need_Do,lmd):
        global star, g, end
        g = ''
        nn = Need_Do.split('+')
        star = 0
        end = len(nn)-1
        ll1=self.ChuDao_F(nn[0],lmd)
        g+=ll1
        def ADD_F(ll1):
            global star,g,end
            if star==end:
                return g
            ll2=self.QiuDao_F(ll1)
            ll3=self.JianDao_F(nn[star+1],ll2)
            ll4=self.ChuDao_F(ll3,lmd)
            g+='+'+ll4
            star+=1
            ADD_F(ll4)
        ADD_F(ll1)
        return g


def GetABC(x):
    if '*' not in x:
        return 1.0
    else:
        return float(x.split('*')[0])

def ANSW_GET(y):
    Tool = Tools()
    QiChi = y.split('=')[0]
    FeiQiChi = y.split('=')[1]
    R_E  = FeiQiChi.split('(')[0]
    if R_E:
        Lmd = R_E.split('^')[1]
        Lmd = float(Lmd.split('*')[0])
    else:
        Lmd = 0

    Need_Do = FeiQiChi.split('(')[1].rstrip(')')

    a,b,c = map(GetABC,QiChi.split('+'))
    def TUX(a,b,c):
        N = (b**2)-4*(a*c)
        if N>=0:
            return (N**0.5)
        else:
            return 0

    Tux = TUX(a,b,c)
    if Tux:
        x1 = (-b+Tux)/(2*a)
        x2 = (-b-Tux)/(2*a)
        if x1 == x2:
            Omg = Lmd - x1
            g = Tool.GET_GO(Need_Do,Omg)
            s = 'y*='+R_E+'('+g+')'+'\nx = {}'.format(x1)
            return s
        else:
            Omg1 = Lmd - x1
            Omg2 = Lmd - x2
            if Omg1 <= Omg2:
                Omgp = Omg1
                Omg1 = Omg2
                Omg2 = Omgp
                g0= Tool.GET_GO(Need_Do, Omg1)
                g = Tool.GET_GO(g0,Omg2)
                s ='y*='+ R_E + '(' + g + ')'+'\nx1 = {},x2 = {}'.format(x1,x2)
                return s

    else:
        return 0
def Check_Go(xincan):
    print(Win.IN_Get.get())
    y = Win.IN_Get.get()
    s = ANSW_GET(y)
    if s:
        Win.Show_AN.configure(text=s,font=("宋体",10))
    else:
        Win.Show_AN.configure(text='抱歉目前不支持此类方程求解',font=("宋体",15))
def Quit_Go(xincan):
    Win.Show_AN.configure(text='',font=("宋体",10))
    Win.tips.set('')
    Win.IN_Get.config(fg='black', textvariable=Win.tips)

if __name__=='__main__':
    root=tk.Tk()
    Win = Root(root)
    Win.Label()
    Win.B_E_Menu()
    Win.Check_B.bind("<Button-1>",lambda a :Check_Go('0'))
    Win.Quit_B.bind("<Button-1>", lambda a: Quit_Go('0'))
    root.mainloop()


效果

在这里插入图片描述