我试图用sympy来生成非线性最小二乘拟合的方程。我的目标是使这个非常复杂,但目前,这是一个简单的案例(但不是太简单!)。它基本上将二维正弦曲线拟合到数据中。这是代词:
Route::get('add/{title?}/{url?}', 'HomeController@add')->name('add');
毕业学期的一个要素如下:
Route::get('add/{title?}/{url?}', 'HomeController@add_')->where('url', '(.*)')->name('add_popup');
我想要的是用Vres替换扩展的术语from sympy import *
S, l, m = symbols('S l m', real=True)
u, v = symbols('u v', real=True)
Vobs = symbols('Vobs', complex=True)
Vres = Vobs - S * exp(- 1j * 2 * pi * (u*l+v*m))
J=Vres*conjugate(Vres)
axes = [S, l, m]
grad = derive_by_array(J, axes)
hess = derive_by_array(grad, axes)
并将两个共轭术语合并为更紧凑的术语:
- 2.0*I*pi*S*u*(-S*exp(-2.0*I*pi*(l*u + m*v)) + Vobs)*exp(2.0*I*pi*(l*u + m*v)) + 2.0*I*pi*S*u*(-S*exp(2.0*I*pi*(l*u + m*v)) + conjugate(Vobs))*exp(-2.0*I*pi*(l*u + m*v))
我看不出如何用同情心来做这件事。这个问题对于一阶导数(grad)是不好的,但是与二阶导数(hess)实际上是不相关的。
答案 0 :(得分:1)
首先,让我们不要在SymPy中使用1j,它是一个浮点数,浮点数对于符号数学是不好的。 SymPy的假想单位是I
。所以,
Vres = Vobs - S * exp(- I * 2 * pi * (u*l+v*m))
要用符号替换表达式Vres,我们首先需要创建这样的符号。我打电话给它Vres0
,但它的名字将是Vres,所以打印为" Vres"在公式中。
Vres0 = symbols('Vres')
g1 = grad[1].subs(Vres, Vres0).conjugate().subs(Vres, Vres0).conjugate()
需要缀合物 - 替代 - 缀合物,因为subs
没有完全认识到用符号的缀合物替换表达的缀合物的可能性。
现在g1是
-2*I*pi*S*Vres*u*exp(2*I*pi*(l*u + m*v)) + 2*I*pi*S*u*exp(-2*I*pi*(l*u + m*v))*conjugate(Vres)
我们希望折叠共轭项的总和。我为此使用自定义转换规则:规则fold_conjugates
适用于两个术语(Add
)的每个总和(len(f.args) == 2
),其中第二个是第一个术语的共轭({{1} }})。它执行的转换:将总和替换为第一个参数(f.args[1] == f.args[0].conjugate()
)的实部的两倍。像这样:
2*re(f.args[0])
最终结果:from sympy.core.rules import Transform
fold_conjugates = Transform(lambda f: 2*re(f.args[0]),
lambda f: isinstance(f, Add) and len(f.args) == 2 and f.args[1] == f.args[0].conjugate())
g = g1.xreplace(fold_conjugates)
。