From 95b3316701c6bafcca9c6add81e445b3b8fc72d3 Mon Sep 17 00:00:00 2001 From: Benoit Jacob Date: Sun, 7 Oct 2007 16:40:49 +0000 Subject: reorganize meta loop unrolling, add Trace (meta-unrolled), fix compilation issues in the conjugation/adjunction stuff --- doc/tutorial.cpp | 1 - src/Core.h | 2 ++ src/Core/Conjugate.h | 6 ++--- src/Core/CopyHelper.h | 67 +++++++++++++++++++++++++++++++++++++++++++++++ src/Core/Loop.h | 54 -------------------------------------- src/Core/Object.h | 15 +++-------- src/Core/Trace.h | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++ 7 files changed, 148 insertions(+), 69 deletions(-) create mode 100644 src/Core/CopyHelper.h delete mode 100644 src/Core/Loop.h create mode 100644 src/Core/Trace.h 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/CopyHelper.h b/src/Core/CopyHelper.h new file mode 100644 index 000000000..04ce37ec6 --- /dev/null +++ b/src/Core/CopyHelper.h @@ -0,0 +1,67 @@ +// 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_COPYHELPER_H +#define EI_COPYHELPER_H + +template class EiCopyHelperUnroller +{ + static const int col = (UnrollCount-1) / Rows; + static const int row = (UnrollCount-1) % Rows; + + public: + template + static void run(Derived1 &dst, const Derived2 &src) + { + EiCopyHelperUnroller::run(dst, src); + dst.write(row, col) = src.read(row, col); + } +}; + +template class EiCopyHelperUnroller<0, Rows> +{ + public: + template + static void run(Derived1 &dst, const Derived2 &src) + { + EI_UNUSED(dst); + EI_UNUSED(src); + } +}; + +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/Loop.h b/src/Core/Loop.h deleted file mode 100644 index 27f53a31b..000000000 --- a/src/Core/Loop.h +++ /dev/null @@ -1,54 +0,0 @@ -// 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 -// -// 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_LOOP_H -#define EI_LOOP_H - -template class EiLoop -{ - static const int col = (UnrollCount-1) / Rows; - static const int row = (UnrollCount-1) % Rows; - - public: - template - static void copy(Derived1 &dst, const Derived2 &src) - { - EiLoop::copy(dst, src); - dst.write(row, col) = src.read(row, col); - } -}; - -template class EiLoop<0, Rows> -{ - public: - template - static void copy(Derived1 &dst, const Derived2 &src) - { - EI_UNUSED(dst); - EI_UNUSED(src); - } -}; - -#endif // EI_LOOP_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 -- cgit v1.2.3