Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/355.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python中多元函数的向量化偏导数_Python_Numpy_Vector_Scipy_Derivative - Fatal编程技术网

Python中多元函数的向量化偏导数

Python中多元函数的向量化偏导数,python,numpy,vector,scipy,derivative,Python,Numpy,Vector,Scipy,Derivative,alko给出了一个惊人的答案,用数值计算多元函数的偏导数 我现在有一个关于增强此函数以接受输入值数组的后续问题。我有一些代码,我在一个长长的n维点列表中循环,计算每个变量的偏导数,这在计算上变得非常昂贵 使用np.vectorize对相关函数进行向量化非常容易,但这会导致偏导数包装器出现问题: from scipy.misc import derivative import numpy as np def foo(x, y): return(x**2 + y**3) def part

alko给出了一个惊人的答案,用数值计算多元函数的偏导数

我现在有一个关于增强此函数以接受输入值数组的后续问题。我有一些代码,我在一个长长的n维点列表中循环,计算每个变量的偏导数,这在计算上变得非常昂贵

使用
np.vectorize
对相关函数进行向量化非常容易,但这会导致
偏导数
包装器出现问题:

from scipy.misc import derivative
import numpy as np

def foo(x, y):
    return(x**2 + y**3)

def partial_derivative(func, var=0, point=[]):
    args = point[:]
    def wraps(x):
        args[var] = x
        return func(*args)
    return derivative(wraps, point[var], dx=1e-6)

vfoo = np.vectorize(foo)

>>>foo(3,1)
>>>10
>>>vfoo([3,3], [1,1])
>>>array([10,10])

>>>partial_derivative(foo,0,[3,1])
>>>6.0
>>>partial_derivative(vfoo,0,[[3,3], [1,1]])
>>>TypeError: can only concatenate list (not "float") to list
最后一行最好返回
[6.0,6.0]
。在这种情况下,提供给矢量化函数
vfoo
的两个数组基本上是成对压缩的,因此
([3,3],[1,1])
被转换为两个点,
[3,1]
[3,1]
。当它被传递到函数
wrapps
时,它似乎被弄坏了。它最终传递给函数
导数的点是
[3,3]
。除此之外,还有明显的
TypeError
抛出

有人有什么建议吗?有没有人需要做类似的事情

编辑 有时候,我认为在SO上发帖只是打破思维障碍的必要条件。我想我已经为任何可能感兴趣的人准备好了:

vfoo = np.vectorize(foo)

foo(3,1)
X = np.array([3,3])
Y = np.array([1,1])
vfoo(X, Y)
partial_derivative(foo,0,[3,1])
partial_derivative(vfoo,0,[X, Y])

最后一行现在返回
数组([6,6.])

我对args[var]=x有一个小问题:这可能会永远更改args[var],并且所有值都已通过引用传递,无论更改多么小。所以你可能得不到你想要的确切答案。以下是一个例子:

In[67]: a = np.arange(9).reshape(3,3)
In[68]: b = a[:]
In[69]: b[0,0]=42
In[70]: a
Out[70]: 
array([[42,  1,  2],
       [ 3,  4,  5],
       [ 6,  7,  8]])
您需要通过以下方式进行修复:

def wraps(x):
    tmp = args[var]
    args[var] = x
    ret= func(*args)
    args[var] = tmp
    return ret
此外,您还可以使用。他们似乎知道自己在做什么。这将完成所有偏导数:

import numpy as np
import numdifftools as nd

def partial_function(f___,input,pos,value):
    tmp  = input[pos]
    input[pos] = value
    ret = f___(*input)
    input[pos] = tmp
    return ret

def partial_derivative(f,input):
    ret = np.empty(len(input))
    for i in range(len(input)):
        fg = lambda x:partial_function(f,input,i,x)
        ret[i] = nd.Derivative(fg)(input[i])
    return ret
if __name__ == "__main__":
    f     = lambda x,y: x*x*x+y*y
    input = np.array([1.0,1.0])
    print ('partial_derivative of f() at: '+str(input))
    print (partial_derivative(f,input))
最后:若您希望函数采用参数数组,例如:

f     = lambda x: x[0]*x[0]*x[0]+x[1]*x[1]
然后将相应的行替换为(删除“*”)


请记住,
np.vectorize
实际上并不比使用普通Python
for
循环做同样的事情快——它只是语法上的糖分。
ret = f___(input)