用sympy简化方形导数

时间:2018-02-12 20:26:34

标签: sympy

我试图用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)实际上是不相关的。

1 个答案:

答案 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)