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 // This Source Code Form is subject to the terms of the Mozilla 00008 // Public License v. 2.0. If a copy of the MPL was not distributed 00009 // with this file, You can obtain one at http://mozilla.org/MPL/2.0/. 00010 00011 #ifndef EIGEN_EIGENBASE_H 00012 #define EIGEN_EIGENBASE_H 00013 00014 namespace Eigen { 00015 00026 template<typename Derived> struct EigenBase 00027 { 00028 // typedef typename internal::plain_matrix_type<Derived>::type PlainObject; 00029 00030 typedef typename internal::traits<Derived>::StorageKind StorageKind; 00031 typedef typename internal::traits<Derived>::Index Index; 00032 00034 Derived& derived() { return *static_cast<Derived*>(this); } 00036 const Derived& derived() const { return *static_cast<const Derived*>(this); } 00037 00038 inline Derived& const_cast_derived() const 00039 { return *static_cast<Derived*>(const_cast<EigenBase*>(this)); } 00040 inline const Derived& const_derived() const 00041 { return *static_cast<const Derived*>(this); } 00042 00044 inline Index rows() const { return derived().rows(); } 00046 inline Index cols() const { return derived().cols(); } 00049 inline Index size() const { return rows() * cols(); } 00050 00052 template<typename Dest> inline void evalTo(Dest& dst) const 00053 { derived().evalTo(dst); } 00054 00056 template<typename Dest> inline void addTo(Dest& dst) const 00057 { 00058 // This is the default implementation, 00059 // derived class can reimplement it in a more optimized way. 00060 typename Dest::PlainObject res(rows(),cols()); 00061 evalTo(res); 00062 dst += res; 00063 } 00064 00066 template<typename Dest> inline void subTo(Dest& dst) const 00067 { 00068 // This is the default implementation, 00069 // derived class can reimplement it in a more optimized way. 00070 typename Dest::PlainObject res(rows(),cols()); 00071 evalTo(res); 00072 dst -= res; 00073 } 00074 00076 template<typename Dest> inline void applyThisOnTheRight(Dest& dst) const 00077 { 00078 // This is the default implementation, 00079 // derived class can reimplement it in a more optimized way. 00080 dst = dst * this->derived(); 00081 } 00082 00084 template<typename Dest> inline void applyThisOnTheLeft(Dest& dst) const 00085 { 00086 // This is the default implementation, 00087 // derived class can reimplement it in a more optimized way. 00088 dst = this->derived() * dst; 00089 } 00090 00091 }; 00092 00093 /*************************************************************************** 00094 * Implementation of matrix base methods 00095 ***************************************************************************/ 00096 00105 template<typename Derived> 00106 template<typename OtherDerived> 00107 Derived& DenseBase<Derived>::operator=(const EigenBase<OtherDerived> &other) 00108 { 00109 other.derived().evalTo(derived()); 00110 return derived(); 00111 } 00112 00113 template<typename Derived> 00114 template<typename OtherDerived> 00115 Derived& DenseBase<Derived>::operator+=(const EigenBase<OtherDerived> &other) 00116 { 00117 other.derived().addTo(derived()); 00118 return derived(); 00119 } 00120 00121 template<typename Derived> 00122 template<typename OtherDerived> 00123 Derived& DenseBase<Derived>::operator-=(const EigenBase<OtherDerived> &other) 00124 { 00125 other.derived().subTo(derived()); 00126 return derived(); 00127 } 00128 00133 template<typename Derived> 00134 template<typename OtherDerived> 00135 inline Derived& 00136 MatrixBase<Derived>::operator*=(const EigenBase<OtherDerived> &other) 00137 { 00138 other.derived().applyThisOnTheRight(derived()); 00139 return derived(); 00140 } 00141 00143 template<typename Derived> 00144 template<typename OtherDerived> 00145 inline void MatrixBase<Derived>::applyOnTheRight(const EigenBase<OtherDerived> &other) 00146 { 00147 other.derived().applyThisOnTheRight(derived()); 00148 } 00149 00151 template<typename Derived> 00152 template<typename OtherDerived> 00153 inline void MatrixBase<Derived>::applyOnTheLeft(const EigenBase<OtherDerived> &other) 00154 { 00155 other.derived().applyThisOnTheLeft(derived()); 00156 } 00157 00158 } // end namespace Eigen 00159 00160 #endif // EIGEN_EIGENBASE_H