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 00040 template<typename Derived> struct EigenBase 00041 { 00042 // typedef typename internal::plain_matrix_type<Derived>::type PlainObject; 00043 00044 typedef typename internal::traits<Derived>::StorageKind StorageKind; 00045 typedef typename internal::traits<Derived>::Index Index; 00046 00048 Derived& derived() { return *static_cast<Derived*>(this); } 00050 const Derived& derived() const { return *static_cast<const Derived*>(this); } 00051 00052 inline Derived& const_cast_derived() const 00053 { return *static_cast<Derived*>(const_cast<EigenBase*>(this)); } 00054 inline const Derived& const_derived() const 00055 { return *static_cast<const Derived*>(this); } 00056 00058 inline Index rows() const { return derived().rows(); } 00060 inline Index cols() const { return derived().cols(); } 00063 inline Index size() const { return rows() * cols(); } 00064 00066 template<typename Dest> inline void evalTo(Dest& dst) const 00067 { derived().evalTo(dst); } 00068 00070 template<typename Dest> inline void addTo(Dest& dst) const 00071 { 00072 // This is the default implementation, 00073 // derived class can reimplement it in a more optimized way. 00074 typename Dest::PlainObject res(rows(),cols()); 00075 evalTo(res); 00076 dst += res; 00077 } 00078 00080 template<typename Dest> inline void subTo(Dest& dst) const 00081 { 00082 // This is the default implementation, 00083 // derived class can reimplement it in a more optimized way. 00084 typename Dest::PlainObject res(rows(),cols()); 00085 evalTo(res); 00086 dst -= res; 00087 } 00088 00090 template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const 00091 { 00092 // This is the default implementation, 00093 // derived class can reimplement it in a more optimized way. 00094 dst = dst * this->derived(); 00095 } 00096 00098 template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const 00099 { 00100 // This is the default implementation, 00101 // derived class can reimplement it in a more optimized way. 00102 dst = this->derived() * dst; 00103 } 00104 00105 }; 00106 00107 /*************************************************************************** 00108 * Implementation of matrix base methods 00109 ***************************************************************************/ 00110 00119 template<typename Derived> 00120 template<typename OtherDerived> 00121 Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other) 00122 { 00123 other.derived().evalTo(derived()); 00124 return derived(); 00125 } 00126 00127 template<typename Derived> 00128 template<typename OtherDerived> 00129 Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other) 00130 { 00131 other.derived().addTo(derived()); 00132 return derived(); 00133 } 00134 00135 template<typename Derived> 00136 template<typename OtherDerived> 00137 Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other) 00138 { 00139 other.derived().subTo(derived()); 00140 return derived(); 00141 } 00142 00147 template<typename Derived> 00148 template<typename OtherDerived> 00149 inline Derived& 00150 MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other) 00151 { 00152 other.derived().applyThisOnTheRight(derived()); 00153 return derived(); 00154 } 00155 00157 template<typename Derived> 00158 template<typename OtherDerived> 00159 inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other) 00160 { 00161 other.derived().applyThisOnTheRight(derived()); 00162 } 00163 00165 template<typename Derived> 00166 template<typename OtherDerived> 00167 inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other) 00168 { 00169 other.derived().applyThisOnTheLeft(derived()); 00170 } 00171 00172 #endif // EIGEN_EIGENBASE_H