Python Fmin can';t将表达式转换为浮点

Python Fmin can';t将表达式转换为浮点,python,scipy,sympy,Python,Scipy,Sympy,我写了一个程序,首先计算逆拉普拉斯变换,然后计算最小二乘,最后应该最小化这些平方和。不幸的是,我得到了这个错误: Traceback (most recent call last): File "C:/program.py", line 46, in <module> LSQminsearch(f, TF, 0.5, 0.5, 0.5, 0.5) File "C:/program.py", line 36, in LSQminsearch res = opti

我写了一个程序,首先计算逆拉普拉斯变换,然后计算最小二乘,最后应该最小化这些平方和。不幸的是,我得到了这个错误:

Traceback (most recent call last):
  File "C:/program.py", line 46, in <module>
    LSQminsearch(f, TF, 0.5, 0.5, 0.5, 0.5)
  File "C:/program.py", line 36, in LSQminsearch
    res = optimize.fmin(f, [k0, dzeta0, tau0, tauz0], maxiter = 100000000, maxfun=1000000)
  File "C:\Users\xyz\AppData\Local\Programs\Python\Python38-32\lib\site-packages\scipy\optimize\optimize.py", line 443, in fmin
    res = _minimize_neldermead(func, x0, args, callback=callback, **opts)
  File "C:\Users\xyz\AppData\Local\Programs\Python\Python38-32\lib\site-packages\scipy\optimize\optimize.py", line 586, in _minimize_neldermead
    fsim[k] = func(sim[k])
  File "C:\Users\xyz\AppData\Local\Programs\Python\Python38-32\lib\site-packages\sympy\core\expr.py", line 325, in __float__
    raise TypeError("can't convert expression to float")
TypeError: can't convert expression to float
我已经看到了一些关于这个的其他问题,但大多数问题是混合了数学函数的名称空间,但我在代码中没有看到这一点。我无法在此处发布data11.txt中的数据,因为它的字符太多,所以这里是:

您需要的更改:

  • 您应该将符号替换为数字,而不是将字符串替换为数字
  • 函数
    f
    应返回浮点值
  • 所以你应该试试这个:

    import pandas as pd
    from sympy import  symbols, inverse_laplace_transform, sympify
    from scipy import optimize
    
    dane = pd.read_fwf('data11.txt', header=None)
    dane.columns = ['time', 'response']
    
    T = dane['time']
    Yt = dane['response']
    
    t = symbols('t', positive=True, real=True)
    s, k, tauz, tau, dzeta = symbols('s k tauz tau dzeta', real=True)
    
    F = (k * ((tauz*s + 1)/((tau**2)*(s**2) + 2*tau*dzeta*s + 1)))
    print('Calculating Inverse Laplace')
    IL = inverse_laplace_transform(F, s, t)
    
    TF = sympify(IL)
    
    LSQ = 0
    print('Calculating least squares')
    for i in range(len(T)):
        LSQl = Yt[i]
        LSQp = TF.subs({t: T[i]})   # <-- use t, not 't'
        LSQk = (LSQl - LSQp)**2
        LSQ = LSQ + LSQk
    
    LSQ = sympify(LSQ)
    
    def f(params):
        # use symbols, not string
        # eval to float, be careful about complex number
        re, im = LSQ.subs({k: params[0], dzeta: params[1], tau: params[2], tauz: params[3]}).evalf().as_real_imag()
        return re
    
    def LSQminsearch(f, TF, k0, dzeta0, tau0, tauz0):
        print(f'Searching for minimum for k0= {k0} dzeta0= {dzeta0} tau0= {tau0} tauz0= {tauz0} ...')
        res = optimize.fmin(f, [k0, dzeta0, tau0, tauz0], maxiter = 100000000, maxfun=1000000)
        k = res[0]
        dzeta = res[1]
        tau = res[2]
        tauz = res[3]
        print(f'Found k0= {k} dzeta0= {dzeta} tau0= {tau} tauz0= {tauz} ...')
    
    LSQminsearch(f, TF, 0.5, 0.5, 0.5, 0.5)
    
    将熊猫作为pd导入
    从sympy导入符号,逆拉普拉斯变换,sympify
    从scipy导入优化
    dane=pd.read_fwf('data11.txt',header=None)
    dane.columns=['time','response']
    T=丹麦['time']
    Yt=丹麦[‘响应’]
    t=符号('t',正=真,实=真)
    s、 k,tauz,tau,dzeta=符号('s k tauz tau dzeta',real=True)
    F=(k*((tauz*s+1)/((tau**2)*(s**2)+2*tau*dzeta*s+1)))
    打印('计算逆拉普拉斯')
    IL=逆拉普拉斯变换(F,s,t)
    TF=同情(IL)
    LSQ=0
    打印('计算最小二乘')
    对于范围内的i(len(T)):
    LSQl=Yt[i]
    LSQp=TF.subs({t:t[i]})#您需要的更改:

  • 您应该将符号替换为数字,而不是将字符串替换为数字
  • 函数
    f
    应返回浮点值
  • 所以你应该试试这个:

    import pandas as pd
    from sympy import  symbols, inverse_laplace_transform, sympify
    from scipy import optimize
    
    dane = pd.read_fwf('data11.txt', header=None)
    dane.columns = ['time', 'response']
    
    T = dane['time']
    Yt = dane['response']
    
    t = symbols('t', positive=True, real=True)
    s, k, tauz, tau, dzeta = symbols('s k tauz tau dzeta', real=True)
    
    F = (k * ((tauz*s + 1)/((tau**2)*(s**2) + 2*tau*dzeta*s + 1)))
    print('Calculating Inverse Laplace')
    IL = inverse_laplace_transform(F, s, t)
    
    TF = sympify(IL)
    
    LSQ = 0
    print('Calculating least squares')
    for i in range(len(T)):
        LSQl = Yt[i]
        LSQp = TF.subs({t: T[i]})   # <-- use t, not 't'
        LSQk = (LSQl - LSQp)**2
        LSQ = LSQ + LSQk
    
    LSQ = sympify(LSQ)
    
    def f(params):
        # use symbols, not string
        # eval to float, be careful about complex number
        re, im = LSQ.subs({k: params[0], dzeta: params[1], tau: params[2], tauz: params[3]}).evalf().as_real_imag()
        return re
    
    def LSQminsearch(f, TF, k0, dzeta0, tau0, tauz0):
        print(f'Searching for minimum for k0= {k0} dzeta0= {dzeta0} tau0= {tau0} tauz0= {tauz0} ...')
        res = optimize.fmin(f, [k0, dzeta0, tau0, tauz0], maxiter = 100000000, maxfun=1000000)
        k = res[0]
        dzeta = res[1]
        tau = res[2]
        tauz = res[3]
        print(f'Found k0= {k} dzeta0= {dzeta} tau0= {tau} tauz0= {tauz} ...')
    
    LSQminsearch(f, TF, 0.5, 0.5, 0.5, 0.5)
    
    将熊猫作为pd导入
    从sympy导入符号,逆拉普拉斯变换,sympify
    从scipy导入优化
    dane=pd.read_fwf('data11.txt',header=None)
    dane.columns=['time','response']
    T=丹麦['time']
    Yt=丹麦[‘响应’]
    t=符号('t',正=真,实=真)
    s、 k,tauz,tau,dzeta=符号('s k tauz tau dzeta',real=True)
    F=(k*((tauz*s+1)/((tau**2)*(s**2)+2*tau*dzeta*s+1)))
    打印('计算逆拉普拉斯')
    IL=逆拉普拉斯变换(F,s,t)
    TF=同情(IL)
    LSQ=0
    打印('计算最小二乘')
    对于范围内的i(len(T)):
    LSQl=Yt[i]
    
    LSQp=TF.subs({t:t[i]})#错误在哪一行?@PaddyHarrison res=optimize.fmin(f[k0,dzeta0,tau0,tauz0],maxiter=100000000,maxfun=1000000)@PaddyHarrison对不起,我现在粘贴了整个错误谢谢。所以我运行了你的代码,在我的机器上,
    subs
    无法正常工作,不管是什么原因导致了你的错误。如果将所有
    subs
    替换为变量:
    LSQp=TF.subs({t:t[i]})
    LSQ.subs({k:params[0],dzeta:params[1],tau:params[2],tauz:params[3]})
    ,那么它会有所帮助。我遇到的下一个问题是,被替换的方程很复杂,我认为解算器没有很好地处理这个问题。也许取绝对值会有帮助?@PaddyHarrison谢谢。你和阿德塔姆的回答很有帮助:)看起来现在可以了错误在哪一行?@PaddyHarrison res=optimize.fmin(f[k0,dzeta0,tau0,tauz0],maxiter=100000000,maxfun=1000000)@PaddyHarrison对不起,我现在粘贴了整个错误谢谢。所以我运行了你的代码,在我的机器上,
    subs
    无法正常工作,不管是什么原因导致了你的错误。如果将所有
    subs
    替换为变量:
    LSQp=TF.subs({t:t[i]})
    LSQ.subs({k:params[0],dzeta:params[1],tau:params[2],tauz:params[3]})
    ,那么它会有所帮助。我遇到的下一个问题是,被替换的方程很复杂,我认为解算器没有很好地处理这个问题。也许取绝对值会有帮助?@PaddyHarrison谢谢。你和阿德塔姆的回答很有帮助:)看起来它现在起作用了