scipy 如何在Python中添加新的字符串

e5nszbig  于 2022-11-10  发布在  Python
关注(0)|答案(2)|浏览(158)

我有一个目标函数,我想最小化关于't'的值,在这个函数中,有一个从0到t的积分,这个积分必须被考虑用于优化。但是,我不知道如何将这个积分包括到我的目标函数中。我已经使用了simpy和scipy库,但是它们似乎都不起作用。下面是我的代码:

Cf= 100;
Cp=50;
  Eta=72.66585511711865;
  Beta=1.18609324
def R(t):
  return math.exp(-t/Eta)**Beta
def f(t):
  return (Beta/(Eta**Beta))*t**(Beta-1)*(math.exp(-t/Eta)**Beta)  
def M(t):
  return t*f(t)
import sympy as sp 
from scipy import *
import scipy.integrate
t = sp.Symbol('t') 
Mt=t*(Beta/(Eta**Beta))*t**(Beta-1)*(sp.exp(-t/Eta)**Beta);
intM=sp.integrate(Mt,t)
print(intM)
def C(t):
  return (Cp*R(t)+Cf*(1-R(t)))/(t*R(t)+ intM)
from scipy.optimize import minimize_scalar
res = minimize_scalar(C)
res

这将显示错误“TypeError:无法确定关系”“的真值。在scipy.integrate.quad中,我无法将上限定义为”t“。另一方面,当我尝试将sp.integrate输出放入目标函数时,它也不起作用。如果你能帮助我,我将很高兴。谢谢。

v1l68za4

v1l68za41#

首先,你不能在优化程序中有一个 * 不定 * 积分,因为它被定义为一个常数。不是一个函数,而是一类函数。
但看起来你的积分是定积分--你对某个虚拟变量积分,比如说,从t '= 0到t'= t,所以这是非常好的,你只需要这样做。
首先,我们来做定积分:

intM = sp.integrate(Mt, (t, 0, t))

# second arg is variable of integration, lower bound, upper bound

# we can skip defining tprime, a mathematician would hate you for this but meh

这仍然依赖于t,所以现在我们把它转换成一个数值函数:

intM_func = sp.lambdify(t, intM)

# note how you can do intM_func(3) and get a number

然后将intM_func(t)而不是符号intM粘贴到您的C最小化函数中,您就可以开始了:)
适用于我的完整版本:

Cf = 100
Cp = 50
Eta = 72.66585511711865
Beta = 1.18609324

def R(t):
    return math.exp(-t / Eta)**Beta

def f(t):
    return (Beta / (Eta**Beta)) * t**(Beta - 1) * (math.exp(-t / Eta)**Beta)

def M(t):
    return t * f(t)

import sympy as sp
from scipy import *
import scipy.integrate

t = sp.Symbol("t")
Mt = t * (Beta / (Eta**Beta)) * t**(Beta - 1) * (sp.exp(-t / Eta)**Beta)
intM = sp.integrate(Mt, (t, 0, t))
intMfunc = sp.lambdify(t, intM)
print(intM)

import numpy as np
def C(t):
    if t == 0:   # dodge a division-by-zero bullet
        return np.inf
    return (Cp * R(t) + Cf * (1 - R(t))) / (t * R(t) + intMfunc(t))

from scipy.optimize import minimize_scalar

res = minimize_scalar(C)
print(res)

我得到:

fun: 1.5407809938973502
 message: '\nOptimization terminated successfully;\nThe returned value satisfies the termination criteria\n(using xtol = 1.48e-08 )'
    nfev: 61
     nit: 28
 success: True
       x: 2964.8614509894874

作为输出。

bvjveswy

bvjveswy2#

我试图“关闭”这个,因为你没有给予完整的错误-与追溯。但它似乎你得到了一个答案,所以我只是试图集中错误,因为你给它。

error " TypeError: cannot determine truth value of Relational" . in scipy.integrate.quad

