diff --git a/doc/tutorial.cpp b/doc/tutorial.cpp index 7c45bbde9..ab145bf3f 100644 --- a/doc/tutorial.cpp +++ b/doc/tutorial.cpp @@ -30,6 +30,5 @@ int main(int, char **) cout << "Column 1 of m2 is:" << endl << m2.col(1) << endl; cout << "The transpose of m2 is:" << endl << m2.transpose() << endl; cout << "The matrix m2 with row 0 and column 1 removed is:" << endl << m2.minor(0,1) << endl; - return 0; } diff --git a/src/Core.h b/src/Core.h index e22fb0996..6b6bc7b12 100644 --- a/src/Core.h +++ b/src/Core.h @@ -1,6 +1,7 @@ #include "Core/Util.h" #include "Core/Numeric.h" #include "Core/Object.h" +#include "Core/CopyHelper.h" #include "Core/MatrixRef.h" #include "Core/MatrixStorage.h" #include "Core/Matrix.h" @@ -10,3 +11,4 @@ #include "Core/Minor.h" #include "Core/Transpose.h" #include "Core/Conjugate.h" +#include "Core/Trace.h" diff --git a/src/Core/Conjugate.h b/src/Core/Conjugate.h index 5b55b7ea0..9ca055e92 100644 --- a/src/Core/Conjugate.h +++ b/src/Core/Conjugate.h @@ -31,7 +31,7 @@ template class EiConjugate { public: typedef typename MatrixType::Scalar Scalar; - typedef typename MatrixType::Ref MatRef; + typedef typename MatrixType::ConstRef MatRef; friend class EiObject >; static const int RowsAtCompileTime = MatrixType::RowsAtCompileTime, @@ -61,9 +61,9 @@ template class EiConjugate template EiConjugate -EiObject::conjugate() +EiObject::conjugate() const { - return EiConjugate(static_cast(this)->ref()); + return EiConjugate(static_cast(this)->constRef()); } #endif // EI_CONJUGATE_H diff --git a/src/Core/Loop.h b/src/Core/CopyHelper.h similarity index 66% rename from src/Core/Loop.h rename to src/Core/CopyHelper.h index 27f53a31b..04ce37ec6 100644 --- a/src/Core/Loop.h +++ b/src/Core/CopyHelper.h @@ -2,6 +2,7 @@ // for linear algebra. Eigen itself is part of the KDE project. // // Copyright (C) 2007 Michael Olbrich +// Copyright (C) 2006-2007 Benoit Jacob // // 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 @@ -23,32 +24,44 @@ // 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 EI_LOOP_H -#define EI_LOOP_H +#ifndef EI_COPYHELPER_H +#define EI_COPYHELPER_H -template class EiLoop +template class EiCopyHelperUnroller { static const int col = (UnrollCount-1) / Rows; static const int row = (UnrollCount-1) % Rows; public: template - static void copy(Derived1 &dst, const Derived2 &src) + static void run(Derived1 &dst, const Derived2 &src) { - EiLoop::copy(dst, src); + EiCopyHelperUnroller::run(dst, src); dst.write(row, col) = src.read(row, col); } }; -template class EiLoop<0, Rows> +template class EiCopyHelperUnroller<0, Rows> { public: template - static void copy(Derived1 &dst, const Derived2 &src) + static void run(Derived1 &dst, const Derived2 &src) { EI_UNUSED(dst); EI_UNUSED(src); } }; -#endif // EI_LOOP_H +template +template +void EiObject::_copy_helper(const EiObject& other) +{ + if(UnrollCount > 0 && UnrollCount <= EI_LOOP_UNROLLING_LIMIT) + EiCopyHelperUnroller::run(*this, other); + else + for(int i = 0; i < rows(); i++) + for(int j = 0; j < cols(); j++) + write(i, j) = other.read(i, j); +} + +#endif // EI_COPYHELPER_H diff --git a/src/Core/Object.h b/src/Core/Object.h index 387350da8..610505707 100644 --- a/src/Core/Object.h +++ b/src/Core/Object.h @@ -36,15 +36,7 @@ template class EiObject RowsAtCompileTime * ColsAtCompileTime : 0; template - void _copy_helper(const EiObject& other) - { - if(UnrollCount > 0 && UnrollCount <= EI_LOOP_UNROLLING_LIMIT) - EiLoop::copy(*this, other); - else - for(int i = 0; i < rows(); i++) - for(int j = 0; j < cols(); j++) - write(i, j) = other.read(i, j); - } + void _copy_helper(const EiObject& other); public: typedef typename EiForwardDecl::Ref Ref; @@ -92,8 +84,9 @@ template class EiObject EiMinor minor(int row, int col); EiBlock block(int startRow, int endRow, int startCol, int endCol); EiTranspose transpose(); - EiConjugate conjugate(); - EiTranspose > adjoint() { return conjugate().transpose(); } + EiConjugate conjugate() const; + EiTranspose > adjoint() const { return conjugate().transpose(); } + Scalar trace() const; template EiMatrixProduct diff --git a/src/Core/Trace.h b/src/Core/Trace.h new file mode 100644 index 000000000..c61944afd --- /dev/null +++ b/src/Core/Trace.h @@ -0,0 +1,72 @@ +// This file is part of Eigen, a lightweight C++ template library +// for linear algebra. Eigen itself is part of the KDE project. +// +// Copyright (C) 2007 Michael Olbrich +// Copyright (C) 2006-2007 Benoit Jacob +// +// 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 EI_TRACE_H +#define EI_TRACE_H + +template struct EiTraceUnroller +{ + typedef typename Derived::Scalar Scalar; + + static void run(const Derived &mat, Scalar &trace) + { + if(CurrentRow == Rows - 1) + trace = mat(CurrentRow, CurrentRow); + else + trace += mat(CurrentRow, CurrentRow); + EiTraceUnroller::run(mat, trace); + } +}; + +template struct EiTraceUnroller<-1, Rows, Derived> +{ + typedef typename Derived::Scalar Scalar; + + static void run(const Derived &mat, Scalar &trace) + { + EI_UNUSED(mat); + EI_UNUSED(trace); + } +}; + +template +Scalar EiObject::trace() const +{ + assert(rows() == cols()); + Scalar res; + if(RowsAtCompileTime != EiDynamic && RowsAtCompileTime <= 16) + EiTraceUnroller + ::run(*static_cast(this), res); + else + { + res = read(0, 0); + for(int i = 1; i < rows(); i++) + res += read(i, i); + } + return res; +} + +#endif // EI_TRACE_H