在 OpenMDAO 中,我可以使用 set_check_partial_options 来防止检查某些导数吗?
In OpenMDAO can I use set_check_partial_options to prevent certain derivatives from being checked?
我有一个om.ExplicitComponent
,其中一些导数是精确的(解析的)并且可以用复杂的步骤方法检查(cs
),一些导数是解析的但不能用 cs
检查,有些只能用有限差分求值。
import openmdao.api as om
from scipy.special import ellipe, ellipk
from scipy.special import hyp2f1
class MWE(om.ExplicitComponent):
def setup(self):
self.add_input("a")
self.add_input("b")
self.add_input("c")
self.add_output("x")
self.add_output("y")
self.add_output("z")
def compute(self, inputs, outputs):
a = inputs["a"]
b = inputs["b"]
c = inputs["c"]
outputs["x"] = a**2
outputs["y"] = ellipe(b)
outputs["z"] = hyp2f1(1 / 10, a, 1 / 2, c)
def setup_partials(self):
self.declare_partials("x", ["a"], method="exact")
self.declare_partials("y", ["b"], method="exact")
self.declare_partials("z", ["a"], method="fd")
self.declare_partials("z", ["c"], method="exact")
def compute_partials(self, inputs, J):
a = inputs["a"]
b = inputs["b"]
c = inputs["c"]
J["x", "a"] = 2 * a
J["y", "b"] = (ellipe(b) - ellipk(b)) / (2 * b)
J["z", "c"] = (a / 5) * hyp2f1(11 / 10, 1 + a, 3 / 2, c)
有没有一种方法可以使用一次或多次调用 set_check_partial_options
和 check_partials
来
- 使用 cs 方法检查
J["x", "a"]
,因为它是最精确或要求最高的,
- 使用 fd 方法检查
J["y", "b"]
,因为椭圆函数不能处理复数,
- 出于同样的原因使用 fd 方法检查
J["z", "c"]
。
- 根本不用检查
J["z", "a"]
,因为它无论如何都需要使用 fd
进行评估,因为没有可能的分析公式(至少在 scipy 内)。
?
您可以使用 set_check_partials
方法对如何执行检查进行细粒度控制。此方法在特定组件的 setup
或 setup_partials
内设置,可让您分别控制每个输入的设置。
如果要将整个组件设置为 CS 或 FD,可以使用“*”作为 wrt
参数。
请注意,这些组件级设置会被您传递给 check_partials
方法本身的 method
参数覆盖。所以只需将其留空并使用其自己的本地设置配置每个组件。
不幸的是,V3.15 中似乎有一个与 set_check_partials_options
有关的错误。以下是模型的正确语法,但如果您取消注释 cs
选项,则会引发错误。对于 V3.15 及更低版本,您必须使用 CS 或 none 检查所有内容。 V3.16应该会修复
import openmdao.api as om
from scipy.special import ellipe, ellipk
from scipy.special import hyp2f1
class MWE(om.ExplicitComponent):
def setup(self):
self.add_input("a")
self.add_input("b")
self.add_input("c")
self.add_output("x")
self.add_output("y")
self.add_output("z")
def compute(self, inputs, outputs):
a = inputs["a"]
b = inputs["b"]
c = inputs["c"]
outputs["x"] = a**2
outputs["y"] = ellipe(b)
outputs["z"] = hyp2f1(1 / 10, a, 1 / 2, c)
def setup_partials(self):
self.declare_partials("x", ["a"], method="exact")
self.declare_partials("y", ["b"], method="exact")
self.declare_partials("z", ["a"], method="fd")
self.declare_partials("z", ["c"], method="exact")
# self.set_check_partial_options(wrt="a", method="cs") # bug in V3.15
self.set_check_partial_options(wrt="a", form="backward")
self.set_check_partial_options(wrt="b", form="central")
def compute_partials(self, inputs, J):
a = inputs["a"]
b = inputs["b"]
c = inputs["c"]
J["x", "a"] = 2 * a
J["y", "b"] = (ellipe(b) - ellipk(b)) / (2 * b)
J["z", "c"] = (a / 5) * hyp2f1(11 / 10, 1 + a, 3 / 2, c)
if __name__ == "__main__":
p = om.Problem()
p.model = MWE()
p.setup(force_alloc_complex=True)
# set some workable initial values to avoid inf
p['a'] = 2.
p['b'] = -2.
p['c'] = -2.
p.run_model()
p.model.list_outputs()
p.check_partials()
我有一个om.ExplicitComponent
,其中一些导数是精确的(解析的)并且可以用复杂的步骤方法检查(cs
),一些导数是解析的但不能用 cs
检查,有些只能用有限差分求值。
import openmdao.api as om
from scipy.special import ellipe, ellipk
from scipy.special import hyp2f1
class MWE(om.ExplicitComponent):
def setup(self):
self.add_input("a")
self.add_input("b")
self.add_input("c")
self.add_output("x")
self.add_output("y")
self.add_output("z")
def compute(self, inputs, outputs):
a = inputs["a"]
b = inputs["b"]
c = inputs["c"]
outputs["x"] = a**2
outputs["y"] = ellipe(b)
outputs["z"] = hyp2f1(1 / 10, a, 1 / 2, c)
def setup_partials(self):
self.declare_partials("x", ["a"], method="exact")
self.declare_partials("y", ["b"], method="exact")
self.declare_partials("z", ["a"], method="fd")
self.declare_partials("z", ["c"], method="exact")
def compute_partials(self, inputs, J):
a = inputs["a"]
b = inputs["b"]
c = inputs["c"]
J["x", "a"] = 2 * a
J["y", "b"] = (ellipe(b) - ellipk(b)) / (2 * b)
J["z", "c"] = (a / 5) * hyp2f1(11 / 10, 1 + a, 3 / 2, c)
有没有一种方法可以使用一次或多次调用 set_check_partial_options
和 check_partials
来
- 使用 cs 方法检查
J["x", "a"]
,因为它是最精确或要求最高的, - 使用 fd 方法检查
J["y", "b"]
,因为椭圆函数不能处理复数, - 出于同样的原因使用 fd 方法检查
J["z", "c"]
。 - 根本不用检查
J["z", "a"]
,因为它无论如何都需要使用fd
进行评估,因为没有可能的分析公式(至少在 scipy 内)。 ?
您可以使用 set_check_partials
方法对如何执行检查进行细粒度控制。此方法在特定组件的 setup
或 setup_partials
内设置,可让您分别控制每个输入的设置。
如果要将整个组件设置为 CS 或 FD,可以使用“*”作为 wrt
参数。
请注意,这些组件级设置会被您传递给 check_partials
方法本身的 method
参数覆盖。所以只需将其留空并使用其自己的本地设置配置每个组件。
不幸的是,V3.15 中似乎有一个与 set_check_partials_options
有关的错误。以下是模型的正确语法,但如果您取消注释 cs
选项,则会引发错误。对于 V3.15 及更低版本,您必须使用 CS 或 none 检查所有内容。 V3.16应该会修复
import openmdao.api as om
from scipy.special import ellipe, ellipk
from scipy.special import hyp2f1
class MWE(om.ExplicitComponent):
def setup(self):
self.add_input("a")
self.add_input("b")
self.add_input("c")
self.add_output("x")
self.add_output("y")
self.add_output("z")
def compute(self, inputs, outputs):
a = inputs["a"]
b = inputs["b"]
c = inputs["c"]
outputs["x"] = a**2
outputs["y"] = ellipe(b)
outputs["z"] = hyp2f1(1 / 10, a, 1 / 2, c)
def setup_partials(self):
self.declare_partials("x", ["a"], method="exact")
self.declare_partials("y", ["b"], method="exact")
self.declare_partials("z", ["a"], method="fd")
self.declare_partials("z", ["c"], method="exact")
# self.set_check_partial_options(wrt="a", method="cs") # bug in V3.15
self.set_check_partial_options(wrt="a", form="backward")
self.set_check_partial_options(wrt="b", form="central")
def compute_partials(self, inputs, J):
a = inputs["a"]
b = inputs["b"]
c = inputs["c"]
J["x", "a"] = 2 * a
J["y", "b"] = (ellipe(b) - ellipk(b)) / (2 * b)
J["z", "c"] = (a / 5) * hyp2f1(11 / 10, 1 + a, 3 / 2, c)
if __name__ == "__main__":
p = om.Problem()
p.model = MWE()
p.setup(force_alloc_complex=True)
# set some workable initial values to avoid inf
p['a'] = 2.
p['b'] = -2.
p['c'] = -2.
p.run_model()
p.model.list_outputs()
p.check_partials()