This class represents a pseudo expression with broadcasting and partial reduction features. It is the return type of DenseBase::colwise() and DenseBase::rowwise() and most of the time this is the only way it is explicitly used.
To understand the logic of rowwise/colwise expression, let's consider a generic case A.colwise().foo() where foo is any method of VectorwiseOp. This expression is equivalent to applying foo() to each column of A and then re-assemble the outputs in a matrix expression:
Matrix3d m = Matrix3d::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the sum of each column:" << endl << m.colwise().sum() << endl;
cout << "Here is the maximum absolute value of each column:"
<< endl << m.cwiseAbs().colwise().maxCoeff() << endl;
Output:
Here is the matrix m:
0.68 0.597 -0.33
-0.211 0.823 0.536
0.566 -0.605 -0.444
Here is the sum of each column:
1.04 0.815 -0.238
Here is the maximum absolute value of each column:
0.68 0.823 0.536
The begin() and end() methods are obviously exceptions to the previous rule as they return STL-compatible begin/end iterators to the rows or columns of the nested expression. Typical use cases include for-range-loop and calls to STL algorithms:
Example:
Matrix3i m = Matrix3i::Random();
cout << "Here is the initial matrix m:" << endl << m << endl;
int i = -1;
for(auto c: m.colwise()) {
c *= i;
++i;
}
cout << "Here is the matrix m after the for-range-loop:" << endl << m << endl;
auto cols = m.colwise();
auto it = std::find_if(cols.cbegin(), cols.cend(),
[](Matrix3i::ConstColXpr x) { return x.squaredNorm() == 0; });
cout << "The first empty column is: " << distance(cols.cbegin(),it) << endl;
Output:
Here is the initial matrix m:
7 6 -3
-2 9 6
6 -6 -5
Here is the matrix m after the for-range-loop:
-7 0 -3
2 0 6
-6 0 -5
The first empty column is: 1
For a partial reduction on an empty input, some rules apply. For the sake of clarity, let's consider a vertical reduction:
If the number of columns is zero, then a 1x0 row-major vector expression is returned.
Otherwise, if the number of rows is zero, then
a row vector of zeros is returned for sum-like reductions (sum, squaredNorm, norm, etc.)
a row vector of ones is returned for a product reduction (e.g., MatrixXd(n,0).colwise().prod())
an assert is triggered for all other reductions (minCoeff,maxCoeff,redux(bin_op))
a row (or column) vector expression representing whether all coefficients of each respective column (or row) are true. This expression can be assigned to a vector with entries of type bool.
a row (or column) vector expression representing whether atleast one coefficient of each respective column (or row) is true. This expression can be assigned to a vector with entries of type bool.
a row (or column) vector expression of the norm of each column (or row) of the referenced expression, using Blue's algorithm. This is a vector with real entries, even if the original matrix has complex entries.
a row (or column) vector expression representing the number of true coefficients of each respective column (or row). This expression can be assigned to a vector whose entries have the same type as is used to index entries of the original matrix; for dense matrices, this is std::ptrdiff_t .
Example:
Matrix3d m = Matrix3d::Random();
cout << "Here is the matrix m:" << endl << m << endl;
Matrix<ptrdiff_t, 3, 1> res = (m.array() >= 0.5).rowwise().count();
cout << "Here is the count of elements larger or equal than 0.5 of each row:" << endl;
cout << res << endl;
Output:
Here is the matrix m:
0.68 0.597 -0.33
-0.211 0.823 0.536
0.566 -0.605 -0.444
Here is the count of elements larger or equal than 0.5 of each row:
2
2
1
a row (or column) vector expression of the norm of each column (or row) of the referenced expression, avoiding underflow and overflow using a concatenation of hypot() calls. This is a vector with real entries, even if the original matrix has complex entries.
See also
DenseBase::hypotNorm()
lpNorm()
template<typename ExpressionType , int Direction>
template<int p>
const LpNormReturnType<p>::Type Eigen::VectorwiseOp< ExpressionType, Direction >::lpNorm
(
)
const
inline
Returns
a row (or column) vector expression of the norm of each column (or row) of the referenced expression. This is a vector with real entries, even if the original matrix has complex entries.
Example:
Matrix3d m = Matrix3d::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the norm of each column:" << endl << m.colwise().norm() << endl;
Output:
Here is the matrix m:
0.68 0.597 -0.33
-0.211 0.823 0.536
0.566 -0.605 -0.444
Here is the norm of each column:
0.91 1.18 0.771
a row (or column) vector expression of the largest coefficient of each column (or row) of the referenced expression.
Warning
the size along the reduction direction must be strictly positive, otherwise an assertion is triggered.
the result is undefined if *this contains NaN.
Example:
Matrix3d m = Matrix3d::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the maximum of each column:" << endl << m.colwise().maxCoeff() << endl;
Output:
Here is the matrix m:
0.68 0.597 -0.33
-0.211 0.823 0.536
0.566 -0.605 -0.444
Here is the maximum of each column:
0.68 0.823 0.536
a row (or column) vector expression of the smallest coefficient of each column (or row) of the referenced expression.
Warning
the size along the reduction direction must be strictly positive, otherwise an assertion is triggered.
the result is undefined if *this contains NaN.
Example:
Matrix3d m = Matrix3d::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the minimum of each column:" << endl << m.colwise().minCoeff() << endl;
Output:
Here is the matrix m:
0.68 0.597 -0.33
-0.211 0.823 0.536
0.566 -0.605 -0.444
Here is the minimum of each column:
-0.211 -0.605 -0.444
a row (or column) vector expression of the norm of each column (or row) of the referenced expression. This is a vector with real entries, even if the original matrix has complex entries.
Example:
Matrix3d m = Matrix3d::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the norm of each column:" << endl << m.colwise().norm() << endl;
Output:
Here is the matrix m:
0.68 0.597 -0.33
-0.211 0.823 0.536
0.566 -0.605 -0.444
Here is the norm of each column:
0.91 1.18 0.771
a row (or column) vector expression of the product of each column (or row) of the referenced expression.
Example:
Matrix3d m = Matrix3d::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the product of each row:" << endl << m.rowwise().prod() << endl;
Output:
Here is the matrix m:
0.68 0.597 -0.33
-0.211 0.823 0.536
0.566 -0.605 -0.444
Here is the product of each row:
-0.134
-0.0933
0.152
a matrix expression where each column (or row) are reversed.
Example:
MatrixXi m = MatrixXi::Random(3,4);
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the rowwise reverse of m:" << endl << m.rowwise().reverse() << endl;
cout << "Here is the colwise reverse of m:" << endl << m.colwise().reverse() << endl;
cout << "Here is the coefficient (1,0) in the rowise reverse of m:" << endl
<< m.rowwise().reverse()(1,0) << endl;
cout << "Let us overwrite this coefficient with the value 4." << endl;
//m.colwise().reverse()(1,0) = 4;
cout << "Now the matrix m is:" << endl << m << endl;
Output:
Here is the matrix m:
7 6 -3 1
-2 9 6 0
6 -6 -5 3
Here is the rowwise reverse of m:
1 -3 6 7
0 6 9 -2
3 -5 -6 6
Here is the colwise reverse of m:
6 -6 -5 3
-2 9 6 0
7 6 -3 1
Here is the coefficient (1,0) in the rowise reverse of m:
0
Let us overwrite this coefficient with the value 4.
Now the matrix m is:
7 6 -3 1
-2 9 6 0
6 -6 -5 3
This is the "in place" version of VectorwiseOp::reverse: it reverses each column or row of *this.
In most cases it is probably better to simply use the reversed expression of a matrix. However, when reversing the matrix data itself is really needed, then this "in-place" version is probably the right choice because it provides the following additional benefits:
less error prone: doing the same operation with .reverse() requires special care:
m = m.reverse().eval();
this API enables reverse operations without the need for a temporary
a row (or column) vector expression of the squared norm of each column (or row) of the referenced expression. This is a vector with real entries, even if the original matrix has complex entries.
Example:
Matrix3d m = Matrix3d::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the square norm of each row:" << endl << m.rowwise().squaredNorm() << endl;
Output:
Here is the matrix m:
0.68 0.597 -0.33
-0.211 0.823 0.536
0.566 -0.605 -0.444
Here is the square norm of each row:
0.928
1.01
0.884
a row (or column) vector expression of the norm of each column (or row) of the referenced expression, avoiding underflow and overflow. This is a vector with real entries, even if the original matrix has complex entries.
a row (or column) vector expression of the sum of each column (or row) of the referenced expression.
Example:
Matrix3d m = Matrix3d::Random();
cout << "Here is the matrix m:" << endl << m << endl;
cout << "Here is the sum of each row:" << endl << m.rowwise().sum() << endl;
Output:
Here is the matrix m:
0.68 0.597 -0.33
-0.211 0.823 0.536
0.566 -0.605 -0.444
Here is the sum of each row:
0.948
1.15
-0.483