diff --git a/src/Manip b/src/Manip index 4b13187bf..440fabcad 100644 --- a/src/Manip +++ b/src/Manip @@ -31,5 +31,6 @@ #include "internal/Block.h" #include "internal/Minor.h" #include "internal/Transpose.h" +#include "internal/Conjugate.h" #endif // EI_MANIP_H diff --git a/src/internal/Conjugate.h b/src/internal/Conjugate.h new file mode 100644 index 000000000..5b55b7ea0 --- /dev/null +++ b/src/internal/Conjugate.h @@ -0,0 +1,69 @@ +// 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-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_CONJUGATE_H +#define EI_CONJUGATE_H + +template class EiConjugate + : public EiObject > +{ + public: + typedef typename MatrixType::Scalar Scalar; + typedef typename MatrixType::Ref MatRef; + friend class EiObject >; + + static const int RowsAtCompileTime = MatrixType::RowsAtCompileTime, + ColsAtCompileTime = MatrixType::ColsAtCompileTime; + + EiConjugate(const MatRef& matrix) : m_matrix(matrix) {} + + EiConjugate(const EiConjugate& other) + : m_matrix(other.m_matrix) {} + + EI_INHERIT_ASSIGNMENT_OPERATORS(EiConjugate) + + private: + EiConjugate& _ref() { return *this; } + const EiConjugate& _constRef() const { return *this; } + int _rows() const { return m_matrix.rows(); } + int _cols() const { return m_matrix.cols(); } + + Scalar _read(int row, int col) const + { + return EiConj(m_matrix.read(row, col)); + } + + protected: + MatRef m_matrix; +}; + +template +EiConjugate +EiObject::conjugate() +{ + return EiConjugate(static_cast(this)->ref()); +} + +#endif // EI_CONJUGATE_H diff --git a/src/internal/Matrix.h b/src/internal/Matrix.h index d20fd9214..b4df04b11 100644 --- a/src/internal/Matrix.h +++ b/src/internal/Matrix.h @@ -127,4 +127,5 @@ EI_MAKE_TYPEDEFS_ALL_SIZES(std::complex, cd) #include "MatrixOps.h" #include "ScalarOps.h" + #endif // EI_MATRIX_H diff --git a/src/internal/Numeric.h b/src/internal/Numeric.h index 126993609..48a36f236 100644 --- a/src/internal/Numeric.h +++ b/src/internal/Numeric.h @@ -24,8 +24,8 @@ // 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_TRAITS_H -#define EI_TRAITS_H +#ifndef EI_NUMERIC_H +#define EI_NUMERIC_H template struct EiTraits; @@ -35,10 +35,10 @@ template<> struct EiTraits typedef double FloatingPoint; typedef double RealFloatingPoint; - static const int Epsilon = 0; static const bool IsComplex = false; static const bool HasFloatingPoint = false; + static int epsilon() { return 0; } static int real(const int& x) { return x; } static int imag(const int& x) { EI_UNUSED(x); return 0; } static int conj(const int& x) { return x; } @@ -50,7 +50,7 @@ template<> struct EiTraits // "rand()%21" would be bad. always use the high-order bits, not the low-order bits. // note: here (gcc 4.1) static_cast seems to round the nearest int. // I don't know if that's part of the standard. - return -10 + static_cast(20.0 * (rand() / (RAND_MAX + 1.0))); + return -10 + static_cast(rand() / ((RAND_MAX + 1.0)/20.0)); } }; @@ -60,10 +60,10 @@ template<> struct EiTraits typedef float FloatingPoint; typedef float RealFloatingPoint; - static const float Epsilon; static const bool IsComplex = false; static const bool HasFloatingPoint = true; + static float epsilon() { return 1e-5f; } static float real(const float& x) { return x; } static float imag(const float& x) { EI_UNUSED(x); return 0; } static float conj(const float& x) { return x; } @@ -72,22 +72,20 @@ template<> struct EiTraits static float abs2(const float& x) { return x*x; } static float random() { - return 20.0f * rand() / RAND_MAX - 10.0f; + return rand() / (RAND_MAX/20.0f) - 10.0f; } }; -const float EiTraits::Epsilon = 1e-5f; - template<> struct EiTraits { typedef double Real; typedef double FloatingPoint; typedef double RealFloatingPoint; - static const double Epsilon; static const bool IsComplex = false; static const bool HasFloatingPoint = true; + static double epsilon() { return 1e-11; } static double real(const double& x) { return x; } static double imag(const double& x) { EI_UNUSED(x); return 0; } static double conj(const double& x) { return x; } @@ -96,12 +94,10 @@ template<> struct EiTraits static double abs2(const double& x) { return x*x; } static double random() { - return 20.0 * rand() / RAND_MAX - 10.0; + return rand() / (RAND_MAX/20.0) - 10.0; } }; -const double EiTraits::Epsilon = 1e-11; - template struct EiTraits > { typedef _Real Real; @@ -109,10 +105,10 @@ template struct EiTraits > typedef std::complex FloatingPoint; typedef typename EiTraits::FloatingPoint RealFloatingPoint; - static const Real Epsilon; static const bool IsComplex = true; static const bool HasFloatingPoint = EiTraits::HasFloatingPoint; + static Real epsilon() { return EiTraits::epsilon(); } static Real real(const Complex& x) { return std::real(x); } static Real imag(const Complex& x) { return std::imag(x); } static Complex conj(const Complex& x) { return std::conj(x); } @@ -128,10 +124,6 @@ template struct EiTraits > } }; -template -const _Real EiTraits >::Epsilon - = EiTraits<_Real>::Epsilon; - template typename EiTraits::Real EiReal(const T& x) { return EiTraits::real(x); } @@ -155,13 +147,13 @@ template T EiRandom() template bool EiNegligible(const T& a, const T& b) { - return(EiAbs(a) <= EiAbs(b) * EiTraits::Epsilon); + return(EiAbs(a) <= EiAbs(b) * EiTraits::epsilon()); } template bool EiApprox(const T& a, const T& b) { if(EiTraits::IsFloat) - return(EiAbs(a - b) <= std::min(EiAbs(a), EiAbs(b)) * EiTraits::Epsilon); + return(EiAbs(a - b) <= std::min(EiAbs(a), EiAbs(b)) * EiTraits::epsilon()); else return(a == b); } @@ -174,4 +166,4 @@ template bool EiLessThanOrApprox(const T& a, const T& b) return(a <= b); } -#endif // EI_TRAITS_H +#endif // EI_NUMERIC_H diff --git a/src/internal/Object.h b/src/internal/Object.h index f7506d218..e969e9ee0 100644 --- a/src/internal/Object.h +++ b/src/internal/Object.h @@ -95,6 +95,8 @@ 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(); } template EiMatrixProduct diff --git a/src/internal/Util.h b/src/internal/Util.h index 64d422115..859913908 100644 --- a/src/internal/Util.h +++ b/src/internal/Util.h @@ -49,6 +49,7 @@ template class EiColumn; template class EiMinor; template class EiBlock; template class EiTranspose; +template class EiConjugate; template class EiSum; template class EiDifference; template class EiMatrixProduct; diff --git a/test/main.h b/test/main.h index 06f295ece..1a6644530 100644 --- a/test/main.h +++ b/test/main.h @@ -47,11 +47,13 @@ class EigenTest : public QObject void testMatrixManip(); }; -template T TestEpsilon(); -template<> int TestEpsilon() { return 0; } -template<> float TestEpsilon() { return 1e-2f; } -template<> double TestEpsilon() { return 1e-4; } -template T TestEpsilon >() { return TestEpsilon(); } +template inline typename EiTraits::Real TestEpsilon(); +template<> inline int TestEpsilon() { return 0; } +template<> inline float TestEpsilon() { return 1e-2f; } +template<> inline double TestEpsilon() { return 1e-4; } +template<> inline int TestEpsilon >() { return TestEpsilon(); } +template<> inline float TestEpsilon >() { return TestEpsilon(); } +template<> inline double TestEpsilon >() { return TestEpsilon(); } template bool TestNegligible(const T& a, const T& b) {