分层嵌套参数积分

时间:2018-09-10 13:15:39

标签: python-3.x sympy lambdify

我有一个损失函数L(u1,...,un),形式为

L(u) = Integral( (I**2 + J**2) * h, (t,c,d) ) //h=h(t), I=I(t,u) 

其中

I = Integral( f, (x,a,b) )   // f=f(x,t,u)
J = Integral( g, (x,a,b) )   // g=g(x,t,u)

我想用L在数值上最小化scipy,因此我需要lambdify表达式。

但是,此时lambdify本身并不支持翻译积分。通过一些技巧,可以使它与单个参数积分一起使用,请参见Lambdify A Parametric Integral。但是,我看不出如何将提议的解决方案扩展到这种一般情况。

以下原则上可行的一个想法是:

采用定义L的计算图。从叶子开始,递归地将每个符号运算替换为表示为lambda函数的相应数值运算。但是,这将导致大量的lambda函数嵌套,我怀疑这会对性能产生非常不利的影响。

理想情况下,我们希望获得与手工制作相同的结果:

L = lambda u: quad(lambda t: (quad(lambda x: f,a,b)[0]**2 
                  + quad(lambda x: g,a,b)[0]**2)*h, c, d)[0] 

MWE:(使用旧线程中的代码)

from sympy import *
from scipy.integrate import quad
import numpy as np
def integral_as_quad(function, limits):
    x, a, b = limits
    param = tuple(function.free_symbols - {x})
    f = sp.lambdify((x, *param), function, modules=['numpy'])
    return quad(f, a, b, args=param)[0]

x,a,b,t = sp.symbols('x a b t')
f = (x/t-a)**2
g = (x/t-b)**2
h = exp(-t)
I = Integral( f**2,(x,0,1))
J = Integral( g**2,(x,0,1))
K = Integral( (I**2 + J**2)*h,(t,1,+oo))
F = lambdify( (a,b), K, modules=['sympy',{"Integral": integral_as_quad}])
L = lambda a,b: quad(lambda t: (quad(lambda x: (x/t-a)**2,0,1)[0]**2 
     + quad(lambda x: (x/t-b)**2,0,1)[0]**2)*np.exp(-t), 1, np.inf)[0] 
display(F(1,1))
display(type(F(1,1)))
display(L(1,1))

0 个答案:

没有答案