alpha 3.1. in this commit:

- finally get the Eval stuff right. get back to having Eval as
  a subclass of Matrix with limited functionality, and then,
  add a typedef MatrixType to get the actual matrix type.
- add swap(), findBiggestCoeff()
- bugfix by Ramon in Transpose
- new demo: doc/echelon.cpp
This commit is contained in:
Benoit Jacob 2008-01-15 13:55:47 +00:00
parent 9c9a42cc49
commit c67e717404
32 changed files with 262 additions and 94 deletions

View File

@ -4,8 +4,8 @@
namespace Eigen {
#include "src/Core/Util.h"
#include "src/Core/ForwardDeclarations.h"
#include "src/Core/Util.h"
#include "src/Core/NumTraits.h"
#include "src/Core/MathFunctions.h"
#include "src/Core/MatrixBase.h"
@ -38,5 +38,6 @@ namespace Eigen {
#include "src/Core/Fuzzy.h"
#include "src/Core/Map.h"
#include "src/Core/IO.h"
#include "src/Core/Swap.h"
} // namespace Eigen

View File

@ -56,8 +56,9 @@ template<typename MatrixType> class Block
public:
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Ref MatRef;
friend class MatrixBase<Scalar, Block<MatrixType> >;
friend class MatrixBase<Scalar, Block>;
typedef MatrixBase<Scalar, Block> Base;
Block(const MatRef& matrix,
int startRow, int startCol,
int blockRows, int blockCols)

View File

@ -52,7 +52,8 @@ template<typename NewScalar, typename MatrixType> class Cast : NoOperatorEquals,
public:
typedef NewScalar Scalar;
typedef typename MatrixType::Ref MatRef;
friend class MatrixBase<Scalar, Cast<Scalar, MatrixType> >;
friend class MatrixBase<Scalar, Cast>;
typedef MatrixBase<Scalar, Cast> Base;
Cast(const MatRef& matrix) : m_matrix(matrix) {}

View File

@ -52,7 +52,8 @@ template<typename MatrixType> class Column
public:
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Ref MatRef;
friend class MatrixBase<Scalar, Column<MatrixType> >;
friend class MatrixBase<Scalar, Column>;
typedef MatrixBase<Scalar, Column> Base;
Column(const MatRef& matrix, int col)
: m_matrix(matrix), m_col(col)

View File

@ -44,7 +44,8 @@ template<typename MatrixType> class Conjugate : NoOperatorEquals,
public:
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Ref MatRef;
friend class MatrixBase<Scalar, Conjugate<MatrixType> >;
friend class MatrixBase<Scalar, Conjugate>;
typedef MatrixBase<Scalar, Conjugate> Base;
Conjugate(const MatRef& matrix) : m_matrix(matrix) {}

View File

@ -44,8 +44,9 @@ template<typename MatrixType> class DiagonalCoeffs
public:
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Ref MatRef;
friend class MatrixBase<Scalar, DiagonalCoeffs<MatrixType> >;
friend class MatrixBase<Scalar, DiagonalCoeffs>;
typedef MatrixBase<Scalar, DiagonalCoeffs> Base;
DiagonalCoeffs(const MatRef& matrix) : m_matrix(matrix) {}
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(DiagonalCoeffs)

View File

@ -47,8 +47,9 @@ class DiagonalMatrix : NoOperatorEquals,
public:
typedef typename CoeffsVectorType::Scalar Scalar;
typedef typename CoeffsVectorType::Ref CoeffsVecRef;
friend class MatrixBase<Scalar, DiagonalMatrix<CoeffsVectorType> >;
friend class MatrixBase<Scalar, DiagonalMatrix>;
typedef MatrixBase<Scalar, DiagonalMatrix> Base;
DiagonalMatrix(const CoeffsVecRef& coeffs) : m_coeffs(coeffs)
{
assert(CoeffsVectorType::Traits::IsVectorAtCompileTime

View File

@ -47,7 +47,8 @@ template<typename Lhs, typename Rhs> class Difference : NoOperatorEquals,
typedef typename Lhs::Ref LhsRef;
typedef typename Rhs::Ref RhsRef;
friend class MatrixBase<Scalar, Difference>;
typedef MatrixBase<Scalar, Difference> Base;
Difference(const LhsRef& lhs, const RhsRef& rhs)
: m_lhs(lhs), m_rhs(rhs)
{

View File

@ -45,53 +45,33 @@
*
* \sa MatrixBase::eval()
*/
template<typename ExpressionType> class Eval
: public MatrixBase<typename ExpressionType::Scalar, Eval<ExpressionType> >
template<typename ExpressionType> class Eval : NoOperatorEquals,
public Matrix< typename ExpressionType::Scalar,
ExpressionType::Traits::RowsAtCompileTime,
ExpressionType::Traits::ColsAtCompileTime,
EIGEN_DEFAULT_MATRIX_STORAGE_ORDER,
ExpressionType::Traits::MaxRowsAtCompileTime,
ExpressionType::Traits::MaxColsAtCompileTime>
{
public:
typedef typename ExpressionType::Scalar Scalar;
friend class MatrixBase<Scalar, Eval>;
typedef MatrixBase<Scalar, Eval> Base;
friend class MatrixRef<Eval>;
typedef MatrixRef<Eval> Ref;
private:
enum {
RowsAtCompileTime = ExpressionType::Traits::RowsAtCompileTime,
ColsAtCompileTime = ExpressionType::Traits::ColsAtCompileTime,
MaxRowsAtCompileTime = ExpressionType::Traits::MaxRowsAtCompileTime,
MaxColsAtCompileTime = ExpressionType::Traits::MaxColsAtCompileTime
};
typedef Matrix<typename ExpressionType::Scalar,
/** The actual matrix type to evaluate to. This type can be used independently
* of the rest of this class to get the actual matrix type to evaluate and store
* the value of an expression.
*
* Here is an example illustrating this:
* \include Eval_MatrixType.cpp
* Output: \verbinclude Eval_MatrixType.out
*/
typedef Matrix<Scalar,
ExpressionType::Traits::RowsAtCompileTime,
ExpressionType::Traits::ColsAtCompileTime,
EIGEN_DEFAULT_MATRIX_STORAGE_ORDER,
ExpressionType::Traits::MaxRowsAtCompileTime,
ExpressionType::Traits::MaxColsAtCompileTime> MatrixType;
int _rows() const { return m_matrix.rows(); }
int _cols() const { return m_matrix.cols(); }
Ref _ref() const { return Ref(*this); }
const Scalar& _coeff(int row, int col) const
{
return m_matrix._coeff(row, col);
}
Scalar& _coeffRef(int row, int col)
{
return m_matrix._coeffRef(row, col);
}
public:
template<typename Derived>
Eval(const MatrixBase<Scalar, Derived>& other) : m_matrix(other) {}
~Eval() {}
EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Eval)
protected:
MatrixType m_matrix;
explicit Eval(const ExpressionType& expr) : MatrixType(expr) {}
};
/** Evaluates *this, which can be any expression, and returns the obtained matrix.
@ -110,7 +90,7 @@ template<typename ExpressionType> class Eval
template<typename Scalar, typename Derived>
const Eval<Derived> MatrixBase<Scalar, Derived>::eval() const
{
return Eval<Derived>(ref());
return Eval<Derived>(*static_cast<const Derived*>(this));
}
#endif // EIGEN_EVAL_H

View File

@ -55,8 +55,9 @@ template<typename MatrixType, int BlockRows, int BlockCols> class FixedBlock
public:
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Ref MatRef;
friend class MatrixBase<Scalar, FixedBlock<MatrixType, BlockRows, BlockCols> >;
friend class MatrixBase<Scalar, FixedBlock>;
typedef MatrixBase<Scalar, FixedBlock> Base;
FixedBlock(const MatRef& matrix, int startRow, int startCol)
: m_matrix(matrix), m_startRow(startRow), m_startCol(startCol)
{

View File

@ -47,8 +47,8 @@ template<typename MatrixType> class Ones;
template<typename CoeffsVectorType> class DiagonalMatrix;
template<typename MatrixType> class DiagonalCoeffs;
template<typename MatrixType> class Identity;
template<typename ExpressionType> class Eval;
template<typename MatrixType> class Map;
template<typename Derived> class Eval;
template<typename T> struct Reference
{
@ -61,10 +61,4 @@ struct Reference<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols
typedef MatrixRef<Matrix<_Scalar, _Rows, _Cols, _StorageOrder, _MaxRows, _MaxCols> > Type;
};
template<typename ExpressionType>
struct Reference<Eval<ExpressionType> >
{
typedef MatrixRef<Eval<ExpressionType> > Type;
};
#endif // EIGEN_FORWARDDECLARATIONS_H

View File

@ -37,8 +37,9 @@ template<typename MatrixType> class Identity : NoOperatorEquals,
{
public:
typedef typename MatrixType::Scalar Scalar;
friend class MatrixBase<Scalar, Identity<MatrixType> >;
friend class MatrixBase<Scalar, Identity>;
typedef MatrixBase<Scalar, Identity> Base;
Identity(int rows, int cols) : m_rows(rows), m_cols(cols)
{
assert(rows > 0

View File

@ -44,7 +44,8 @@ template<typename MatrixType> class Map
{
public:
typedef typename MatrixType::Scalar Scalar;
friend class MatrixBase<Scalar, Map<MatrixType> >;
friend class MatrixBase<Scalar, Map>;
typedef MatrixBase<Scalar, Map> Base;
private:
enum {

View File

@ -111,13 +111,11 @@ class Matrix : public MatrixBase<_Scalar, Matrix<_Scalar, _Rows, _Cols,
typedef _Scalar Scalar;
typedef MatrixRef<Matrix> Ref;
friend class MatrixRef<Matrix>;
template<typename ExpressionType> friend class Eval;
private:
enum {
RowsAtCompileTime = _Rows,
ColsAtCompileTime = _Cols,
SizeAtCompileTime = _Rows == Dynamic || _Cols == Dynamic ? Dynamic : _Rows * _Cols,
StorageOrder = _StorageOrder,
MaxRowsAtCompileTime = _MaxRows,
MaxColsAtCompileTime = _MaxCols,
@ -167,14 +165,9 @@ class Matrix : public MatrixBase<_Scalar, Matrix<_Scalar, _Rows, _Cols,
&& cols > 0
&& (MaxColsAtCompileTime == Dynamic || MaxColsAtCompileTime >= cols)
&& (ColsAtCompileTime == Dynamic || ColsAtCompileTime == cols));
if(SizeAtCompileTime == Dynamic)
{
const int size = rows * cols;
if(size > m_rows.value() * m_cols.value())
m_array.resize(size);
m_rows.setValue(rows);
m_cols.setValue(cols);
}
m_rows.setValue(rows);
m_cols.setValue(cols);
m_array.resize(rows * cols);
}
/** Copies the value of the expression \a other into *this.

View File

@ -304,6 +304,34 @@ template<typename Scalar, typename Derived> class MatrixBase
Scalar& w();
const Eval<Derived> eval() const EIGEN_ALWAYS_INLINE;
/** puts in *row and *col the location of the coefficient of *this
* which has the biggest absolute value.
*/
void findBiggestCoeff(int *row, int *col) const
{
RealScalar biggest = 0;
for(int j = 0; j < cols(); j++)
for(int i = 0; i < rows(); i++)
{
RealScalar x = abs(coeff(i,j));
if(x > biggest)
{
biggest = x;
*row = i;
*col = j;
}
}
}
/** swaps *this with the expression \a other.
*
* \note \a other is only marked const because I couln't find another way
* to get g++ 4.2 to accept that template parameter resolution. It gets const_cast'd
* of course. TODO: get rid of const here.
*/
template<typename OtherDerived>
void swap(const MatrixBase<Scalar, OtherDerived>& other);
};
#endif // EIGEN_MATRIXBASE_H

View File

@ -32,6 +32,7 @@ template<typename MatrixType> class MatrixRef
public:
typedef typename MatrixType::Scalar Scalar;
friend class MatrixBase<Scalar, MatrixRef>;
typedef MatrixBase<Scalar, MatrixRef> Base;
MatrixRef(const MatrixType& matrix) : m_matrix(matrix) {}
~MatrixRef() {}

View File

@ -44,7 +44,8 @@ template<typename MatrixType> class Minor
public:
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Ref MatRef;
friend class MatrixBase<Scalar, Minor<MatrixType> >;
friend class MatrixBase<Scalar, Minor>;
typedef MatrixBase<Scalar, Minor> Base;
Minor(const MatRef& matrix,
int row, int col)

View File

@ -38,8 +38,9 @@ template<typename MatrixType> class Ones : NoOperatorEquals,
{
public:
typedef typename MatrixType::Scalar Scalar;
friend class MatrixBase<Scalar, Ones<MatrixType> >;
friend class MatrixBase<Scalar, Ones>;
typedef MatrixBase<Scalar, Ones> Base;
private:
enum {
RowsAtCompileTime = MatrixType::Traits::RowsAtCompileTime,

View File

@ -44,8 +44,9 @@ template<typename MatrixType> class Opposite : NoOperatorEquals,
public:
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Ref MatRef;
friend class MatrixBase<Scalar, Opposite<MatrixType> >;
friend class MatrixBase<Scalar, Opposite>;
typedef MatrixBase<Scalar, Opposite> Base;
Opposite(const MatRef& matrix) : m_matrix(matrix) {}
private:

View File

@ -1,4 +1,4 @@
// This file is part of Eigen, a lightweight C++ template library
// // This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob@math.jussieu.fr>
@ -81,7 +81,8 @@ template<typename Lhs, typename Rhs> class Product : NoOperatorEquals,
typedef typename Lhs::Ref LhsRef;
typedef typename Rhs::Ref RhsRef;
friend class MatrixBase<Scalar, Product>;
typedef MatrixBase<Scalar, Product> Base;
Product(const LhsRef& lhs, const RhsRef& rhs)
: m_lhs(lhs), m_rhs(rhs)
{

View File

@ -38,7 +38,8 @@ template<typename MatrixType> class Random : NoOperatorEquals,
{
public:
typedef typename MatrixType::Scalar Scalar;
friend class MatrixBase<Scalar, Random<MatrixType> >;
friend class MatrixBase<Scalar, Random>;
typedef MatrixBase<Scalar, Random> Base;
private:
enum {
@ -86,7 +87,8 @@ template<typename MatrixType> class Random : NoOperatorEquals,
* \sa random(), random(int)
*/
template<typename Scalar, typename Derived>
const Eval<Random<Derived> > MatrixBase<Scalar, Derived>::random(int rows, int cols)
const Eval<Random<Derived> >
MatrixBase<Scalar, Derived>::random(int rows, int cols)
{
return Random<Derived>(rows, cols).eval();
}
@ -108,7 +110,8 @@ const Eval<Random<Derived> > MatrixBase<Scalar, Derived>::random(int rows, int c
* \sa random(), random(int,int)
*/
template<typename Scalar, typename Derived>
const Eval<Random<Derived> > MatrixBase<Scalar, Derived>::random(int size)
const Eval<Random<Derived> >
MatrixBase<Scalar, Derived>::random(int size)
{
assert(Traits::IsVectorAtCompileTime);
if(Traits::RowsAtCompileTime == 1) return Random<Derived>(1, size).eval();
@ -127,7 +130,8 @@ const Eval<Random<Derived> > MatrixBase<Scalar, Derived>::random(int size)
* \sa random(int), random(int,int)
*/
template<typename Scalar, typename Derived>
const Eval<Random<Derived> > MatrixBase<Scalar, Derived>::random()
const Eval<Random<Derived> >
MatrixBase<Scalar, Derived>::random()
{
return Random<Derived>(Traits::RowsAtCompileTime, Traits::ColsAtCompileTime).eval();
}

View File

@ -52,7 +52,8 @@ template<typename MatrixType> class Row
public:
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Ref MatRef;
friend class MatrixBase<Scalar, Row<MatrixType> >;
friend class MatrixBase<Scalar, Row>;
typedef MatrixBase<Scalar, Row> Base;
Row(const MatRef& matrix, int row)
: m_matrix(matrix), m_row(row)

View File

@ -43,7 +43,8 @@ template<typename FactorType, typename MatrixType> class ScalarMultiple : NoOper
public:
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Ref MatRef;
friend class MatrixBase<Scalar, ScalarMultiple<FactorType, MatrixType> >;
friend class MatrixBase<Scalar, ScalarMultiple>;
typedef MatrixBase<Scalar, ScalarMultiple> Base;
ScalarMultiple(const MatRef& matrix, FactorType factor)
: m_matrix(matrix), m_factor(factor) {}

View File

@ -47,6 +47,7 @@ template<typename Lhs, typename Rhs> class Sum : NoOperatorEquals,
typedef typename Lhs::Ref LhsRef;
typedef typename Rhs::Ref RhsRef;
friend class MatrixBase<Scalar, Sum>;
typedef MatrixBase<Scalar, Sum> Base;
Sum(const LhsRef& lhs, const RhsRef& rhs)
: m_lhs(lhs), m_rhs(rhs)

64
Eigen/src/Core/Swap.h Normal file
View File

@ -0,0 +1,64 @@
// This file is part of Eigen, a lightweight C++ template library
// for linear algebra. Eigen itself is part of the KDE project.
//
// Copyright (C) 2006-2008 Benoit Jacob <jacob@math.jussieu.fr>
//
// Eigen is free software; you can redistribute it and/or modify it under the
// terms of the GNU General Public License as published by the Free Software
// Foundation; either version 2 or (at your option) any later version.
//
// Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
// WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
// FOR A PARTICULAR PURPOSE. See the GNU General Public License for more
// details.
//
// You should have received a copy of the GNU General Public License along
// with Eigen; if not, write to the Free Software Foundation, Inc., 51
// Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
//
// As a special exception, if other files instantiate templates or use macros
// or functions from this file, or you compile this file and link it
// with other works to produce a work based on this file, this file does not
// by itself cause the resulting work to be covered by the GNU General Public
// License. This exception does not invalidate any other reasons why a work
// based on this file might be covered by the GNU General Public License.
#ifndef EIGEN_SWAP_H
#define EIGEN_SWAP_H
template<typename Scalar, typename Derived>
template<typename OtherDerived>
void MatrixBase<Scalar, Derived>::swap(const MatrixBase<Scalar, OtherDerived>& other)
{
MatrixBase<Scalar, OtherDerived> *_other = const_cast<MatrixBase<Scalar, OtherDerived>*>(&other);
if(Traits::SizeAtCompileTime == Dynamic)
{
Scalar tmp;
if(Traits::IsVectorAtCompileTime)
{
assert(OtherDerived::Traits::IsVectorAtCompileTime && size() == _other->size());
for(int i = 0; i < size(); i++)
{
tmp = coeff(i);
coeffRef(i) = _other->coeff(i);
_other->coeffRef(i) = tmp;
}
}
else
for(int j = 0; j < cols(); j++)
for(int i = 0; i < rows(); i++)
{
tmp = coeff(i, j);
coeffRef(i, j) = _other->coeff(i, j);
_other->coeffRef(i, j) = tmp;
}
}
else // SizeAtCompileTime != Dynamic
{
typename Eval<Derived>::MatrixType buf(*this);
*this = other;
*_other = buf;
}
}
#endif // EIGEN_SWAP_H

View File

@ -44,7 +44,8 @@ template<typename MatrixType> class Transpose
public:
typedef typename MatrixType::Scalar Scalar;
typedef typename MatrixType::Ref MatRef;
friend class MatrixBase<Scalar, Transpose<MatrixType> >;
friend class MatrixBase<Scalar, Transpose>;
typedef MatrixBase<Scalar, Transpose> Base;
Transpose(const MatRef& matrix) : m_matrix(matrix) {}
@ -54,8 +55,8 @@ template<typename MatrixType> class Transpose
enum {
RowsAtCompileTime = MatrixType::Traits::ColsAtCompileTime,
ColsAtCompileTime = MatrixType::Traits::RowsAtCompileTime,
MaxRowsAtCompileTime = MatrixType::Traits::MaxRowsAtCompileTime,
MaxColsAtCompileTime = MatrixType::Traits::MaxColsAtCompileTime
MaxRowsAtCompileTime = MatrixType::Traits::MaxColsAtCompileTime,
MaxColsAtCompileTime = MatrixType::Traits::MaxRowsAtCompileTime
};
const Transpose& _ref() const { return *this; }

View File

@ -67,18 +67,18 @@ using Eigen::MatrixBase;
template<typename OtherScalar, typename OtherDerived> \
Derived& operator Op(const MatrixBase<OtherScalar, OtherDerived>& other) \
{ \
return MatrixBase<Scalar, Derived>::operator Op(other); \
return Base::operator Op(other); \
} \
Derived& operator Op(const Derived& other) \
{ \
return MatrixBase<Scalar, Derived>::operator Op(other); \
return Base::operator Op(other); \
}
#define EIGEN_INHERIT_SCALAR_ASSIGNMENT_OPERATOR(Derived, Op) \
template<typename Other> \
Derived& operator Op(const Other& scalar) \
{ \
return MatrixBase<Scalar, Derived>::operator Op(scalar); \
return Base::operator Op(scalar); \
}
#define EIGEN_INHERIT_ASSIGNMENT_OPERATORS(Derived) \

View File

@ -38,7 +38,8 @@ template<typename MatrixType> class Zero : NoOperatorEquals,
{
public:
typedef typename MatrixType::Scalar Scalar;
friend class MatrixBase<Scalar, Zero<MatrixType> >;
friend class MatrixBase<Scalar, Zero>;
typedef MatrixBase<Scalar, Zero> Base;
private:
enum {

View File

@ -5,7 +5,7 @@
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = Eigen
PROJECT_NUMBER = 2.0-alpha3
PROJECT_NUMBER = 2.0-alpha3.1
OUTPUT_DIRECTORY = ${CMAKE_BINARY_DIR}/doc
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English

View File

@ -73,7 +73,7 @@ If you want to stay informed of Eigen news and releases, please subscribe to our
<a name="download"></a>
<h2>Download</h2>
The source code of the latest release is here: <a href="http://download.tuxfamily.org/eigen/eigen-2.0-alpha3.tar.gz">eigen-2.0-alpha3.tar.gz</a><br/>
The source code of the latest release is here: <a href="http://download.tuxfamily.org/eigen/eigen-2.0-alpha3.1.tar.gz">eigen-2.0-alpha3.1.tar.gz</a><br/>
Alternatively, you can checkout the development tree by anonymous svn, by doing:
<pre>svn co svn://anonsvn.kde.org/home/kde/branches/work/eigen2</pre>

71
doc/echelon.cpp Normal file
View File

@ -0,0 +1,71 @@
#include <Eigen/Core>
USING_PART_OF_NAMESPACE_EIGEN
namespace Eigen {
template<typename Scalar, typename Derived>
void echelon(MatrixBase<Scalar, Derived>& m)
{
const int N = std::min(m.rows(), m.cols());
for(int k = 0; k < N; k++)
{
int rowOfBiggest, colOfBiggest;
int cornerRows = m.rows()-k;
int cornerCols = m.cols()-k;
m.corner(BottomRight, cornerRows, cornerCols)
.findBiggestCoeff(&rowOfBiggest, &colOfBiggest);
m.row(k).swap(m.row(k+rowOfBiggest));
m.col(k).swap(m.col(k+colOfBiggest));
for(int r = k+1; r < m.rows(); r++)
m.row(r).end(cornerCols) -= m.row(k).end(cornerCols) * m(r,k) / m(k,k);
}
}
template<typename Scalar, typename Derived>
void doSomeRankPreservingOperations(MatrixBase<Scalar, Derived>& m)
{
for(int a = 0; a < 3*(m.rows()+m.cols()); a++)
{
double d = Eigen::random<double>(-1,1);
int i = Eigen::random<int>(0,m.rows()-1); // i is a random row number
int j;
do {
j = Eigen::random<int>(0,m.rows()-1);
} while (i==j); // j is another one (must be different)
m.row(i) += d * m.row(j);
i = Eigen::random<int>(0,m.cols()-1); // i is a random column number
do {
j = Eigen::random<int>(0,m.cols()-1);
} while (i==j); // j is another one (must be different)
m.col(i) += d * m.col(j);
}
}
} // namespace Eigen
using namespace std;
int main(int, char **)
{
srand((unsigned int)time(0));
const int Rows = 6, Cols = 4;
typedef Matrix<double, Rows, Cols> Mat;
const int N = Rows < Cols ? Rows : Cols;
// start with a matrix m that's obviously of rank N-1
Mat m = Mat::identity(Rows, Cols); // args just in case of dyn. size
m.row(0) = m.row(1) = m.row(0) + m.row(1);
doSomeRankPreservingOperations(m);
// now m is still a matrix of rank N-1
cout << "Here's the matrix m:" << endl << m << endl;
cout << "Now let's echelon m:" << endl;
echelon(m);
cout << "Now m is:" << endl << m << endl;
}

View File

@ -0,0 +1,13 @@
typedef Matrix3i MyMatrixType;
MyMatrixType m = MyMatrixType::random(3, 3);
cout << "Here's the matrix m:" << endl << m << endl;
typedef Eigen::Eval<Eigen::Row<MyMatrixType> >::MatrixType MyRowType;
// now MyRowType is just the same typedef as RowVector3i
MyRowType r = m.row(0);
cout << "Here's r:" << endl << r << endl;
typedef Eigen::Eval<Eigen::Block<MyMatrixType> >::MatrixType MyBlockType;
MyBlockType c = m.corner(Eigen::TopRight, 2, 2);
// now MyBlockType is a a matrix type where the number of rows and columns
// are dynamic, but know at compile-time to be <= 2. Therefore no dynamic memory
// allocation occurs.
cout << "Here's c:" << endl << c << endl;