考虑以下代码:
#include <Eigen/Core>
using Matrix = Eigen::Matrix<float, 2, 2>;
Matrix func1(const Matrix& mat) { return mat + 0.5; }
Matrix func2(const Matrix& mat) { return mat / 0.5; }
func1()
不编译;需要将函数体中的mat
替换为mat.array()
进行修复([1])。然而,func2()
是编译原有。
我的问题是关于为什么API就是这样设计的。为什么标量加法和标量除法的处理方式不同?如果将以下方法添加到Matrix
类中会出现什么问题,为什么operator/
方法还没有出现这些问题?:
auto operator+(Scalar s) const { return this->array() + s; }
从数学的角度来看,一个标量加到一个矩阵"应该";与仅将标量添加到对角线相同。也就是说,数学文本通常使用M + 0.5
表示M + 0.5I
,而I
表示单位矩阵。有很多方法可以证明这一点。例如,您可以使用类比I = 1
,或者您可以在x
是矢量时使用Mx + 0.5x = (M + 0.5)x
,等等。
或者,可以取M + 0.5
将0.5
添加到每个元素中。这就是你认为正确的如果你不从线性代数的角度考虑矩阵并将它们视为数字的集合(数组),其中仅"广播"是很自然的;标量操作。
因为有多个"明显"在标量和矩阵之间处理+
的方法,当有人期望其中一个可能被另一个蒙蔽时,像Eigen那样做并禁止这样的表达式是一个好主意。然后,你被迫用一种不那么模棱两可的方式来表示你想要的东西。
/
从代数角度的自然定义与数组角度一致,因此没有理由禁止它。