我有一个符号数组,可以表示为:
from sympy import lambdify, Matrix
g_sympy = Matrix([[ x, 2*x, 3*x, 4*x, 5*x, 6*x, 7*x, 8*x, 9*x, 10*x],
[x**2, x**3, x**4, x**5, x**6, x**7, x**8, x**9, x**10, x**11]])
g = lambdify( (x), g_sympy )
所以对于每个x
,我得到一个不同的矩阵:
g(1.) # matrix([[ 1., 2., 3., 4., 5., 6., 7., 8., 9., 10.],
# [ 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.]])
g(2.) # matrix([[ 2.00e+00, 4.00e+00, 6.00e+00, 8.00e+00, 1.00e+01, 1.20e+01, 1.40e+01, 1.60e+01, 1.80e+01, 2.00e+01],
# [ 4.00e+00, 8.00e+00, 1.60e+01, 3.20e+01, 6.40e+01, 1.28e+02, 2.56e+02, 5.12e+02, 1.02e+03, 2.05e+03]])
等等
我需要对g
在x
上进行数值积分,比如from 0. to 100.
(在真实的情况下,积分没有精确解),在我目前的方法中,我必须对g
中的每个元素进行lambdify
,并对其进行单独积分。我正在使用quad
进行元素集成,如:
ans = np.zeros( g_sympy.shape )
for (i,j), func_sympy in ndenumerate(g_sympy):
func = lambdify( (x), func_sympy)
ans[i,j] = quad( func, 0., 100. )
这里有两个问题:1)lambdify多次使用和2)for循环;我相信第一个是瓶颈,因为g_sympy
矩阵最多有10000个项(这对for循环来说不是什么大问题)。
如上所示,lambdify
允许计算整个矩阵,所以我想:“有没有办法融合整个矩阵?“scipy.integrate.quadrature
有一个参数vec_func
,这给了我希望。我期待的是:
g_int = quadrature( g, x1, x2 )
以得到完全积分的矩阵,但它给出了ValueError:
矩阵必须是二维的
编辑:我正在尝试使用quadv
和has already been discussed for SciPy来做can apparently be done in Matlab
真实的案例has been made available here。
要运行它,您需要:
- numpy
- scipy
- matplotlib
- 症状
运行:"python curved_beam_mrs.py"
。
您将看到这个过程已经很慢了,主要是因为集成,如文件curved_beam.py
中的TODO
所示。
如果删除文件curved_beam_mrs.py
中TODO
后面的注解,速度会慢得多。
集成的函数矩阵显示在print.txt
文件中。
谢谢你!
6条答案
按热度按时间mbjcgjjk1#
quad
或quadrature
的第一个参数必须是可调用的。quadrature
的vec_func
参数指的是这个可调用的 * 参数 * 是否是一个(可能是多维的)向量。从技术上讲,您可以vectorize
quad
本身:但这只相当于在
a
的元素上显式循环。具体来说,它不会给您带来任何性能增益,如果这就是您所追求的。所以,总而言之,问题是为什么以及你到底想在这里实现什么。gtlvzcf82#
向量化梯形与辛普森积分法则。Trapezoidal只是从另一个使用logspace而不是linspace的项目中复制和粘贴,以便它可以利用非均匀网格。
检查trapazoidal和simpson规则累积相对误差:
注意,两个梯形规则都使用200个点,而simpson基于上述收敛仅计时100个点。对不起,我没有症状:
结果如下:
在时间上需要指出的是,振亚的回答应该更准确。我相信一切都是正确的,请让我知道如果需要改变。
如果您提供的功能和范围,您将使用我可能会掀起一些更好的为您的系统。另外,您是否有兴趣利用其他内核/节点?
vshtjzan3#
在真实的情况下,积分没有精确解,你指的是奇点吗?你能更精确地描述它吗,以及你希望整合的矩阵的大小。我不得不承认,当涉及到一些事情时,Sympy非常慢(不确定集成是否是其中的一部分,但我更喜欢远离Sympy,坚持使用Numpy解决方案)。你想得到一个更优雅的解决方案,通过一个矩阵或一个更快的?
编辑:像这样的东西?
已经看到你想要积分像sum(asin(bx+c)^ncos(dx+e)^m)这样的东西,对于a,b,c,d,e,m,n的不同系数,我建议分析地做所有这些。(应该有一些公式,因为你可以把sin改写成复指数
当我更好地检查这些函数时,我注意到的另一件事是sin(ax+pi/2)和sin(ax+pi)以及类似的东西可以以删除pi/2或pi的方式重写为cos或sin。我还看到,只要看看你的函数矩阵中的第一个元素:
这也简化了计算。如果你有一个不涉及大量txtfile的公式,我会检查你需要积分的最一般的公式是什么,但我猜它像a*sin^n(bx+c)*cos^m(dx+e),m和n是0 1或2,这些东西可以简化成可以分析积分的东西。所以如果你找到了你得到的最一般的解析函数,你可以很容易地做出类似这样的东西
其中s1(x)等只是函数的分析集成版本?
(not我真的打算检查你的整个代码,看看剩下的都做了什么,但是它只是把这些函数从a到b集成在txt文件中吗?或者有没有什么东西,比如,求每个函数的平方,或者其他什么东西,可能会破坏分析的可能性?)
这应该简化你的积分,我猜?
first integral和:第二个
嗯,第二个链接不起作用,但我想你从第一个链接中得到了这个想法
编辑,因为您不需要分析解决方案:改进之处在于消除症状:
结果:
结论:使用numpy,ditch sympy,(我较慢的numpy方法实际上在这种情况下更快,因为在这个例子中我只尝试了一个sin函数,而不是在它们的ndarray上,但是当比较numpy版本的快速方法的时间和一个快速方法的渐近版本的时间时,ditch sympy的点仍然存在)
6vl6ewon4#
我可能已经找到了一些有趣的方法来做到这一点,代价是为矩阵
g_symp
定义不同的符号:结果:
使用ipython magic
%timeit vec_quad(G,0,100)
我认为这种方法在某种程度上更干净,尽管与符号的杂耍。
szqfcxe25#
quadpy(我的一个项目)进行矢量化正交。这一
给予
时间:
83qze16e6#
SciPy quad_vec用于自适应求向量函数的正交
对于像我这样多年后才遇到这个问题的人来说,现在有一个特定的SciPy函数scipy.integrate.quad_vec专门解决这个问题。它允许向量函数(或不同函数)的 * 自适应 * 正交。
当要集成的不同函数或组件共享一些计算时,此函数特别有用,这通常是向量函数的情况。
可以使用以下代码行实现向量函数
func
的非常有效的向量化求积(我重写了原始问题中的精确函数,与其他一些答案中使用的函数略有不同)打印结果为