Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010 #ifndef EIGEN_DOT_H
00011 #define EIGEN_DOT_H
00012
00013 namespace Eigen {
00014
00015 namespace internal {
00016
00017
00018
00019
00020 template<typename T, typename U,
00021
00022 bool NeedToTranspose = T::IsVectorAtCompileTime
00023 && U::IsVectorAtCompileTime
00024 && ((int(T::RowsAtCompileTime) == 1 && int(U::ColsAtCompileTime) == 1)
00025 |
00026
00027 (int(T::ColsAtCompileTime) == 1 && int(U::RowsAtCompileTime) == 1))
00028 >
00029 struct dot_nocheck
00030 {
00031 typedef typename scalar_product_traits<typename traits<T>::Scalar,typename traits<U>::Scalar>::ReturnType ResScalar;
00032 static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
00033 {
00034 return a.template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> >(b).sum();
00035 }
00036 };
00037
00038 template<typename T, typename U>
00039 struct dot_nocheck<T, U, true>
00040 {
00041 typedef typename scalar_product_traits<typename traits<T>::Scalar,typename traits<U>::Scalar>::ReturnType ResScalar;
00042 static inline ResScalar run(const MatrixBase<T>& a, const MatrixBase<U>& b)
00043 {
00044 return a.transpose().template binaryExpr<scalar_conj_product_op<typename traits<T>::Scalar,typename traits<U>::Scalar> >(b).sum();
00045 }
00046 };
00047
00048 }
00049
00060 template<typename Derived>
00061 template<typename OtherDerived>
00062 typename internal::scalar_product_traits<typename internal::traits<Derived>::Scalar,typename internal::traits<OtherDerived>::Scalar>::ReturnType
00063 MatrixBase<Derived>::dot(const MatrixBase<OtherDerived>& other) const
00064 {
00065 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00066 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00067 EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
00068 typedef internal::scalar_conj_product_op<Scalar,typename OtherDerived::Scalar> func;
00069 EIGEN_CHECK_BINARY_COMPATIBILIY(func,Scalar,typename OtherDerived::Scalar);
00070
00071 eigen_assert(size() == other.size());
00072
00073 return internal::dot_nocheck<Derived,OtherDerived>::run(*this, other);
00074 }
00075
00076 #ifdef EIGEN2_SUPPORT
00077
00086 template<typename Derived>
00087 template<typename OtherDerived>
00088 typename internal::traits<Derived>::Scalar
00089 MatrixBase<Derived>::eigen2_dot(const MatrixBase<OtherDerived>& other) const
00090 {
00091 EIGEN_STATIC_ASSERT_VECTOR_ONLY(Derived)
00092 EIGEN_STATIC_ASSERT_VECTOR_ONLY(OtherDerived)
00093 EIGEN_STATIC_ASSERT_SAME_VECTOR_SIZE(Derived,OtherDerived)
00094 EIGEN_STATIC_ASSERT((internal::is_same<Scalar, typename OtherDerived::Scalar>::value),
00095 YOU_MIXED_DIFFERENT_NUMERIC_TYPES__YOU_NEED_TO_USE_THE_CAST_METHOD_OF_MATRIXBASE_TO_CAST_NUMERIC_TYPES_EXPLICITLY)
00096
00097 eigen_assert(size() == other.size());
00098
00099 return internal::dot_nocheck<OtherDerived,Derived>::run(other,*this);
00100 }
00101 #endif
00102
00103
00104
00105
00112 template<typename Derived>
00113 EIGEN_STRONG_INLINE typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::squaredNorm() const
00114 {
00115 return numext::real((*this).cwiseAbs2().sum());
00116 }
00117
00124 template<typename Derived>
00125 inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real MatrixBase<Derived>::norm() const
00126 {
00127 using std::sqrt;
00128 return sqrt((double)squaredNorm());
00129 }
00130
00137 template<typename Derived>
00138 inline const typename MatrixBase<Derived>::PlainObject
00139 MatrixBase<Derived>::normalized() const
00140 {
00141 typedef typename internal::nested<Derived>::type Nested;
00142 typedef typename internal::remove_reference<Nested>::type _Nested;
00143 _Nested n(derived());
00144 return n / n.norm();
00145 }
00146
00153 template<typename Derived>
00154 inline void MatrixBase<Derived>::normalize()
00155 {
00156 *this /= norm();
00157 }
00158
00159
00160
00161 namespace internal {
00162
00163 template<typename Derived, int p>
00164 struct lpNorm_selector
00165 {
00166 typedef typename NumTraits<typename traits<Derived>::Scalar>::Real RealScalar;
00167 static inline RealScalar run(const MatrixBase<Derived>& m)
00168 {
00169 using std::pow;
00170 return pow(m.cwiseAbs().array().pow(p).sum(), RealScalar(1)/p);
00171 }
00172 };
00173
00174 template<typename Derived>
00175 struct lpNorm_selector<Derived, 1>
00176 {
00177 static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
00178 {
00179 return m.cwiseAbs().sum();
00180 }
00181 };
00182
00183 template<typename Derived>
00184 struct lpNorm_selector<Derived, 2>
00185 {
00186 static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
00187 {
00188 return m.norm();
00189 }
00190 };
00191
00192 template<typename Derived>
00193 struct lpNorm_selector<Derived, Infinity>
00194 {
00195 static inline typename NumTraits<typename traits<Derived>::Scalar>::Real run(const MatrixBase<Derived>& m)
00196 {
00197 return m.cwiseAbs().maxCoeff();
00198 }
00199 };
00200
00201 }
00202
00209 template<typename Derived>
00210 template<int p>
00211 inline typename NumTraits<typename internal::traits<Derived>::Scalar>::Real
00212 MatrixBase<Derived>::lpNorm() const
00213 {
00214 return internal::lpNorm_selector<Derived, p>::run(*this);
00215 }
00216
00217
00218
00225 template<typename Derived>
00226 template<typename OtherDerived>
00227 bool MatrixBase<Derived>::isOrthogonal
00228 (const MatrixBase<OtherDerived>& other, const RealScalar& prec) const
00229 {
00230 typename internal::nested<Derived,2>::type nested(derived());
00231 typename internal::nested<OtherDerived,2>::type otherNested(other.derived());
00232 return numext::abs2(nested.dot(otherNested)) <= prec * prec * nested.squaredNorm() * otherNested.squaredNorm();
00233 }
00234
00246 template<typename Derived>
00247 bool MatrixBase<Derived>::isUnitary(const RealScalar& prec) const
00248 {
00249 typename Derived::Nested nested(derived());
00250 for(Index i = 0; i < cols(); ++i)
00251 {
00252 if(!internal::isApprox(nested.col(i).squaredNorm(), static_cast<RealScalar>(1), prec))
00253 return false;
00254 for(Index j = 0; j < i; ++j)
00255 if(!internal::isMuchSmallerThan(nested.col(i).dot(nested.col(j)), static_cast<Scalar>(1), prec))
00256 return false;
00257 }
00258 return true;
00259 }
00260
00261 }
00262
00263 #endif // EIGEN_DOT_H