这类似于numpy数组中常见的“二义性错误”。某个函数试图执行简单的True/False操作,例如if。scipy函数可能正在测试范围值的顺序是否正确。或者错误发生在func中。如果没有回溯,我们只能猜测。或者从以前的知识中推断。所以你很幸运,有人已经熟悉这些问题。只是不要指望这一点!
举例说明:
isympy会话中,考虑以下符号:

In [35]: x

和一个亲戚:

In [36]: x>0

In [37]: type(_)
Out[37]: sympy.core.relational.StrictGreaterThan

把这个关系式放在一个‘if’中:

In [38]: if x>0: print('yes')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [38], in <cell line: 1>()
----> 1 if x>0: print('yes')

File ~\anaconda3\lib\site-packages\sympy\core\relational.py:511, in Relational.__bool__(self)
    510 def __bool__(self):
--> 511     raise TypeError("cannot determine truth value of Relational")

TypeError: cannot determine truth value of Relational

sympy无法从关系表达式返回简单的True/False。
同时使用sympyscipy需要对两者的工作原理有相当多的了解。在数值函数中使用symmy表达式太容易了,但却不起作用。
以下是缺少的回溯:

In [59]: res = minimize_scalar(C)
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
Input In [59], in <cell line: 1>()
----> 1 res = minimize_scalar(C)

File ~\anaconda3\lib\site-packages\scipy\optimize\_minimize.py:794, in minimize_scalar(fun, bracket, bounds, args, method, tol, options)
    792     return method(fun, args=args, bracket=bracket, bounds=bounds,**options)
    793 elif meth == 'brent':
--> 794     return _minimize_scalar_brent(fun, bracket, args,**options)
    795 elif meth == 'bounded':
    796     if bounds is None:

File ~\anaconda3\lib\site-packages\scipy\optimize\optimize.py:2396, in _minimize_scalar_brent(func, brack, args, xtol, maxiter,**unknown_options)
   2393 brent = Brent(func=func, args=args, tol=tol,
   2394               full_output=True, maxiter=maxiter)
   2395 brent.set_bracket(brack)
-> 2396 brent.optimize()
   2397 x, fval, nit, nfev = brent.get_result(full_output=True)
   2399 success = nit < maxiter and not (np.isnan(x) or np.isnan(fval))

File ~\anaconda3\lib\site-packages\scipy\optimize\optimize.py:2180, in Brent.optimize(self)
   2177 def optimize(self):
   2178     # set up for optimization
   2179     func = self.func
-> 2180     xa, xb, xc, fa, fb, fc, funcalls = self.get_bracket_info()
   2181     _mintol = self._mintol
   2182     _cg = self._cg

File ~\anaconda3\lib\site-packages\scipy\optimize\optimize.py:2154, in Brent.get_bracket_info(self)
   2151 ### BEGIN core bracket_info code ###
   2152 ### carefully DOCUMENT any CHANGES in core ##
   2153 if brack is None:
-> 2154     xa, xb, xc, fa, fb, fc, funcalls = bracket(func, args=args)
   2155 elif len(brack) == 2:
   2156     xa, xb, xc, fa, fb, fc, funcalls = bracket(func, xa=brack[0],
   2157                                                xb=brack[1], args=args)

File ~\anaconda3\lib\site-packages\scipy\optimize\optimize.py:2606, in bracket(func, xa, xb, args, grow_limit, maxiter)
   2604 fa = func(*(xa,) + args)
   2605 fb = func(*(xb,) + args)
-> 2606 if (fa < fb):                      # Switch so fa > fb
   2607     xa, xb = xb, xa
   2608     fa, fb = fb, fa

File ~\anaconda3\lib\site-packages\sympy\core\relational.py:511, in Relational.__bool__(self)
    510 def __bool__(self):
--> 511     raise TypeError("cannot determine truth value of Relational")

TypeError: cannot determine truth value of Relational

因此,正如我所怀疑的,scipy正在尝试检查范围;

if (fa < fb):                      # Switch so fa > fb

C被给定一个简单的标量参数产生一个sympy表达式-带有一个未计算的积分。

In [57]: C(1)
Out[57]:

你忘了给我们看的那个intM

In [60]: intM
Out[60]:

相关问题