如何在Python中定义对多变量函数进行操作的运算符(如积分器)?

如何在Python中定义对多变量函数进行操作的运算符(如积分器)?,python,function,functional-programming,integral,Python,Function,Functional Programming,Integral,如何在Python中定义对多变量函数进行操作的运算符(如积分器)?我的问题是,当我定义一个积分函数numint来数值积分一个多变量函数沿着它的一个变量时,这个变量应该首先被引入,而我需要用户在调用操作符时引入它,因为它可以从一行代码变为另一行代码。一种方法是不使用运算符,在需要计算积分的变量时插入积分公式,但这样代码会变得相当繁琐,因此最好尽量避免。对我来说,错误的代码如下。有没有办法让它正常工作 var('x,y,z,t,x1,y1,z1,t1') U=function('U0',x,y,z,

如何在Python中定义对多变量函数进行操作的运算符(如积分器)?我的问题是,当我定义一个积分函数numint来数值积分一个多变量函数沿着它的一个变量时,这个变量应该首先被引入,而我需要用户在调用操作符时引入它,因为它可以从一行代码变为另一行代码。一种方法是不使用运算符,在需要计算积分的变量时插入积分公式,但这样代码会变得相当繁琐,因此最好尽量避免。对我来说,错误的代码如下。有没有办法让它正常工作

var('x,y,z,t,x1,y1,z1,t1')
U=function('U0',x,y,z,t,x1,y1,z1,t1)
U=sin(x*y*z*t - x1*y1*z1*t1)^5

num=2
def numint(f, u, h):
    integ = 0.5*h*(f(u=0) + f(u=1))
    for i in range(1,num):
        integ = integ + h * f(u=i*h)
    return integ

print numint(U,t1,1/num)+numint(U,t,1/num)
现在进行积分的变量是“u”,在函数“u”中根本找不到,因此结果是:

2*sin(t*x*y*z - t1*x1*y1*z1)^5
当我期望它一次集成U WRT和一次WRT t1,然后将它们相加时

据我所知,问题在于局部变量和全局变量。也许使用闭包和嵌套函数是定义运算符的合适方法,如所提供的示例中所述,但该示例对单变量函数很有用,而我不能将其用于多变量函数


更新。下面的代码符合我的要求(请参阅最后一个print命令,前面的打印用于实验),但我应该使用函数的自由参数(如
y
),并尝试使用伪变量(如上面示例代码中的
u
)失败:

结果是:

0.250000000000000*U0(x, 0, z, t, x1, y1, z1, t1) + 1/2*U0(x, 1/2, z, t,
x1, y1, z1, t1) + 0.250000000000000*U0(x, 1, z, t, x1, y1, z1, t1) 

1/2*sin(-y1 + 1/2)*sin(z - z1)*sin(x - x1)*sin(t - t1) +
0.250000000000000*sin(-y1 + 1)*sin(z - z1)*sin(x - x1)*sin(t - t1) +
0.250000000000000*sin(z - z1)*sin(x - x1)*sin(t - t1)*sin(-y1) 


sin(-y1 + z)*sin(y - z1)*sin(x - x1)*sin(t - t1) 

0.250000000000000*U0(x, z, 0, t, x1, y1, z1, t1) + 1/2*U0(x, z, 1/2, t,
x1, y1, z1, t1) + 0.250000000000000*U0(x, z, 1, t, x1, y1, z1, t1) 

1/2*sin(-z1 + 1/2)*sin(-y1 + z)*sin(x - x1)*sin(t - t1) +
0.250000000000000*sin(-z1 + 1)*sin(-y1 + z)*sin(x - x1)*sin(t - t1) +
0.250000000000000*sin(-y1 + z)*sin(x - x1)*sin(t - t1)*sin(-z1) 


1/2*sin(-t1 + 1/2)*sin(z - z1)*sin(y - y1)*sin(x - x1) +
0.250000000000000*sin(-t1 + 1)*sin(z - z1)*sin(y - y1)*sin(x - x1) +
0.250000000000000*sin(t - 1)*sin(z - z1)*sin(y - y1)*sin(x - x1) +
1/2*sin(t - 1/2)*sin(z - z1)*sin(y - y1)*sin(x - x1) +
0.250000000000000*sin(z - z1)*sin(y - y1)*sin(x - x1)*sin(t) +
0.250000000000000*sin(z - z1)*sin(y - y1)*sin(x - x1)*sin(-t1)
注意我是如何被迫使用
.substitute()
的。这里的积分是单变量的,但当积分的维数增加时,这种编码方式会变得混乱。有没有更简洁、更直接的方法?

您可以使用它将具有多个变量的函数转换为具有一个自由变量的函数

编辑:您的函数是

def numint(func, h):
    ...
所以你应该使用例如

p = partial(numint, h=1/2.0)
然后可以调用新函数:

p(func)
您应该使用关键字参数来指示您要给部分用户的参数!非keywoard任务不能跟在关键字参数后面


Edit2:请注意,Python本身不具备对方程进行符号操作的能力,这似乎正是您所需要的。您可能应该将其重新标记为SageMath问题。

您能否提供一个示例,说明如何将其用于此集成例程?我尝试使用它(例如通过从functools导入部分;var1=x;numx=partial(numint,var1))写入
)失败:(也使用
partial(numint(U0,var1,1/num),var1=t)
虽然没有给出错误,但似乎不起作用。如果我经常使用命令,请告诉我,我是一个新手。感谢这个例子,我尝试过并编写了它,但它不起作用。你能解释一下为什么它不起作用吗?你的最小示例中从
var
U0
的第一部分代码无效on;它给出了一个语法错误。你应该首先修复它。
U0
不是一个有效的函数定义…啊,你是对的,我刚刚创建了一个python文件,遇到了与你指出的相同的语法错误,但我无法解决它。大多数人建议使用列表而不是参数来避免此类错误,而我在这里不能这样做,I r确实,我使用的是基于Python的SageMath,代码在那里运行没有错误,但输出仍然是
sin(x-x1)*sin(y-y1)*sin(z-z1)*sin(t-t1)
。也就是说,集成并没有按预期进行。
var('x,y,z,t,x1,y1,z1,t1,var1')
U=function('U0',x,y,z,t,x1,y1,z1,t1)
U0(x,y,z,t,x1,y1,z1,t1)=sin(x-x1)*sin(y-y1)*sin(z-z1)*sin(t-t1)
    # if write U0=... instead of U0(...)=... the order of arguments of U0 is not
    # specified and e.g. sin(x-x1) might become sin(x-y) from the system's viewpoint

num=2.0
def numint(func, h):
    #global var1
    integ = 0.5*h*(func(var1=0) + func(var1=1))
    for i in range(1,num):
        integ = integ + h * func(var1=i*h)
    return integ


print numint(U0(x=var1),1/num)+numint(U0(y1=var1),1/num)
var('x,y,z,t,x1,y1,z1,t1,var1')
U=function('U0',x,y,z,t,x1,y1,z1,t1)
U0(x,y,z,t,x1,y1,z1,t1)=sin(x-x1)*sin(y-y1)*sin(z-z1)*sin(t-t1)
    # if write U0=... instead of U0(...)=... the order of arguments of U0 is not
    # specified and e.g. sin(x-x1) might become sin(x-y) from the system's viewpoint

num=2.0
def numint(func, h):
    #global var1
    integ = 0.5*h*(func(var1=0) + func(var1=1))
    for i in range(1,num):
        integ = integ + h * func(var1=i*h)
    return integ


print numint(U0(x=var1),1/num)+numint(U0(y1=var1),1/num)