簡體   English   中英

如何在Python中定義對多變量函數進行操作的運算符(例如,積分器)?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM