Reductions
In Eigen, a reduction is a function taking a matrix or array, and returning a single scalar value.最常用的归约方法之一是.sum(),它返回给定矩阵或数组内所有元素的总和。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #include <iostream> #include <Eigen/Dense> using namespace std; int main() { Eigen::Matrix2d mat; mat << 1, 2, 3, 4; cout << "Here is mat.sum(): " << mat.sum() << endl; cout << "Here is mat.prod(): " << mat.prod() << endl; cout << "Here is mat.mean(): " << mat.mean() << endl; cout << "Here is mat.minCoeff(): " << mat.minCoeff() << endl; cout << "Here is mat.maxCoeff(): " << mat.maxCoeff() << endl; cout << "Here is mat.trace(): " << mat.trace() << endl; } |
输出:
1 2 3 4 5 6 | ere is mat.sum(): 10 Here is mat.prod(): 24 Here is mat.mean(): 2.5 Here is mat.minCoeff(): 1 Here is mat.maxCoeff(): 4 Here is mat.trace(): 5 |
The trace of a matrix, as returned by the function
范数计算
向量的平方范数可以通过squaredNorm()获得。它其系数的平方的绝对值之和。
Eigen还提供了norm()方法,该方法返回squaredNorm()的平方根。
这些运算也可以在矩阵上运算。在这种情况下,n×p矩阵被视为大小为(n * p)的向量,因此例如norm()方法返回“ Frobenius”或“ Hilbert-Schmidt”范数。
如果你想使用其他Lp范数,可以使用lpNorm< p >()方法。
p可以取Infinity,which is the maximum of the absolute values of the coefficients.
下面的示例演示了这些方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <Eigen/Dense> #include <iostream> using namespace std; using namespace Eigen; int main() { VectorXf v(2); MatrixXf m(2,2), n(2,2); v << -1, 2; m << 1,-2, -3,4; cout << "v.squaredNorm() = " << v.squaredNorm() << endl; cout << "v.norm() = " << v.norm() << endl; cout << "v.lpNorm<1>() = " << v.lpNorm<1>() << endl; cout << "v.lpNorm<Infinity>() = " << v.lpNorm<Infinity>() << endl; cout << endl; cout << "m.squaredNorm() = " << m.squaredNorm() << endl; cout << "m.norm() = " << m.norm() << endl; cout << "m.lpNorm<1>() = " << m.lpNorm<1>() << endl; cout << "m.lpNorm<Infinity>() = " << m.lpNorm<Infinity>() << endl; } |
输出:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <Eigen/Dense> #include <iostream> using namespace std; using namespace Eigen; int main() { VectorXf v(2); MatrixXf m(2,2), n(2,2); v << -1, 2; m << 1,-2, -3,4; cout << "v.squaredNorm() = " << v.squaredNorm() << endl; cout << "v.norm() = " << v.norm() << endl; cout << "v.lpNorm<1>() = " << v.lpNorm<1>() << endl; cout << "v.lpNorm<Infinity>() = " << v.lpNorm<Infinity>() << endl; cout << endl; cout << "m.squaredNorm() = " << m.squaredNorm() << endl; cout << "m.norm() = " << m.norm() << endl; cout << "m.lpNorm<1>() = " << m.lpNorm<1>() << endl; cout << "m.lpNorm<Infinity>() = " << m.lpNorm<Infinity>() << endl; } |
Operator norm: 1-norm和∞-norm可以通过其他方式得到。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | #include <Eigen/Dense> #include <iostream> using namespace std; using namespace Eigen; int main() { VectorXf v(2); MatrixXf m(2,2), n(2,2); v << -1, 2; m << 1,-2, -3,4; cout << "v.squaredNorm() = " << v.squaredNorm() << endl; cout << "v.norm() = " << v.norm() << endl; cout << "v.lpNorm<1>() = " << v.lpNorm<1>() << endl; cout << "v.lpNorm<Infinity>() = " << v.lpNorm<Infinity>() << endl; cout << endl; cout << "m.squaredNorm() = " << m.squaredNorm() << endl; cout << "m.norm() = " << m.norm() << endl; cout << "m.lpNorm<1>() = " << m.lpNorm<1>() << endl; cout << "m.lpNorm<Infinity>() = " << m.lpNorm<Infinity>() << endl; } |
输出:
1 2 | 1-norm(m) = 6 == 6 infty-norm(m) = 7 == 7 |
有关这些表达式的语法的更多说明,请参见下文。
Boolean reductions
以下归约运算适用于布尔值:
- all() returns true if all of the coefficients in a given Matrix or Array evaluate to true .
- any() returns true if at least one of the coefficients in a given Matrix or Array evaluates to true .
- count() returns the number of coefficients in a given Matrix or Array that evaluate to true.
这些通常与Array提供的按元素比较和相等运算符结合使用。
For instance,
在以下示例中可以看到:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <Eigen/Dense> #include <iostream> using namespace std; using namespace Eigen; int main() { ArrayXXf a(2,2); a << 1,2, 3,4; cout << "(a > 0).all() = " << (a > 0).all() << endl; cout << "(a > 0).any() = " << (a > 0).any() << endl; cout << "(a > 0).count() = " << (a > 0).count() << endl; cout << endl; cout << "(a > 2).all() = " << (a > 2).all() << endl; cout << "(a > 2).any() = " << (a > 2).any() << endl; cout << "(a > 2).count() = " << (a > 2).count() << endl; } |
输出:
1 2 3 4 5 6 7 | (a > 0).all() = 1 (a > 0).any() = 1 (a > 0).count() = 4 (a > 2).all() = 0 (a > 2).any() = 1 (a > 2).count() = 2 |
用户定义的Reductions
查看DenseBase :: redux()函数。
Visitors
Visitors are useful when one wants to obtain the location of a coefficient inside a Matrix or Array.
最简单的示例是maxCoeff(&x,&y)和minCoeff(&x,&y),用于查找Matrix或Array中最大或最小元素的位置。
传递给Visitors的参数是指向要存储行和列位置变量的指针。这些变量应为Index类型,如下所示:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 | #include <iostream> #include <Eigen/Dense> using namespace std; using namespace Eigen; int main() { Eigen::MatrixXf m(2,2); m << 1, 2, 3, 4; //get location of maximum MatrixXf::Index maxRow, maxCol; float max = m.maxCoeff(&maxRow, &maxCol); //get location of minimum MatrixXf::Index minRow, minCol; float min = m.minCoeff(&minRow, &minCol); cout << "Max: " << max << ", at: " << maxRow << "," << maxCol << endl; cout << "Min: " << min << ", at: " << minRow << "," << minCol << endl; } |
输出:
1 2 | Max: 4, at: 1,1 Min: 1, at: 0,0 |
Partial reductions
Partial reductions是可以在Matrix或Array上按列或按行操作的reductions,对每个列或行应用reductions运算,并返回具有相应值的列或行向量。Partial reductions适用于colwise()或rowwise()。
一个简单的示例是获取给定矩阵中每一列中元素的最大值,并将结果存储在行向量中:
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <iostream> #include <Eigen/Dense> using namespace std; int main() { Eigen::MatrixXf mat(2,4); mat << 1, 2, 6, 9, 3, 1, 7, 2; std::cout << "Column's maximum: " << std::endl << mat.colwise().maxCoeff() << std::endl; } |
输出:
1 2 | Column's maximum: 3 2 7 9 |
可以逐行执行相同的操作:
1 2 3 4 5 6 7 8 9 10 11 12 13 | #include <iostream> #include <Eigen/Dense> using namespace std; int main() { Eigen::MatrixXf mat(2,4); mat << 1, 2, 6, 9, 3, 1, 7, 2; std::cout << "Row's maximum: " << std::endl << mat.rowwise().maxCoeff() << std::endl; } |
输出:
1 2 3 | Row's maximum: 9 7 |
Note that column-wise operations return a row vector, while row-wise operations return a column vector.
将Partial reductions与其他操作结合起来
将Partial reductions的结果进行进一步处理。
Here is another example that finds the column whose sum of elements is the maximum within a matrix. With column-wise partial reductions this can be coded as:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <iostream> #include <Eigen/Dense> using namespace std; using namespace Eigen; int main() { MatrixXf mat(2,4); mat << 1, 2, 6, 9, 3, 1, 7, 2; MatrixXf::Index maxIndex; float maxNorm = mat.colwise().sum().maxCoeff(&maxIndex); std::cout << "Maximum sum at position " << maxIndex << std::endl; std::cout << "The corresponding vector is: " << std::endl; std::cout << mat.col( maxIndex ) << std::endl; std::cout << "And its sum is is: " << maxNorm << std::endl; } |
输出:
1 2 3 4 5 | Maximum sum at position 2 The corresponding vector is: 6 7 And its sum is is: 13 |
广播
广播背后的概念类似于 partial reductions,with the difference that broadcasting constructs an expression where a vector (column or row) is interpreted as a matrix by replicating it in one direction.
一个简单的示例是将某个列向量添加到矩阵中的每一列。这可以通过以下方式完成:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 | #include <iostream> #include <Eigen/Dense> using namespace std; int main() { Eigen::MatrixXf mat(2,4); Eigen::VectorXf v(2); mat << 1, 2, 6, 9, 3, 1, 7, 2; v << 0, 1; //add v to each column of m mat.colwise() += v; std::cout << "Broadcasting result: " << std::endl; std::cout << mat << std::endl; } |
输出:
1 2 3 | Broadcasting result: 1 2 6 9 4 2 8 3 |
要指出的是,要逐列或逐行添加的向量必须为Vector类型,并且不能为Matrix。如果不满足,则会出现编译时错误。这也意味着,在使用Matrix进行操作时,只能对Vector类型的对象应用广播操作。这同样适用于Array类,其中等效VectorXf是ArrayXf。与往常一样,您不应在同一表达式中混合使用数组和矩阵。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #include <iostream> #include <Eigen/Dense> using namespace std; int main() { Eigen::MatrixXf mat(2,4); Eigen::VectorXf v(4); mat << 1, 2, 6, 9, 3, 1, 7, 2; v << 0,1,2,3; //add v to each row of m mat.rowwise() += v.transpose(); std::cout << "Broadcasting result: " << std::endl; std::cout << mat << std::endl; } |
输出:
1 2 3 | Broadcasting result: 1 3 8 12 3 2 9 5 |
将广播与其他操作结合
Broadcasting can also be combined with other operations, such as Matrix or Array operations, reductions and partial reductions.我们可以深入研究一个更高级的示例:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | #include <iostream> #include <Eigen/Dense> using namespace std; using namespace Eigen; int main() { Eigen::MatrixXf m(2,4); Eigen::VectorXf v(2); m << 1, 23, 6, 9, 3, 11, 7, 2; v << 2, 3; MatrixXf::Index index; // find nearest neighbour (m.colwise() - v).colwise().squaredNorm().minCoeff(&index); cout << "Nearest neighbour is column " << index << ":" << endl; cout << m.col(index) << endl; } |
输出:
1 2 3 | Nearest neighbour is column 0: 1 3 |