00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012 #ifndef MTL_RANK_ONE_UPDATE_INCLUDE
00013 #define MTL_RANK_ONE_UPDATE_INCLUDE
00014
00015 #include <boost/numeric/mtl/utility/tag.hpp>
00016 #include <boost/numeric/mtl/utility/property_map.hpp>
00017 #include <boost/numeric/mtl/utility/exception.hpp>
00018 #include <boost/numeric/mtl/utility/range_generator.hpp>
00019 #include <boost/numeric/mtl/matrix/inserter.hpp>
00020 #include <boost/numeric/mtl/operation/update.hpp>
00021 #include <boost/numeric/mtl/operation/conj.hpp>
00022
00023 namespace mtl { namespace matrix {
00024
00025
00027
00029 template <typename Matrix, typename VectorX, typename VectorY>
00030 inline void rank_one_update(Matrix& matrix, const VectorX& x, const VectorY& y)
00031 {
00032 using mtl::conj;
00033 MTL_THROW_IF(num_rows(matrix) != size(x) || num_cols(matrix) != size(y), incompatible_size());
00034 namespace traits = mtl::traits;
00035 typedef typename traits::range_generator<tag::nz, VectorX>::type x_cursor;
00036 typename traits::index<VectorX>::type index_x(x);
00037 typename traits::const_value<VectorX>::type value_x(x);
00038
00039 typedef typename traits::range_generator<tag::nz, VectorY>::type y_cursor;
00040 typename traits::index<VectorY>::type index_y(y);
00041 typename traits::const_value<VectorY>::type value_y(y);
00042
00043 matrix::inserter<Matrix, operations::update_plus<typename Collection<Matrix>::value_type> > ins(matrix);
00044
00045 for (x_cursor xc= begin<tag::nz>(x), xend= end<tag::nz>(x); xc != xend; ++xc)
00046 for (y_cursor yc= begin<tag::nz>(y), yend= end<tag::nz>(y); yc != yend; ++yc)
00047 ins(index_x(*xc), index_y(*yc)) << value_x(*xc) * conj(value_y(*yc));
00048 }
00049
00050
00051 }}
00052
00053 #endif // MTL_RANK_ONE_UPDATE_INCLUDE