关于 python:OpenMDAO 中是否可以在标量上定义组件的矢量化?

Is vectorization of Components defined on scalars possible in OpenMDAO?

在函数式编程的上下文中,接受并返回标量的函数可以映射到列表/向量上,以返回映射值的列表/向量。在常规 Python 中,我会在功能上或以 NumPy 的矢量化方式执行此操作:

1
2
3
4
5
6
7
8
import numpy as np # NumPy import

xs = [1,2,3,4,5] # List of inputs
f = lambda x: x**2 # Some function, which could be the equivalent of an ExplicitComponent

list(map(f, xs)) # Functional style
[ f(x) for x in xs ] # List comprehension
f(np.array(xs)) # NumPy vectorized style

这种行为可以使用 Components 实现吗?我的意思是 Component 可以接受标量输入并像普通函数一样执行,但也会自动对向量和可变长度的列表执行操作。

我无法在文档中找到类似的内容。我知道 OpenMDAO 中的大多数行为都使用 NumPy 的矢量化来提高效率,但这是否意味着所有可能具有矢量输入的组件都必须使用某种 self.options.declare('num_nodes', default=1) 方法并传递全局状态 n 来表示节点数对于所有 Components?

的长度/维度 n 的列表/向量

关于设计考虑,我知道在 NumPy 中默认情况下未实现输入向量的笛卡尔积的向量化,并且它们更像 zip。但对于单个 NumPy 数组,默??认情况下它确实像部分应用的映射函数一样工作,例如:

1
2
3
4
5
6
7
8
9
10
11
>>> xs = [1,2,3,4,5]
>>> f = lambda x,y: x**2 + y**2
>>> f(np.array(xs), np.array([2,4,6,8]))
Traceback (most recent call last):
  File"<stdin>", line 1, in <module>
  File"<stdin>", line 1, in <lambda>
ValueError: operands could not be broadcast together with shapes (5,) (4,)
>>> f(np.array(xs), np.array([2,4,6,8,10]))
array([  5,  20,  45,  80, 125])
>>> f(np.array(xs), 1)
array([ 2,  5, 10, 17, 26])

另一种方法是使用 NumPy 的 meshgrid(),如下所示:

1
2
3
4
xs, ys = [1,2,3,4,5], [2,4,6,8]
f = lambda x, y: x**2 + y**2
xys = np.meshgrid(xs, ys)
f(xys[0], xys[1])

那么对于 Components 来说,这样的行为是否更可行(也更可取!)?


从 OpenMDAO V3.1 开始,在 OpenMDAO 中执行此操作的唯一方法是通过诸如 num_nodesvec_size 之类的选项/参数。

其他用户表示有兴趣在组件中允许动态调整 IO。例如,输入的大小取决于它所连接的输出。请参阅 https://github.com/OpenMDAO/POEMs/pull/51。

我们正在努力解决这个问题,但目前还没有时间表说明何时能找到可接受的解决方案。