![](/img/trans.png)
[英]How can I create a numpy array holding values of a multi-variable function?
[英]How can I define an operator (eg integrator) in Python operating on a multi-variable function?
如何在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 t和一次WRT t1,然后將它們添加在一起。
就我所讀的而言,問題出在局部變量和全局變量。 就像這里提供的示例中一樣,也許使用閉包和嵌套函數是定義運算符的一種合適方法,但是該示例對單變量函數很有用,而我不能將其用於多變量函數。
更新。 下面的代碼完成了我想要的( 請參閱最后的打印命令,以前的打印用於實驗 ),但是我應該使用函數的自由參數(如y
)並嘗試使用虛擬變量(如上述示例代碼中的u
)失敗:
var('x,y,z,t,x1,y1,z1,t1')
R=[x,y,z,t]
R1=[x1,y1,z1,t1]
U=function('U0',*(R+R1))
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
def numint(func, h):
#integ = 0.5*h*(func(x=x,y=0,z=z,t=t,x1=x1,y1=y1,z1=z1,t1=t1) + func(x=x,y=1,z=z,t=t,x1=x1,y1=y1,z1=z1,t1=t1))
#for i in range(1,num):
# integ = integ + h * func(x=x,y=i*h,z=z,t=t,x1=x1,y1=y1,z1=z1,t1=t1)
#integ = 0.5*h*(func(x,0,z,t,x1,y1,z1,t1) + func(x,1,z,t,x1,y1,z1,t1))
#for i in range(1,num):
# integ = integ + h * func(x,i*h,z,t,x1,y1,z1,t1)
integ = 0.5*h*(func(y=0) + func(y=1))
for i in range(1,num):
integ = integ + h * func(y=i*h)
return integ
print numint(U,h=1/num),'\n'
print numint(U0,h=1/num),'\n\n'
print U0(y=z,z=y),'\n'
print numint(U(y=z,z=y),h=1/num),'\n'
print numint(U0(y=z,z=y),h=1/num),'\n\n'
print numint(U0(y=t,t=y),h=1/num).substitute(t=y)+numint(U0(y=t1,t1=y),h=1/num).substitute(t1=y)
結果是:
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()
。 這里的集成是單變量的,但是當集成的維度增加時,這種編碼方式就會變得混亂。 有什么想法可以更清潔,更直接地做到這一點?
您可以使用functools.partial()
將具有多個變量的函數轉換為具有一個自由變量的函數。
編輯:您的功能是
def numint(func, h):
...
所以你應該使用例如
p = partial(numint, h=1/2.0)
然后,您可以調用新函數:
p(func)
您應該使用關鍵字參數來指示您要為部分參數提供哪些參數! 而且,非鍵控參數不能跟隨關鍵字參數。
EDIT2:請注意,Python本身沒有做方程的符號運算,這似乎是你要找的內容的能力。 您可能應該將其重新標記為SageMath問題。
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)
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.