Main MRPT website > C++ reference
MRPT logo

Dot.h

Go to the documentation of this file.
00001 // This file is part of Eigen, a lightweight C++ template library
00002 // for linear algebra.
00003 //
00004 // Copyright (C) 2006-2008, 2010 Benoit Jacob <jacob.benoit.1@gmail.com>
00005 //
00006 // Eigen is free software; you can redistribute it and/or
00007 // modify it under the terms of the GNU Lesser General Public
00008 // License as published by the Free Software Foundation; either
00009 // version 3 of the License, or (at your option) any later version.
00010 //
00011 // Alternatively, you can redistribute it and/or
00012 // modify it under the terms of the GNU General Public License as
00013 // published by the Free Software Foundation; either version 2 of
00014 // the License, or (at your option) any later version.
00015 //
00016 // Eigen is distributed in the hope that it will be useful, but WITHOUT ANY
00017 // WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
00018 // FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License or the
00019 // GNU General Public License for more details.
00020 //
00021 // You should have received a copy of the GNU Lesser General Public
00022 // License and a copy of the GNU General Public License along with
00023 // Eigen. If not, see <http://www.gnu.org/licenses/>.
00024 
00025 #ifndef EIGEN_DOT_H
00026 #define EIGEN_DOT_H
00027 
00028 namespace internal {
00029 
00030 // helper function for dot(). The problem is that if we put that in the body of dot(), then upon calling dot
00031 // with mismatched types, the compiler emits errors about failing to instantiate cwiseProduct BEFORE
00032 // looking at the static assertions. Thus this is a trick to get better compile errors.
00033 template<typename T, typename U,
00034 // the NeedToTranspose condition here is taken straight from Assign.h
00035          bool NeedToTranspose = T::IsVectorAtCompileTime
00036                 && U::IsVectorAtCompileTime
00037                 && ((int(T::RowsAtCompileTime) == 1 && int(U::ColsAtCompileTime) == 1)
00038                       |  // FIXME | instead of || to please GCC 4.4.0 stupid warning "suggest parentheses around &&".
00039                          // revert to || as soon as not needed anymore.
00040                     (int(T::ColsAtCompileTime) == 1 && int(U::RowsAtCompileTime) == 1))
00041 >
00042 struct dot_nocheck
00043 {
00044   static inline typename traits<T>::Scalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
00045   {
00046     return a.template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar> >(b).sum();
00047   }
00048 };
00049 
00050 template<typename T, typename U>
00051 struct dot_nocheck<T, U, true>
00052 {
00053   static inline typename traits<T>::Scalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
00054   {
00055     return a.transpose().template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar> >(b).sum();
00056   }
00057 };
00058 
00059 } // end namespace internal
00060 
00061 /** \returns the dot product of *this with other.
00062   *
00063   * \only_for_vectors
00064   *
00065   * \note If the scalar type is complex numbers, then this function returns the hermitian
00066   * (sesquilinear) dot product, conjugate-linear in the first variable and linear in the
00067   * second variable.
00068   *
00069   * \sa squaredNorm(), norm()
00070   */
00071 template<typename Derived>
00072 template<typename OtherDerived>
00073 typename internal::traits<Derived>::Scalar
00074 MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
00075 {
00076   EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00077   EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00078   EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
00079   EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
00080     YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
00081 
00082   eigen_assert(size() == other.size());
00083 
00084   return internal::dot_nocheck<Derived,OtherDerived>::run(*this, other);
00085 }
00086 
00087 //---------- implementation of L2 norm and related functions ----------
00088 
00089 /** \returns the squared \em l2 norm of *this, i.e., for vectors, the dot product of *this with itself.
00090   *
00091   * \sa dot(), norm()
00092   */
00093 template<typename Derived>
00094 EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
00095 {
00096   return internal::real((*this).cwiseAbs2().sum());
00097 }
00098 
00099 /** \returns the \em l2 norm of *this, i.e., for vectors, the square root of the dot product of *this with itself.
00100   *
00101   * \sa dot(), squaredNorm()
00102   */
00103 template<typename Derived>
00104 inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
00105 {
00106   return internal::sqrt(squaredNorm());
00107 }
00108 
00109 /** \returns an expression of the quotient of *this by its own norm.
00110   *
00111   * \only_for_vectors
00112   *
00113   * \sa norm(), normalize()
00114   */
00115 template<typename Derived>
00116 inline const typename MatrixBase<Derived>::PlainObject
00117 MatrixBase<Derived>::normalized() const
00118 {
00119   typedef typename internal::nested<Derived>::type Nested;
00120   typedef typename internal::remove_reference<Nested>::type _Nested;
00121   _Nested n(derived());
00122   return n / n.norm();
00123 }
00124 
00125 /** Normalizes the vector, i.e. divides it by its own norm.
00126   *
00127   * \only_for_vectors
00128   *
00129   * \sa norm(), normalized()
00130   */
00131 template<typename Derived>
00132 inline void MatrixBase<Derived>::normalize()
00133 {
00134   *this /= norm();
00135 }
00136 
00137 //---------- implementation of other norms ----------
00138 
00139 namespace internal {
00140 
00141 template<typename Derived, int p>
00142 struct lpNorm_selector
00143 {
00144   typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
00145   inline static RealScalar run(const MatrixBase<Derived>& m)
00146   {
00147     return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
00148   }
00149 };
00150 
00151 template<typename Derived>
00152 struct lpNorm_selector<Derived, 1>
00153 {
00154   inline static typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
00155   {
00156     return m.cwiseAbs().sum();
00157   }
00158 };
00159 
00160 template<typename Derived>
00161 struct lpNorm_selector<Derived, 2>
00162 {
00163   inline static typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
00164   {
00165     return m.norm();
00166   }
00167 };
00168 
00169 template<typename Derived>
00170 struct lpNorm_selector<Derived, Infinity>
00171 {
00172   inline static typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
00173   {
00174     return m.cwiseAbs().maxCoeff();
00175   }
00176 };
00177 
00178 } // end namespace internal
00179 
00180 /** \returns the \f$ \ell^p \f$ norm of *this, that is, returns the p-th root of the sum of the p-th powers of the absolute values
00181   *          of the coefficients of *this. If \a p is the special value \a Eigen::Infinity, this function returns the \f$ \ell^\infty \f$
00182   *          norm, that is the maximum of the absolute values of the coefficients of *this.
00183   *
00184   * \sa norm()
00185   */
00186 template<typename Derived>
00187 template<int p>
00188 inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
00189 MatrixBase<Derived>::lpNorm() const
00190 {
00191   return internal::lpNorm_selector<Derived, p>::run(*this);
00192 }
00193 
00194 //---------- implementation of isOrthogonal / isUnitary ----------
00195 
00196 /** \returns true if *this is approximately orthogonal to \a other,
00197   *          within the precision given by \a prec.
00198   *
00199   * Example: \include MatrixBase_isOrthogonal.cpp
00200   * Output: \verbinclude MatrixBase_isOrthogonal.out
00201   */
00202 template<typename Derived>
00203 template<typename OtherDerived>
00204 bool MatrixBase<Derived>::isOrthogonal
00205 (const MatrixBase<OtherDerived>& other, RealScalar prec) const
00206 {
00207   typename internal::nested<Derived,2>::type nested(derived());
00208   typename internal::nested<OtherDerived,2>::type otherNested(other.derived());
00209   return internal::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
00210 }
00211 
00212 /** \returns true if *this is approximately an unitary matrix,
00213   *          within the precision given by \a prec. In the case where the \a Scalar
00214   *          type is real numbers, a unitary matrix is an orthogonal matrix, whence the name.
00215   *
00216   * \note This can be used to check whether a family of vectors forms an orthonormal basis.
00217   *       Indeed, \c m.isUnitary() returns true if and only if the columns (equivalently, the rows) of m form an
00218   *       orthonormal basis.
00219   *
00220   * Example: \include MatrixBase_isUnitary.cpp
00221   * Output: \verbinclude MatrixBase_isUnitary.out
00222   */
00223 template<typename Derived>
00224 bool MatrixBase<Derived>::isUnitary(RealScalar prec) const
00225 {
00226   typename Derived::Nested nested(derived());
00227   for(Index i = 0; i < cols(); ++i)
00228   {
00229     if(!internal::isApprox(nested.col(i).squaredNorm(), static_cast<RealScalar>(1), prec))
00230       return false;
00231     for(Index j = 0; j < i; ++j)
00232       if(!internal::isMuchSmallerThan(nested.col(i).dot(nested.col(j)), static_cast<Scalar>(1), prec))
00233         return false;
00234   }
00235   return true;
00236 }
00237 
00238 #endif // EIGEN_DOT_H



Page generated by Doxygen 1.7.3 for MRPT 0.9.4 SVN:exported at Tue Jan 25 21:56:31 UTC 2011