00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_FROBENIUS_NORM_INCLUDE
00013 #define MTL_FROBENIUS_NORM_INCLUDE
00014
00015 #include <boost/numeric/mtl/concept/collection.hpp>
00016 #include <boost/numeric/mtl/utility/is_row_major.hpp>
00017 #include <boost/numeric/mtl/utility/tag.hpp>
00018 #include <boost/numeric/mtl/utility/range_generator.hpp>
00019 #include <boost/numeric/mtl/utility/property_map.hpp>
00020 #include <boost/numeric/mtl/operation/max_of_sums.hpp>
00021 #include <boost/numeric/linear_algebra/identity.hpp>
00022
00023
00024 namespace mtl { namespace matrix {
00025
00027 template <typename Matrix>
00028 typename RealMagnitude<typename Collection<Matrix>::value_type>::type
00029 inline frobenius_norm(const Matrix& matrix)
00030 {
00031 using std::sqrt; using std::abs; using math::zero;
00032 namespace traits = mtl::traits;
00033 typename traits::const_value<Matrix>::type value(matrix);
00034
00035 typedef typename Collection<Matrix>::value_type value_type;
00036 typedef typename RealMagnitude<value_type>::type real_type;
00037 real_type ref, sum= zero(ref);
00038
00039 typedef typename traits::range_generator<tag::major, Matrix>::type cursor_type;
00040 typedef typename traits::range_generator<tag::nz, cursor_type>::type icursor_type;
00041
00042 for (cursor_type cursor = begin<tag::major>(matrix), cend = end<tag::major>(matrix); cursor != cend; ++cursor)
00043 for (icursor_type icursor = begin<tag::nz>(cursor), icend = end<tag::nz>(cursor); icursor != icend; ++icursor) {
00044 real_type tmp= abs(value(*icursor));
00045 sum+= tmp * tmp;
00046 }
00047 return sqrt(sum);
00048 }
00049
00050 }}
00051
00052 #endif // MTL_FROBENIUS_NORM_INCLUDE