28 #ifndef EIGEN_PLUGIN_H
29 #define EIGEN_PLUGIN_H
59 EIGEN_STRONG_INLINE
void fill(
const Scalar v) { derived().setConstant(v); }
62 EIGEN_STRONG_INLINE
void assign(
const Scalar v) { derived().setConstant(v); }
64 EIGEN_STRONG_INLINE
void assign(
size_t N,
const Scalar v) { derived().resize(N); derived().setConstant(v); }
67 EIGEN_STRONG_INLINE
size_t getRowCount()
const {
return rows(); }
69 EIGEN_STRONG_INLINE
size_t getColCount()
const {
return cols(); }
72 EIGEN_STRONG_INLINE
void unit(
const size_t nRows,
const Scalar diag_vals) {
74 derived().setIdentity(nRows,nRows);
76 derived().setZero(nRows,nRows);
77 derived().diagonal().setConstant(diag_vals);
82 EIGEN_STRONG_INLINE
void unit() { derived().setIdentity(); }
84 EIGEN_STRONG_INLINE
void eye() { derived().setIdentity(); }
87 EIGEN_STRONG_INLINE
void zeros() { derived().setZero(); }
89 EIGEN_STRONG_INLINE
void zeros(
const size_t row,
const size_t col) { derived().setZero(row,col); }
92 EIGEN_STRONG_INLINE
void ones(
const size_t row,
const size_t col) { derived().setOnes(row,col); }
94 EIGEN_STRONG_INLINE
void ones() { derived().setOnes(); }
99 EIGEN_STRONG_INLINE Scalar *
get_unsafe_row(
size_t row) {
return &derived().coeffRef(row,0); }
100 EIGEN_STRONG_INLINE
const Scalar*
get_unsafe_row(
size_t row)
const {
return &derived().coeff(row,0); }
103 EIGEN_STRONG_INLINE Scalar
get_unsafe(
const size_t row,
const size_t col)
const {
105 return derived()(row,col);
107 return derived().coeff(row,col);
111 EIGEN_STRONG_INLINE Scalar&
get_unsafe(
const size_t row,
const size_t col) {
113 return derived()(row,col);
115 return derived().coeffRef(row,col);
118 EIGEN_STRONG_INLINE
void set_unsafe(
const size_t row,
const size_t col,
const Scalar val) {
120 derived()(row,col) = val;
122 derived().coeffRef(row,col) = val;
128 const Index N =
size();
129 derived().conservativeResize(N+1);
133 EIGEN_STRONG_INLINE
bool isSquare()
const {
return cols()==rows(); }
134 EIGEN_STRONG_INLINE
bool isSingular(
const Scalar absThreshold = 0)
const {
return std::abs(derived().determinant())<absThreshold; }
154 std::string
inMatlabFormat(
const size_t decimal_digits = 6)
const;
166 const std::string &file,
168 bool appendMRPTHeader =
false,
169 const std::string &userHeader = std::string()
187 EIGEN_STRONG_INLINE
void swapCols(
size_t i1,
size_t i2) { derived().col(i1).swap( derived().col(i2) ); }
188 EIGEN_STRONG_INLINE
void swapRows(
size_t i1,
size_t i2) { derived().row(i1).swap( derived().row(i2) ); }
190 EIGEN_STRONG_INLINE
size_t countNonZero()
const {
return ((*static_cast<const Derived*>(
this))!= 0).count(); }
197 if (
size()==0)
throw std::runtime_error(
"maximum: container is empty");
198 return derived().maxCoeff();
206 if (
size()==0)
throw std::runtime_error(
"minimum: container is empty");
207 return derived().minCoeff();
215 Scalar & out_max)
const
225 EIGEN_STRONG_INLINE Scalar
maximum(
size_t *maxIndex)
const
227 if (
size()==0)
throw std::runtime_error(
"maximum: container is empty");
229 const Scalar m = derived().maxCoeff(&idx);
230 if (maxIndex) *maxIndex = idx;
239 if (cols()==0 || rows()==0)
throw std::runtime_error(
"find_index_max_value: container is empty");
241 valMax = derived().maxCoeff(&idx1,&idx2);
249 EIGEN_STRONG_INLINE Scalar
minimum(
size_t *minIndex)
const
251 if (
size()==0)
throw std::runtime_error(
"minimum: container is empty");
253 const Scalar m =derived().minCoeff(&idx);
254 if (minIndex) *minIndex = idx;
265 size_t *maxIndex)
const
272 EIGEN_STRONG_INLINE Scalar
norm_inf()
const {
return lpNorm<Eigen::Infinity>(); }
275 EIGEN_STRONG_INLINE Scalar
squareNorm()
const {
return squaredNorm(); }
278 EIGEN_STRONG_INLINE Scalar
sumAll()
const {
return derived().sum(); }
283 template<
typename OtherDerived>
284 EIGEN_STRONG_INLINE
void laplacian(Eigen::MatrixBase <OtherDerived>& ret)
const
286 if (rows()!=cols())
throw std::runtime_error(
"laplacian: Defined for square matrixes only");
287 const Index N = rows();
289 for (Index i=0;i<N;i++)
292 for (Index j=0;j<N;j++) deg+= derived().coeff(j,i);
293 ret.coeffRef(i,i)+=deg;
301 EIGEN_STRONG_INLINE
void setSize(
size_t row,
size_t col)
304 if ((Derived::RowsAtCompileTime!=Eigen::Dynamic && Derived::RowsAtCompileTime!=
int(row)) || (Derived::ColsAtCompileTime!=Eigen::Dynamic && Derived::ColsAtCompileTime!=
int(col))) {
305 std::stringstream ss; ss <<
"setSize: Trying to change a fixed sized matrix from " << rows() <<
"x" << cols() <<
" to " << row <<
"x" << col;
306 throw std::runtime_error(ss.str());
309 const Index oldCols = cols();
310 const Index oldRows = rows();
311 const int nNewCols = int(col) - int(cols());
312 const int nNewRows = int(row) - int(rows());
314 if (nNewCols>0) derived().block(0,oldCols,row,nNewCols).setZero();
315 if (nNewRows>0) derived().block(oldRows,0,nNewRows,col).setZero();
319 template <
class OUTVECT>
322 Scalar resolution = Scalar(0.01),
323 size_t maxIterations = 6,
324 int *out_Iterations = NULL,
325 float *out_estimatedResolution = NULL )
const
329 const Index n = rows();
335 Eigen::Matrix<Scalar,Derived::RowsAtCompileTime,1> xx = (*this) * x;
336 xx *= Scalar(1.0/xx.norm());
337 dif = (x-xx).array().abs().sum();
340 }
while (iter<maxIterations && dif>resolution);
341 if (out_Iterations) *out_Iterations=
static_cast<int>(iter);
342 if (out_estimatedResolution) *out_estimatedResolution=dif;
349 derived().setIdentity();
351 for (
unsigned int i=1;i<pow;i++)
352 derived() *= derived();
357 EIGEN_STRONG_INLINE
void scalarPow(
const Scalar s) { (*this)=array().pow(s); }
362 for (Index c=0;c<cols();c++)
363 for (Index r=0;r<rows();r++)
364 if (r!=c && coeff(r,c)!=0)
374 EIGEN_STRONG_INLINE
double mean()
const
376 if (
size()==0)
throw std::runtime_error(
"mean: Empty container.");
377 return derived().sum()/
static_cast<double>(
size());
388 const bool unbiased_variance =
true )
const
390 const double N = rows();
391 if (N==0)
throw std::runtime_error(
"meanAndStd: Empty container.");
392 const double N_inv = 1.0/N;
393 const double N_ = unbiased_variance ? (N>1 ? 1.0/(N-1) : 1.0) : 1.0/N;
394 outMeanVector.resize(cols());
395 outStdVector.resize(cols());
396 for (Index i=0;i<cols();i++)
398 outMeanVector[i]= this->col(i).array().sum() * N_inv;
399 outStdVector[i] = std::sqrt( (this->col(i).array()-outMeanVector[i]).
square().
sum() * N_ );
410 const bool unbiased_variance =
true )
const
412 const double N =
size();
413 if (N==0)
throw std::runtime_error(
"meanAndStdAll: Empty container.");
414 const double N_ = unbiased_variance ? (N>1 ? 1.0/(N-1) : 1.0) : 1.0/N;
415 outMean = derived().array().sum()/
static_cast<double>(
size());
416 outStd = std::sqrt( (this->array() - outMean).
square().
sum()*N_);
420 template <
typename MAT>
421 EIGEN_STRONG_INLINE
void insertMatrix(
size_t r,
size_t c,
const MAT &m) { derived().block(r,c,m.rows(),m.cols())=m; }
423 template <
typename MAT>
424 EIGEN_STRONG_INLINE
void insertMatrixTranspose(
size_t r,
size_t c,
const MAT &m) { derived().block(r,c,m.cols(),m.rows())=m.adjoint(); }
426 template <
typename MAT> EIGEN_STRONG_INLINE
void insertRow(
size_t nRow,
const MAT & aRow) { this->row(nRow) = aRow; }
427 template <
typename MAT> EIGEN_STRONG_INLINE
void insertCol(
size_t nCol,
const MAT & aCol) { this->col(nCol) = aCol; }
429 template <
typename R>
void insertRow(
size_t nRow,
const std::vector<R> & aRow)
431 if (static_cast<Index>(aRow.size())!=cols())
throw std::runtime_error(
"insertRow: Row size doesn't fit the size of this matrix.");
432 for (Index j=0;j<cols();j++)
433 coeffRef(nRow,j) = aRow[j];
435 template <
typename R>
void insertCol(
size_t nCol,
const std::vector<R> & aCol)
437 if (static_cast<Index>(aCol.size())!=rows())
throw std::runtime_error(
"insertRow: Row size doesn't fit the size of this matrix.");
438 for (Index j=0;j<rows();j++)
439 coeffRef(j,nCol) = aCol[j];
443 EIGEN_STRONG_INLINE
void removeColumns(
const std::vector<size_t> &idxsToRemove)
445 std::vector<size_t> idxs = idxsToRemove;
446 std::sort( idxs.begin(), idxs.end() );
448 idxs.resize( itEnd - idxs.begin() );
457 for (std::vector<size_t>::const_reverse_iterator it = idxs.rbegin(); it != idxs.rend(); it++, k++)
459 const size_t nC = cols() - *it - k;
461 derived().block(0,*it,rows(),nC) = derived().block(0,*it+1,rows(),nC).eval();
463 derived().conservativeResize(NoChange,cols()-idxs.size());
467 EIGEN_STRONG_INLINE
void removeRows(
const std::vector<size_t> &idxsToRemove)
469 std::vector<size_t> idxs = idxsToRemove;
470 std::sort( idxs.begin(), idxs.end() );
472 idxs.resize( itEnd - idxs.begin() );
481 for (std::vector<size_t>::reverse_iterator it = idxs.rbegin(); it != idxs.rend(); it++, k++)
483 const size_t nR = rows() - *it - k;
485 derived().block(*it,0,nR,cols()) = derived().block(*it+1,0,nR,cols()).eval();
487 derived().conservativeResize(rows()-idxs.size(),NoChange);
491 EIGEN_STRONG_INLINE
const AdjointReturnType
t()
const {
return derived().adjoint(); }
493 EIGEN_STRONG_INLINE PlainObject
inv()
const { PlainObject outMat = derived().inverse().eval();
return outMat; }
494 template <
class MATRIX> EIGEN_STRONG_INLINE
void inv(MATRIX &outMat)
const { outMat = derived().inverse().eval(); }
495 template <
class MATRIX> EIGEN_STRONG_INLINE
void inv_fast(MATRIX &outMat)
const { outMat = derived().inverse().eval(); }
496 EIGEN_STRONG_INLINE Scalar
det()
const {
return derived().determinant(); }
507 template<
typename OTHERMATRIX> EIGEN_STRONG_INLINE
void add_Ac(
const OTHERMATRIX &m,
const Scalar c) { (*this)+=c*m; }
509 template<
typename OTHERMATRIX> EIGEN_STRONG_INLINE
void substract_Ac(
const OTHERMATRIX &m,
const Scalar c) { (*this) -= c*m; }
512 template<
typename OTHERMATRIX> EIGEN_STRONG_INLINE
void substract_At(
const OTHERMATRIX &m) { (*this) -= m.adjoint(); }
515 template<
typename OTHERMATRIX> EIGEN_STRONG_INLINE
void substract_An(
const OTHERMATRIX& m,
const size_t n) { this->noalias() -= n * m; }
518 template<
typename OTHERMATRIX> EIGEN_STRONG_INLINE
void add_AAt(
const OTHERMATRIX &A) { this->noalias() += A; this->noalias() += A.adjoint(); }
521 template<typename OTHERMATRIX> EIGEN_STRONG_INLINE
void substract_AAt(
const OTHERMATRIX &A) { this->noalias() -= A; this->noalias() -= A.adjoint(); }
524 template <
class MATRIX1,
class MATRIX2> EIGEN_STRONG_INLINE
void multiply(
const MATRIX1& A,
const MATRIX2 &B ) { (*this)= A*B; }
526 template <
class MATRIX1,
class MATRIX2>
527 EIGEN_STRONG_INLINE
void multiply_AB(
const MATRIX1& A,
const MATRIX2 &B ) {
531 template <
typename MATRIX1,
typename MATRIX2>
532 EIGEN_STRONG_INLINE
void multiply_AtB(
const MATRIX1 &A,
const MATRIX2 &B) {
533 *
this = A.adjoint() * B;
537 template<
typename OTHERVECTOR1,
typename OTHERVECTOR2>
538 EIGEN_STRONG_INLINE
void multiply_Ab(
const OTHERVECTOR1 &vIn,OTHERVECTOR2 &vOut,
bool accumToOutput =
false)
const {
539 if (accumToOutput) vOut.noalias() += (*this) * vIn;
540 else vOut = (*this) * vIn;
544 template<typename OTHERVECTOR1,typename OTHERVECTOR2>
545 EIGEN_STRONG_INLINE
void multiply_Atb(
const OTHERVECTOR1 &vIn,OTHERVECTOR2 &vOut,
bool accumToOutput =
false)
const {
546 if (accumToOutput) vOut.noalias() += this->adjoint() * vIn;
547 else vOut = this->adjoint() * vIn;
550 template <
typename MAT_C,
typename MAT_R>
551 EIGEN_STRONG_INLINE
void multiply_HCHt(
const MAT_C &C,MAT_R &R,
bool accumResultInOutput=
false) const {
552 if (accumResultInOutput)
553 R.noalias() += (*this) * C * this->adjoint();
554 else R.noalias() = (*this) * C * this->adjoint();
557 template <
typename MAT_C,
typename MAT_R>
558 EIGEN_STRONG_INLINE
void multiply_HtCH(
const MAT_C &C,MAT_R &R,
bool accumResultInOutput=
false) const {
559 if (accumResultInOutput)
560 R.noalias() += this->adjoint() * C * (*this);
561 else R.noalias() = this->adjoint() * C * (*this);
565 template <
typename MAT_C>
567 return ( (*
this) * C * this->adjoint() ).eval()(0,0);
571 template <
typename MAT_C>
573 return ( this->adjoint() * C * (*
this) ).eval()(0,0);
577 template<
typename MAT_A>
579 *
this = (A * A.adjoint()) * f;
584 *
this = (A.adjoint() * A) * f;
588 template <
class MAT_A,
class SKEW_3VECTOR>
void multiply_A_skew3(
const MAT_A &A,
const SKEW_3VECTOR &v) {
592 template <
class SKEW_3VECTOR,
class MAT_A>
void multiply_skew3_A(
const SKEW_3VECTOR &v,
const MAT_A &A) {
597 template <
class MAT_A,
class MAT_OUT>
598 EIGEN_STRONG_INLINE
void multiply_subMatrix(
const MAT_A &A,MAT_OUT &outResult,
const size_t A_cols_offset,
const size_t A_rows_offset,
const size_t A_col_count)
const {
599 outResult = derived() * A.block(A_rows_offset,A_cols_offset,derived().cols(),A_col_count);
602 template <
class MAT_A,
class MAT_B,
class MAT_C>
607 template <
class MAT_A,
class MAT_B,
class MAT_C>
609 *
this = A*B*C.adjoint();
612 template <
class MAT_A,
class MAT_B,
class MAT_C>
614 *
this = A.adjoint()*B*C;
617 template <
class MAT_A,
class MAT_B>
619 *
this = A*B.adjoint();
622 template <
class MAT_A>
624 *
this = A*A.adjoint();
627 template <
class MAT_A>
629 *
this = A.adjoint()*A;
632 template <
class MAT_A,
class MAT_B>
639 template<
class MAT2,
class MAT3 >
642 Eigen::ColPivHouseholderQR<PlainObject> QR = A.colPivHouseholderQr();
643 if (!QR.isInvertible())
throw std::runtime_error(
"leftDivideSquare: Matrix A is not invertible");
644 RES = QR.inverse() * (*this);
648 template<
class MAT2,
class MAT3 >
651 Eigen::ColPivHouseholderQR<PlainObject> QR = B.colPivHouseholderQr();
652 if (!QR.isInvertible())
throw std::runtime_error(
"rightDivideSquare: Matrix B is not invertible");
653 RES = (*this) * QR.inverse();
666 template <
class MATRIX1,
class MATRIX2>
667 EIGEN_STRONG_INLINE
void eigenVectors( MATRIX1 & eVecs, MATRIX2 & eVals )
const;
674 template <
class MATRIX1,
class VECTOR1>
675 EIGEN_STRONG_INLINE
void eigenVectorsVec( MATRIX1 & eVecs, VECTOR1 & eVals )
const;
682 template <
class VECTOR>
686 eVecs.resizeLike(*
this);
692 template <
class MATRIX1,
class MATRIX2>
698 template <
class MATRIX1,
class VECTOR1>
711 template <
class MATRIX> EIGEN_STRONG_INLINE
bool chol(MATRIX &U)
const
713 Eigen::LLT<PlainObject> Chol = derived().selfadjointView<Eigen::Lower>().llt();
714 if (Chol.info()==Eigen::NoConvergence)
716 U = PlainObject(Chol.matrixU());
723 EIGEN_STRONG_INLINE
size_t rank(
double threshold=0)
const
725 Eigen::ColPivHouseholderQR<PlainObject> QR = this->colPivHouseholderQr();
726 if (threshold>0) QR.setThreshold(threshold);
737 EIGEN_STRONG_INLINE MatrixBase<Derived>&
Sqrt() { (*this) = this->array().sqrt();
return *
this; }
738 EIGEN_STRONG_INLINE PlainObject
Sqrt()
const { PlainObject res = this->array().sqrt();
return res; }
740 EIGEN_STRONG_INLINE MatrixBase<Derived>&
Abs() { (*this) = this->array().abs();
return *
this; }
741 EIGEN_STRONG_INLINE PlainObject
Abs()
const { PlainObject res = this->array().abs();
return res; }
743 EIGEN_STRONG_INLINE MatrixBase<Derived>&
Log() { (*this) = this->array().log();
return *
this; }
744 EIGEN_STRONG_INLINE PlainObject
Log()
const { PlainObject res = this->array().log();
return res; }
746 EIGEN_STRONG_INLINE MatrixBase<Derived>&
Exp() { (*this) = this->array().exp();
return *
this; }
747 EIGEN_STRONG_INLINE PlainObject
Exp()
const { PlainObject res = this->array().exp();
return res; }
749 EIGEN_STRONG_INLINE MatrixBase<Derived>&
Square() { (*this) = this->array().square();
return *
this; }
750 EIGEN_STRONG_INLINE PlainObject
Square()
const { PlainObject res = this->array().square();
return res; }
755 if (
size()==0)
return;
756 Scalar curMin,curMax;
758 Scalar minMaxDelta = curMax - curMin;
759 if (minMaxDelta==0) minMaxDelta = 1;
760 const Scalar minMaxDelta_ = (valMax-valMin)/minMaxDelta;
761 this->array() = (this->array()-curMin)*minMaxDelta_+valMin;
770 template <
class OtherDerived> EIGEN_STRONG_INLINE
void extractRow(
size_t nRow, Eigen::EigenBase<OtherDerived> &v,
size_t startingCol = 0)
const {
771 v = derived().block(nRow,startingCol,1,cols()-startingCol);
774 template <
typename T>
inline void extractRow(
size_t nRow, std::vector<T> &v,
size_t startingCol = 0)
const {
775 const size_t N = cols()-startingCol;
777 for (
size_t i=0;i<N;i++) v[i]=(*
this)(nRow,startingCol+i);
780 template <
class VECTOR> EIGEN_STRONG_INLINE
void extractRowAsCol(
size_t nRow, VECTOR &v,
size_t startingCol = 0)
const
782 v = derived().adjoint().block(startingCol,nRow,cols()-startingCol,1);
787 template <
class VECTOR> EIGEN_STRONG_INLINE
void extractCol(
size_t nCol, VECTOR &v,
size_t startingRow = 0)
const {
788 v = derived().block(startingRow,nCol,rows()-startingRow,1);
791 template <
typename T>
inline void extractCol(
size_t nCol, std::vector<T> &v,
size_t startingRow = 0)
const {
792 const size_t N = rows()-startingRow;
794 for (
size_t i=0;i<N;i++) v[i]=(*
this)(startingRow+i,nCol);
797 template <
class MATRIX> EIGEN_STRONG_INLINE
void extractMatrix(
const size_t firstRow,
const size_t firstCol, MATRIX &m)
const
799 m = derived().block(firstRow,firstCol,m.rows(),m.cols());
801 template <
class MATRIX> EIGEN_STRONG_INLINE
void extractMatrix(
const size_t firstRow,
const size_t firstCol,
const size_t nRows,
const size_t nCols, MATRIX &m)
const
803 m.resize(nRows,nCols);
804 m = derived().block(firstRow,firstCol,nRows,nCols);
808 template <
class MATRIX>
809 EIGEN_STRONG_INLINE
void extractSubmatrix(
const size_t row_first,
const size_t row_last,
const size_t col_first,
const size_t col_last,MATRIX &out)
const
811 out.resize(row_last-row_first+1,col_last-col_first+1);
812 out = derived().block(row_first,col_first,row_last-row_first+1,col_last-col_first+1);
819 template <
class MATRIX>
821 const size_t block_size,
822 const std::vector<size_t> &block_indices,
825 if (block_size<1)
throw std::runtime_error(
"extractSubmatrixSymmetricalBlocks: block_size must be >=1");
826 if (cols()!=rows())
throw std::runtime_error(
"extractSubmatrixSymmetricalBlocks: Matrix is not square.");
828 const size_t N = block_indices.size();
829 const size_t nrows_out=N*block_size;
830 out.resize(nrows_out,nrows_out);
832 for (
size_t dst_row_blk=0;dst_row_blk<N; ++dst_row_blk )
834 for (
size_t dst_col_blk=0;dst_col_blk<N; ++dst_col_blk )
837 if (block_indices[dst_col_blk]*block_size + block_size-1>=
size_t(cols()))
throw std::runtime_error(
"extractSubmatrixSymmetricalBlocks: Indices out of range!");
839 out.block(dst_row_blk * block_size,dst_col_blk * block_size, block_size,block_size)
841 derived().block(block_indices[dst_row_blk] * block_size, block_indices[dst_col_blk] * block_size, block_size,block_size);
851 template <
class MATRIX>
853 const std::vector<size_t> &indices,
856 if (cols()!=rows())
throw std::runtime_error(
"extractSubmatrixSymmetrical: Matrix is not square.");
858 const size_t N = indices.size();
859 const size_t nrows_out=N;
860 out.resize(nrows_out,nrows_out);
862 for (
size_t dst_row_blk=0;dst_row_blk<N; ++dst_row_blk )
863 for (
size_t dst_col_blk=0;dst_col_blk<N; ++dst_col_blk )
864 out.coeffRef(dst_row_blk,dst_col_blk) = this->coeff(indices[dst_row_blk],indices[dst_col_blk]);