annotate DEPENDENCIES/generic/include/boost/numeric/ublas/operation_sparse.hpp @ 133:4acb5d8d80b6 tip

Don't fail environmental check if README.md exists (but .txt and no-suffix don't)
author Chris Cannam
date Tue, 30 Jul 2019 12:25:44 +0100
parents 2665513ce2d3
children
rev   line source
Chris@16 1 //
Chris@16 2 // Copyright (c) 2000-2002
Chris@16 3 // Joerg Walter, Mathias Koch
Chris@16 4 //
Chris@16 5 // Distributed under the Boost Software License, Version 1.0. (See
Chris@16 6 // accompanying file LICENSE_1_0.txt or copy at
Chris@16 7 // http://www.boost.org/LICENSE_1_0.txt)
Chris@16 8 //
Chris@16 9 // The authors gratefully acknowledge the support of
Chris@16 10 // GeNeSys mbH & Co. KG in producing this work.
Chris@16 11 //
Chris@16 12
Chris@16 13 #ifndef _BOOST_UBLAS_OPERATION_SPARSE_
Chris@16 14 #define _BOOST_UBLAS_OPERATION_SPARSE_
Chris@16 15
Chris@16 16 #include <boost/numeric/ublas/traits.hpp>
Chris@16 17
Chris@16 18 // These scaled additions were borrowed from MTL unashamedly.
Chris@16 19 // But Alexei Novakov had a lot of ideas to improve these. Thanks.
Chris@16 20
Chris@16 21 namespace boost { namespace numeric { namespace ublas {
Chris@16 22
Chris@16 23 template<class M, class E1, class E2, class TRI>
Chris@16 24 BOOST_UBLAS_INLINE
Chris@16 25 M &
Chris@16 26 sparse_prod (const matrix_expression<E1> &e1,
Chris@16 27 const matrix_expression<E2> &e2,
Chris@16 28 M &m, TRI,
Chris@16 29 row_major_tag) {
Chris@16 30 typedef M matrix_type;
Chris@16 31 typedef TRI triangular_restriction;
Chris@16 32 typedef const E1 expression1_type;
Chris@16 33 typedef const E2 expression2_type;
Chris@16 34 typedef typename M::size_type size_type;
Chris@16 35 typedef typename M::value_type value_type;
Chris@16 36
Chris@16 37 // ISSUE why is there a dense vector here?
Chris@16 38 vector<value_type> temporary (e2 ().size2 ());
Chris@16 39 temporary.clear ();
Chris@16 40 typename expression1_type::const_iterator1 it1 (e1 ().begin1 ());
Chris@16 41 typename expression1_type::const_iterator1 it1_end (e1 ().end1 ());
Chris@16 42 while (it1 != it1_end) {
Chris@16 43 size_type jb (temporary.size ());
Chris@16 44 size_type je (0);
Chris@16 45 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 46 typename expression1_type::const_iterator2 it2 (it1.begin ());
Chris@16 47 typename expression1_type::const_iterator2 it2_end (it1.end ());
Chris@16 48 #else
Chris@16 49 typename expression1_type::const_iterator2 it2 (boost::numeric::ublas::begin (it1, iterator1_tag ()));
Chris@16 50 typename expression1_type::const_iterator2 it2_end (boost::numeric::ublas::end (it1, iterator1_tag ()));
Chris@16 51 #endif
Chris@16 52 while (it2 != it2_end) {
Chris@16 53 // temporary.plus_assign (*it2 * row (e2 (), it2.index2 ()));
Chris@16 54 matrix_row<expression2_type> mr (e2 (), it2.index2 ());
Chris@16 55 typename matrix_row<expression2_type>::const_iterator itr (mr.begin ());
Chris@16 56 typename matrix_row<expression2_type>::const_iterator itr_end (mr.end ());
Chris@16 57 while (itr != itr_end) {
Chris@16 58 size_type j (itr.index ());
Chris@16 59 temporary (j) += *it2 * *itr;
Chris@16 60 jb = (std::min) (jb, j);
Chris@16 61 je = (std::max) (je, j);
Chris@16 62 ++ itr;
Chris@16 63 }
Chris@16 64 ++ it2;
Chris@16 65 }
Chris@16 66 for (size_type j = jb; j < je + 1; ++ j) {
Chris@16 67 if (temporary (j) != value_type/*zero*/()) {
Chris@16 68 // FIXME we'll need to extend the container interface!
Chris@16 69 // m.push_back (it1.index1 (), j, temporary (j));
Chris@16 70 // FIXME What to do with adaptors?
Chris@16 71 // m.insert (it1.index1 (), j, temporary (j));
Chris@16 72 if (triangular_restriction::other (it1.index1 (), j))
Chris@16 73 m (it1.index1 (), j) = temporary (j);
Chris@16 74 temporary (j) = value_type/*zero*/();
Chris@16 75 }
Chris@16 76 }
Chris@16 77 ++ it1;
Chris@16 78 }
Chris@16 79 return m;
Chris@16 80 }
Chris@16 81
Chris@16 82 template<class M, class E1, class E2, class TRI>
Chris@16 83 BOOST_UBLAS_INLINE
Chris@16 84 M &
Chris@16 85 sparse_prod (const matrix_expression<E1> &e1,
Chris@16 86 const matrix_expression<E2> &e2,
Chris@16 87 M &m, TRI,
Chris@16 88 column_major_tag) {
Chris@16 89 typedef M matrix_type;
Chris@16 90 typedef TRI triangular_restriction;
Chris@16 91 typedef const E1 expression1_type;
Chris@16 92 typedef const E2 expression2_type;
Chris@16 93 typedef typename M::size_type size_type;
Chris@16 94 typedef typename M::value_type value_type;
Chris@16 95
Chris@16 96 // ISSUE why is there a dense vector here?
Chris@16 97 vector<value_type> temporary (e1 ().size1 ());
Chris@16 98 temporary.clear ();
Chris@16 99 typename expression2_type::const_iterator2 it2 (e2 ().begin2 ());
Chris@16 100 typename expression2_type::const_iterator2 it2_end (e2 ().end2 ());
Chris@16 101 while (it2 != it2_end) {
Chris@16 102 size_type ib (temporary.size ());
Chris@16 103 size_type ie (0);
Chris@16 104 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
Chris@16 105 typename expression2_type::const_iterator1 it1 (it2.begin ());
Chris@16 106 typename expression2_type::const_iterator1 it1_end (it2.end ());
Chris@16 107 #else
Chris@16 108 typename expression2_type::const_iterator1 it1 (boost::numeric::ublas::begin (it2, iterator2_tag ()));
Chris@16 109 typename expression2_type::const_iterator1 it1_end (boost::numeric::ublas::end (it2, iterator2_tag ()));
Chris@16 110 #endif
Chris@16 111 while (it1 != it1_end) {
Chris@16 112 // column (m, it2.index2 ()).plus_assign (*it1 * column (e1 (), it1.index1 ()));
Chris@16 113 matrix_column<expression1_type> mc (e1 (), it1.index1 ());
Chris@16 114 typename matrix_column<expression1_type>::const_iterator itc (mc.begin ());
Chris@16 115 typename matrix_column<expression1_type>::const_iterator itc_end (mc.end ());
Chris@16 116 while (itc != itc_end) {
Chris@16 117 size_type i (itc.index ());
Chris@16 118 temporary (i) += *it1 * *itc;
Chris@16 119 ib = (std::min) (ib, i);
Chris@16 120 ie = (std::max) (ie, i);
Chris@16 121 ++ itc;
Chris@16 122 }
Chris@16 123 ++ it1;
Chris@16 124 }
Chris@16 125 for (size_type i = ib; i < ie + 1; ++ i) {
Chris@16 126 if (temporary (i) != value_type/*zero*/()) {
Chris@16 127 // FIXME we'll need to extend the container interface!
Chris@16 128 // m.push_back (i, it2.index2 (), temporary (i));
Chris@16 129 // FIXME What to do with adaptors?
Chris@16 130 // m.insert (i, it2.index2 (), temporary (i));
Chris@16 131 if (triangular_restriction::other (i, it2.index2 ()))
Chris@16 132 m (i, it2.index2 ()) = temporary (i);
Chris@16 133 temporary (i) = value_type/*zero*/();
Chris@16 134 }
Chris@16 135 }
Chris@16 136 ++ it2;
Chris@16 137 }
Chris@16 138 return m;
Chris@16 139 }
Chris@16 140
Chris@16 141 // Dispatcher
Chris@16 142 template<class M, class E1, class E2, class TRI>
Chris@16 143 BOOST_UBLAS_INLINE
Chris@16 144 M &
Chris@16 145 sparse_prod (const matrix_expression<E1> &e1,
Chris@16 146 const matrix_expression<E2> &e2,
Chris@16 147 M &m, TRI, bool init = true) {
Chris@16 148 typedef typename M::value_type value_type;
Chris@16 149 typedef TRI triangular_restriction;
Chris@16 150 typedef typename M::orientation_category orientation_category;
Chris@16 151
Chris@16 152 if (init)
Chris@16 153 m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
Chris@16 154 return sparse_prod (e1, e2, m, triangular_restriction (), orientation_category ());
Chris@16 155 }
Chris@16 156 template<class M, class E1, class E2, class TRI>
Chris@16 157 BOOST_UBLAS_INLINE
Chris@16 158 M
Chris@16 159 sparse_prod (const matrix_expression<E1> &e1,
Chris@16 160 const matrix_expression<E2> &e2,
Chris@16 161 TRI) {
Chris@16 162 typedef M matrix_type;
Chris@16 163 typedef TRI triangular_restriction;
Chris@16 164
Chris@16 165 matrix_type m (e1 ().size1 (), e2 ().size2 ());
Chris@16 166 // FIXME needed for c_matrix?!
Chris@16 167 // return sparse_prod (e1, e2, m, triangular_restriction (), false);
Chris@16 168 return sparse_prod (e1, e2, m, triangular_restriction (), true);
Chris@16 169 }
Chris@16 170 template<class M, class E1, class E2>
Chris@16 171 BOOST_UBLAS_INLINE
Chris@16 172 M &
Chris@16 173 sparse_prod (const matrix_expression<E1> &e1,
Chris@16 174 const matrix_expression<E2> &e2,
Chris@16 175 M &m, bool init = true) {
Chris@16 176 typedef typename M::value_type value_type;
Chris@16 177 typedef typename M::orientation_category orientation_category;
Chris@16 178
Chris@16 179 if (init)
Chris@16 180 m.assign (zero_matrix<value_type> (e1 ().size1 (), e2 ().size2 ()));
Chris@16 181 return sparse_prod (e1, e2, m, full (), orientation_category ());
Chris@16 182 }
Chris@16 183 template<class M, class E1, class E2>
Chris@16 184 BOOST_UBLAS_INLINE
Chris@16 185 M
Chris@16 186 sparse_prod (const matrix_expression<E1> &e1,
Chris@16 187 const matrix_expression<E2> &e2) {
Chris@16 188 typedef M matrix_type;
Chris@16 189
Chris@16 190 matrix_type m (e1 ().size1 (), e2 ().size2 ());
Chris@16 191 // FIXME needed for c_matrix?!
Chris@16 192 // return sparse_prod (e1, e2, m, full (), false);
Chris@16 193 return sparse_prod (e1, e2, m, full (), true);
Chris@16 194 }
Chris@16 195
Chris@16 196 }}}
Chris@16 197
Chris@16 198 #endif