00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_ORTH_INCLUDE
00013 #define MTL_ORTH_INCLUDE
00014
00015 #include <boost/numeric/linear_algebra/identity.hpp>
00016 #include <boost/numeric/mtl/concept/collection.hpp>
00017 #include <boost/numeric/mtl/utility/tag.hpp>
00018 #include <boost/numeric/mtl/utility/category.hpp>
00019 #include <boost/numeric/mtl/operation/size.hpp>
00020 #include <boost/numeric/mtl/operation/size1D.hpp>
00021 #include <boost/numeric/mtl/operation/entry1D.hpp>
00022 #include <boost/numeric/mtl/operation/dot.hpp>
00023 #include <boost/numeric/mtl/operation/two_norm.hpp>
00024
00025 namespace mtl { namespace vector {
00026
00027 namespace impl {
00028
00029 template <typename VVector>
00030 inline void orth(VVector& v, typename mtl::Collection<VVector>::size_type j, tag::vector)
00031 {
00032 using mtl::two_norm; using mtl::size1D;
00033 MTL_DEBUG_THROW_IF(j < 0 || j >= size1D(v), index_out_of_range());
00034
00035 typedef typename mtl::Collection<VVector>::size_type Size;
00036 for (Size i= 0; i < j; ++i)
00037 entry1D(v, j)-= dot(entry1D(v, i), entry1D(v, j)) * entry1D(v, i);
00038 entry1D(v, j)/= two_norm(entry1D(v, j));
00039 }
00040
00041 template <typename VVector>
00042 inline void orth(VVector& v, tag::vector)
00043 {
00044 typedef typename mtl::Collection<VVector>::size_type Size;
00045 using mtl::size1D;
00046 for (Size j= 0; j < size1D(v); ++j)
00047 orth(v, j, tag::vector());
00048 }
00049
00050
00051 template <typename VVector>
00052 dense2D<typename mtl::Collection
00053 <typename mtl::Collection<VVector>::value_type
00054 >::value_type >
00055 inline orthogonalize_factors(VVector& v, tag::vector)
00056 {
00057 using ::mtl::two_norm; using math::zero; using mtl::size1D;
00058 typedef typename mtl::Collection<VVector>::size_type Size;
00059 typedef typename mtl::Collection<VVector>::value_type Vector;
00060 typedef typename mtl::Collection<Vector>::value_type Scalar;
00061
00062 dense2D<Scalar> tau(size1D(v), size1D(v));
00063 tau= zero(Scalar());
00064
00065 for (Size j= 0; j < size1D(v); ++j) {
00066 for (Size i= 0; i < j; ++i) {
00067 Scalar t= dot(entry1D(v, i), entry1D(v, j)) / tau[i][i];
00068 tau[i][j]= t;
00069 entry1D(v, j)-= t * entry1D(v, i);
00070 }
00071 tau[j][j]= dot(entry1D(v, j), entry1D(v, j));
00072 }
00073 return tau;
00074 }
00075
00076 }
00077
00078
00079
00089 template <typename Value>
00090 inline void orth(Value& value)
00091 {
00092 impl::orth(value, typename traits::category<Value>::type());
00093 }
00094
00106 template <typename Value>
00107 inline void orth(Value& value, typename mtl::Collection<Value>::size_type i)
00108 {
00109 impl::orth(value, i, typename traits::category<Value>::type());
00110 }
00111
00112
00124 template <typename Value>
00125 dense2D<typename mtl::Collection
00126 <typename mtl::Collection<Value>::value_type
00127 >::value_type >
00128 inline orthogonalize_factors(Value& v)
00129 {
00130 return impl::orthogonalize_factors(v, typename traits::category<Value>::type());
00131 }
00132
00133 }
00134
00135 namespace matrix {
00136
00137
00138 template <typename Vector>
00139 inline void orth(multi_vector<Vector>& A)
00140 {
00141 mtl::vector::impl::orth(A, mtl::tag::vector());
00142 }
00143 }
00144
00145 using vector::orth;
00146 using vector::orthogonalize_factors;
00147
00148 }
00149
00150 #endif // MTL_ORTH_INCLUDE