Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/wcf/4.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
具有任意输入和输出维数的向量值多元函数的Numpy/Scipy逼近_Numpy_Scipy_Interpolation_Taylor Series_Function Approximation - Fatal编程技术网

具有任意输入和输出维数的向量值多元函数的Numpy/Scipy逼近

具有任意输入和输出维数的向量值多元函数的Numpy/Scipy逼近,numpy,scipy,interpolation,taylor-series,function-approximation,Numpy,Scipy,Interpolation,Taylor Series,Function Approximation,起点是m维向量值函数 , 其中,输入也是一个n维向量: 此函数的输入和输出是numpy向量。这个函数计算起来很昂贵,所以我需要一个近似值/插值 是否存在一个numpy/scipy函数,该函数在任意尺寸m,n的x的给定值附近返回近似值,例如泰勒展开 所以本质上,我要求对scipy.interpolate.approximate_taylor_多项式进行推广,因为我也对近似的二次项感兴趣 在scipy.interpolate中,向量值x似乎有一些选项,但仅针对标量函数,但仅在函数的m个分量上循环不

起点是m维向量值函数

,

其中,输入也是一个n维向量:

此函数的输入和输出是numpy向量。这个函数计算起来很昂贵,所以我需要一个近似值/插值

是否存在一个numpy/scipy函数,该函数在任意尺寸m,n的x的给定值附近返回近似值,例如泰勒展开

所以本质上,我要求对scipy.interpolate.approximate_taylor_多项式进行推广,因为我也对近似的二次项感兴趣

在scipy.interpolate中,向量值x似乎有一些选项,但仅针对标量函数,但仅在函数的m个分量上循环不是一个选项,因为这些分量无法单独计算,并且调用函数的频率将超过必要的频率


如果这样的函数不存在,那么使用现有方法并避免不必要的函数调用的快速方法也会很好。

我认为您必须使用自己的近似方法。想法很简单:在一些合理的点对函数进行采样(至少与泰勒近似中的单项式一样多,但最好更多),然后用
np.linalg.lstsq
拟合系数。实际配合是一条线,其余的是准备

我将使用一个n=3,m=2的例子,三个变量和二维值。初始设置:

import numpy as np
def f(point):
  x, y, z = point[0], point[1], point[2]
  return np.array([np.exp(x + 2*y + 3*z), np.exp(3*x + 2*y + z)]) 
n = 3
m = 2
scale = 0.1
比例
参数的选择受到与
近似泰勒多项式
文档字符串相同的考虑(参见)

下一步是生成点。对于n个变量,二次拟合涉及
1+n+n*(n+1)/2
单项式(一个常数,n个线性,n(n+1)/2个二次)。我使用
1+n+n**2
点,这些点位于
(0,0,0)
周围,具有一个或两个非零坐标。具体的选择有些武断;我找不到多元二次拟合的“标准”样本点选择

points = [np.zeros((n, ))]
points.extend(scale*np.eye(n))
for i in range(n):
    for j in range(n):
        point = np.zeros((n,))
        point[i], point[j] = scale, -scale
        points.append(point)
points = np.array(points)
values = f(points.T).T
数组
values
保存每个点的函数值。前一行是调用
f
的唯一位置。下一步,为模型生成单项式,并在这些相同的点上对其进行评估

monomials = [np.zeros((1, n)), np.eye(n)]
for i in range(n):
    for j in range(i, n):
        monom = np.zeros((1, n))
        monom[0, i] += 1
        monom[0, j] += 1
        monomials.append(monom)
monomials = np.concatenate(monomials, axis=0)
monom_values = np.prod(points**monomials[:, None, :], axis=-1).T
让我们回顾一下情况:我们有函数的
值,这里有形状(13,2)的值,还有单项式的值,形状(13,10)的值。这里13是点数,10是单项式数。对于
值的每一列
lstsq
方法将找到最接近它的
单项式
列的线性组合。这些是我们想要的系数

coeffs = np.linalg.lstsq(monom_values, values, rcond=None)[0]
让我们看看这些是否有用。系数为

[[1.         1.        ]
 [1.01171761 3.03011523]
 [2.01839762 2.01839762]
 [3.03011523 1.01171761]
 [0.50041681 4.53385141]
 [2.00667556 6.04011017]
 [3.02759266 3.02759266]
 [2.00667556 2.00667556]
 [6.04011017 2.00667556]
 [4.53385141 0.50041681]]
数组
单项式
,仅供参考

[[0. 0. 0.]
 [1. 0. 0.]
 [0. 1. 0.]
 [0. 0. 1.]
 [2. 0. 0.]
 [1. 1. 0.]
 [1. 0. 1.]
 [0. 2. 0.]
 [0. 1. 1.]
 [0. 0. 2.]]
因此,例如,编码为
[2、0、0]
、的单体
x**2
,得到函数的两个组件的系数
[0.50041681 4.53385141]
。这很有意义,因为它在
exp(x+2*y+3*z)
的泰勒展开式中的系数是0.5,在
exp(3*x+2*y+z)
的泰勒展开式中的系数是4.5

函数f的近似值可通过以下公式获得:

def fFit(point,coeffs,monomials):
    return np.prod(point**monomials[:, None, :], axis=-1).T.dot(coeffs)[0]

testpoint = np.array([0.05,-0.05,0.0])

# true value:
print(f(testpoint)) # output: [ 0.95122942  1.0512711 ]

# approximation:
print(fFit(testpoint,coeffs,monomials)) # output: [ 0.95091704  1.05183692]

谢谢,完美的答案!一个小评论:有n(n+1)/2个二次单项式,例如,对于n=3,有6个。无法编辑您的答案,因为必须更改至少6个字符。