使用 numpy 或 scipy 对 sympy 代码进行运行时优化
Runtime Optimization of sympy code using numpy or scipy
我是编程新手,这是我的第一个问题。我在这个问题上花了很多时间。这是我为论文编写的程序的摘要。也许这对你们中的一些专家来说是微不足道的,但我什至可能缺乏数学知识。
我想为 b1、b2 和 c3 求解以下方程组:
0 = cos(b1)+ cos(b2)- 0.0166
0 = sin(b1)+ sin(b2)+ 0.3077*c3 - 0.6278
0 = cos(b1)- cos(b2)+ 5.4155*c3 - 4.3547
b1 和 b2 是角度,因此应该在 [0, 2*pi] 之间,c3 应该在 [0,1] 之间,但这不是必需的。我可以稍后过滤结果。
我找到了一个使用 sympy 的解决方案:
import sympy as sy
b1 = sy.Symbol('b1',real=True)
b2 = sy.Symbol('b2',real=True)
c3 = sy.Symbol('c3',real=True)
a = sy.cos(b1)+sy.cos(b2)-0.0166
b = sy.sin(b1)+sy.sin(b2)+0.3077*c3-0.6278
c = sy.cos(b1)-sy.cos(b2)+5.4155*c3-4.3547
Erg = sy.solve([a,b,c,],[b1,b2,c3],dict=True)
[{c3: -0.4634, b1: 2.7245, b2: 0.3739}]
结果是合理的,但不幸的是,这导致计算时间为 6 秒,这将导致我的程序的总计算时间超过 7 小时。请帮我找到一个更快的解决方案。我试过了 scipy
from scipy.optimize import fsolve
import numpy as np
def equations(p):
b1, b2, c3 = p
return (np.cos(b1)+np.cos(b2)-0.0166, np.sin(b1)+np.sin(b2)+0.3077*c3-0.6278,np.cos(b1)-np.cos(b2)+5.4155*c3-4.3547)
b1, b2, c3 = fsolve(equations, (-0.4634, 2.7245, 0.3739))
这导致 (-9.8418e-14, 5.6621e-15,-7.5495e-14) 小于 1。我不知道哪个数字属于哪个变量,但无论如何它们都没有任何意义。另一种选择是优化最小 c3 的方程。请不要犹豫,问我是否有什么不清楚的地方。
如果我修复了您的 numpy
示例中缺少的括号,我会得到不同的结果:
In [40]: b1,b2,c3
Out[40]: (0.21407625679722384, 2.8598524043642226, 0.4463029985826017)
无论如何,你的输入点不是很好,因为你的变量混淆了。您的函数按顺序 b1,b2,c3
定义,但起点对应于 c3,b1,b2
的符号解。改变顺序给我
In [42]: b1,b2,c3
Out[42]: (2.9450733464142882, 0.07278767695320594, 1.1693849677611501)
请注意,对于给定的 b1,b2
,您还会有一个 b1+2*k*pi,b2*2*l*pi
的解决方案,其中 k,l
是整数。
我没有将这些数字放入您的方程式中,但我很确定它们可以求解。问题是,有很多解决方案。正如我所说,您的前两个变量是周期性的,即使这样也可以有很多其他 c3
的解决方案。如果你对 fsolve
使用一堆不同的起点,你会得到一堆不同的解决方案。
更糟糕的是:您的解决方案没有强制执行 0<c3<1
限制。
关于数学:由于可能的解决方案多种多样,您可能希望先在纸上简化数值问题。
例如,第一个方程是特殊的,因为它不包含 c3
。您可以将 b1
与 b2
相关联,尽管是以非线性方式。对于每个 b1
你会知道
b2=+-acos(0.0166-cos(b1))+2*k*pi
这已经是一个约束。此外,添加方程式。 1 到方程式。 3给你
0 = 2*cos(b1)+ 5.4155*c3 - 4.3547-0.0166
换句话说,c3
线性依赖于 cos(b1)
。如果将其引入方程式可能会有所帮助。 2、获取b1
和b2
函数之间的联系。本质上,您的变量为 b1,b2(b1),c3(b1)
,只有一个方程式。 2个解决。
另一个注意事项:我猜测大量的方程式来自方程式中数值因子的大量组合。对不对?如果是这样,您可能想在方程式中引入一些符号常数而不是浮点文字,并尝试解决这个问题。如果你成功了,你就不必求解大量的非线性方程组:你只需求解一组,然后代入你的各种参数。
我是编程新手,这是我的第一个问题。我在这个问题上花了很多时间。这是我为论文编写的程序的摘要。也许这对你们中的一些专家来说是微不足道的,但我什至可能缺乏数学知识。
我想为 b1、b2 和 c3 求解以下方程组:
0 = cos(b1)+ cos(b2)- 0.0166
0 = sin(b1)+ sin(b2)+ 0.3077*c3 - 0.6278
0 = cos(b1)- cos(b2)+ 5.4155*c3 - 4.3547
b1 和 b2 是角度,因此应该在 [0, 2*pi] 之间,c3 应该在 [0,1] 之间,但这不是必需的。我可以稍后过滤结果。
我找到了一个使用 sympy 的解决方案:
import sympy as sy
b1 = sy.Symbol('b1',real=True)
b2 = sy.Symbol('b2',real=True)
c3 = sy.Symbol('c3',real=True)
a = sy.cos(b1)+sy.cos(b2)-0.0166
b = sy.sin(b1)+sy.sin(b2)+0.3077*c3-0.6278
c = sy.cos(b1)-sy.cos(b2)+5.4155*c3-4.3547
Erg = sy.solve([a,b,c,],[b1,b2,c3],dict=True)
[{c3: -0.4634, b1: 2.7245, b2: 0.3739}]
结果是合理的,但不幸的是,这导致计算时间为 6 秒,这将导致我的程序的总计算时间超过 7 小时。请帮我找到一个更快的解决方案。我试过了 scipy
from scipy.optimize import fsolve
import numpy as np
def equations(p):
b1, b2, c3 = p
return (np.cos(b1)+np.cos(b2)-0.0166, np.sin(b1)+np.sin(b2)+0.3077*c3-0.6278,np.cos(b1)-np.cos(b2)+5.4155*c3-4.3547)
b1, b2, c3 = fsolve(equations, (-0.4634, 2.7245, 0.3739))
这导致 (-9.8418e-14, 5.6621e-15,-7.5495e-14) 小于 1。我不知道哪个数字属于哪个变量,但无论如何它们都没有任何意义。另一种选择是优化最小 c3 的方程。请不要犹豫,问我是否有什么不清楚的地方。
如果我修复了您的 numpy
示例中缺少的括号,我会得到不同的结果:
In [40]: b1,b2,c3
Out[40]: (0.21407625679722384, 2.8598524043642226, 0.4463029985826017)
无论如何,你的输入点不是很好,因为你的变量混淆了。您的函数按顺序 b1,b2,c3
定义,但起点对应于 c3,b1,b2
的符号解。改变顺序给我
In [42]: b1,b2,c3
Out[42]: (2.9450733464142882, 0.07278767695320594, 1.1693849677611501)
请注意,对于给定的 b1,b2
,您还会有一个 b1+2*k*pi,b2*2*l*pi
的解决方案,其中 k,l
是整数。
我没有将这些数字放入您的方程式中,但我很确定它们可以求解。问题是,有很多解决方案。正如我所说,您的前两个变量是周期性的,即使这样也可以有很多其他 c3
的解决方案。如果你对 fsolve
使用一堆不同的起点,你会得到一堆不同的解决方案。
更糟糕的是:您的解决方案没有强制执行 0<c3<1
限制。
关于数学:由于可能的解决方案多种多样,您可能希望先在纸上简化数值问题。
例如,第一个方程是特殊的,因为它不包含 c3
。您可以将 b1
与 b2
相关联,尽管是以非线性方式。对于每个 b1
你会知道
b2=+-acos(0.0166-cos(b1))+2*k*pi
这已经是一个约束。此外,添加方程式。 1 到方程式。 3给你
0 = 2*cos(b1)+ 5.4155*c3 - 4.3547-0.0166
换句话说,c3
线性依赖于 cos(b1)
。如果将其引入方程式可能会有所帮助。 2、获取b1
和b2
函数之间的联系。本质上,您的变量为 b1,b2(b1),c3(b1)
,只有一个方程式。 2个解决。
另一个注意事项:我猜测大量的方程式来自方程式中数值因子的大量组合。对不对?如果是这样,您可能想在方程式中引入一些符号常数而不是浮点文字,并尝试解决这个问题。如果你成功了,你就不必求解大量的非线性方程组:你只需求解一组,然后代入你的各种参数。