1

我有一个 Python 函数,它有 2 个输入 X0 和 X1 以及 1 个输出 Y:

def mySimulator(x):
    y0 = 1. - x[0] * x[1]
    y = [y0]
    return y

例如,当 X0~Normal(1,3) 和 X1~Normal(2,4) 时,我想估计泰勒分解的输出 Y 的方差。

使用OpenTURNS很容易:

import openturns as ot
g = ot.PythonFunction(2,1,mySimulator)
distX0 = ot.Normal(1.,3.)
distX1 = ot.Normal(2.,4.)
X = ot.ComposedDistribution([distX0,distX1])
XRV = ot.RandomVector(X)
Y = ot.CompositeRandomVector(g, XRV)
taylor = ot.TaylorExpansionMoments(Y)
sigma2 = taylor.getCovariance()
print(sigma2)

前面的脚本打印:

>>> print(sigma2)
[[ 52 ]]

泰勒展开式的协方差基于函数的梯度和边际的方差。问题是这里函数的梯度是从有限差分中计算出来的。很遗憾,因为这里的精确梯度很容易计算:

def myGradient(x):
    dy0dx0 = -x[1]
    dy0dx1 = -x[0]
    gradient = [[dy0dx0],[dy0dx1]]
    return gradient

但是,我不知道如何定义PythonFunction具有用户定义渐变的 a:这可能吗?

我在文档中搜索,发现以下有用的页面,这些页面并没有引导我找到解决方案:

4

1 回答 1

0

其实,我自己找到了答案。有PythonFunction一个gradient选项可以设置函数的梯度。

我首先使用以下 Python 函数定义了渐变,该函数返回一个 OpenTURNS Matrix

def myGradient(x):
    dy0dx0 = -x[1]
    dy0dx1 = -x[0]
    gradient = ot.Matrix([[dy0dx0],[dy0dx1]])
    return gradient

然后PythonFunction可以按如下方式定义和使用:只改变函数的定义,不改变脚本的其余部分。

g = ot.PythonFunction(2,1,mySimulator,gradient=myGradient)
XRV = ot.RandomVector(X)
Y = ot.CompositeRandomVector(g, XRV)
taylor = ot.TaylorExpansionMoments(Y)
sigma2 = taylor.getCovariance()
于 2019-11-29T18:11:16.873 回答