00001 // This file is part of Eigen, a lightweight C++ template library 00002 // for linear algebra. 00003 // 00004 // Copyright (C) 2009 Benoit Jacob <jacob.benoit.1@gmail.com> 00005 // Copyright (C) 2009 Gael Guennebaud <gael.guennebaud@inria.fr> 00006 // 00007 // Eigen is free software; you can redistribute it and/or 00008 // modify it under the terms of the GNU Lesser General Public 00009 // License as published by the Free Software Foundation; either 00010 // version 3 of the License, or (at your option) any later version. 00011 // 00012 // Alternatively, you can redistribute it and/or 00013 // modify it under the terms of the GNU General Public License as 00014 // published by the Free Software Foundation; either version 2 of 00015 // the License, or (at your option) any later version. 00016 // 00017 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY 00018 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 00019 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the 00020 // GNU General Public License for more details. 00021 // 00022 // You should have received a copy of the GNU Lesser General Public 00023 // License and a copy of the GNU General Public License along with 00024 // Eigen. If not, see <http://www.gnu.org/licenses/>. 00025 00026 #ifndef EIGEN_EIGENBASE_H 00027 #define EIGEN_EIGENBASE_H 00028 00029 namespace Eigen { 00030 00041 template<typename Derived> struct EigenBase 00042 { 00043 // typedef typename internal::plain_matrix_type<Derived>::type PlainObject; 00044 00045 typedef typename internal::traits<Derived>::StorageKind StorageKind; 00046 typedef typename internal::traits<Derived>::Index Index; 00047 00049 Derived& derived() { return *static_cast<Derived*>(this); } 00051 const Derived& derived() const { return *static_cast<const Derived*>(this); } 00052 00053 inline Derived& const_cast_derived() const 00054 { return *static_cast<Derived*>(const_cast<EigenBase*>(this)); } 00055 inline const Derived& const_derived() const 00056 { return *static_cast<const Derived*>(this); } 00057 00059 inline Index rows() const { return derived().rows(); } 00061 inline Index cols() const { return derived().cols(); } 00064 inline Index size() const { return rows() * cols(); } 00065 00067 template<typename Dest> inline void evalTo(Dest& dst) const 00068 { derived().evalTo(dst); } 00069 00071 template<typename Dest> inline void addTo(Dest& dst) const 00072 { 00073 // This is the default implementation, 00074 // derived class can reimplement it in a more optimized way. 00075 typename Dest::PlainObject res(rows(),cols()); 00076 evalTo(res); 00077 dst += res; 00078 } 00079 00081 template<typename Dest> inline void subTo(Dest& dst) const 00082 { 00083 // This is the default implementation, 00084 // derived class can reimplement it in a more optimized way. 00085 typename Dest::PlainObject res(rows(),cols()); 00086 evalTo(res); 00087 dst -= res; 00088 } 00089 00091 template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const 00092 { 00093 // This is the default implementation, 00094 // derived class can reimplement it in a more optimized way. 00095 dst = dst * this->derived(); 00096 } 00097 00099 template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const 00100 { 00101 // This is the default implementation, 00102 // derived class can reimplement it in a more optimized way. 00103 dst = this->derived() * dst; 00104 } 00105 00106 }; 00107 00108 /*************************************************************************** 00109 * Implementation of matrix base methods 00110 ***************************************************************************/ 00111 00120 template<typename Derived> 00121 template<typename OtherDerived> 00122 Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other) 00123 { 00124 other.derived().evalTo(derived()); 00125 return derived(); 00126 } 00127 00128 template<typename Derived> 00129 template<typename OtherDerived> 00130 Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other) 00131 { 00132 other.derived().addTo(derived()); 00133 return derived(); 00134 } 00135 00136 template<typename Derived> 00137 template<typename OtherDerived> 00138 Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other) 00139 { 00140 other.derived().subTo(derived()); 00141 return derived(); 00142 } 00143 00148 template<typename Derived> 00149 template<typename OtherDerived> 00150 inline Derived& 00151 MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other) 00152 { 00153 other.derived().applyThisOnTheRight(derived()); 00154 return derived(); 00155 } 00156 00158 template<typename Derived> 00159 template<typename OtherDerived> 00160 inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other) 00161 { 00162 other.derived().applyThisOnTheRight(derived()); 00163 } 00164 00166 template<typename Derived> 00167 template<typename OtherDerived> 00168 inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other) 00169 { 00170 other.derived().applyThisOnTheLeft(derived()); 00171 } 00172 00173 } // end namespace Eigen 00174 00175 #endif // EIGEN_EIGENBASE_H