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_MATRIX_ASSIGN_
|
Chris@16
|
14 #define _BOOST_UBLAS_MATRIX_ASSIGN_
|
Chris@16
|
15
|
Chris@16
|
16 #include <boost/numeric/ublas/traits.hpp>
|
Chris@16
|
17 // Required for make_conformant storage
|
Chris@16
|
18 #include <vector>
|
Chris@16
|
19
|
Chris@16
|
20 // Iterators based on ideas of Jeremy Siek
|
Chris@16
|
21
|
Chris@16
|
22 namespace boost { namespace numeric { namespace ublas {
|
Chris@16
|
23 namespace detail {
|
Chris@16
|
24
|
Chris@16
|
25 // Weak equality check - useful to compare equality two arbitary matrix expression results.
|
Chris@16
|
26 // Since the actual expressions are unknown, we check for and arbitary error bound
|
Chris@16
|
27 // on the relative error.
|
Chris@16
|
28 // For a linear expression the infinity norm makes sense as we do not know how the elements will be
|
Chris@16
|
29 // combined in the expression. False positive results are inevitable for arbirary expressions!
|
Chris@16
|
30 template<class E1, class E2, class S>
|
Chris@16
|
31 BOOST_UBLAS_INLINE
|
Chris@16
|
32 bool equals (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2, S epsilon, S min_norm) {
|
Chris@16
|
33 return norm_inf (e1 - e2) < epsilon *
|
Chris@16
|
34 std::max<S> (std::max<S> (norm_inf (e1), norm_inf (e2)), min_norm);
|
Chris@16
|
35 }
|
Chris@16
|
36
|
Chris@16
|
37 template<class E1, class E2>
|
Chris@16
|
38 BOOST_UBLAS_INLINE
|
Chris@16
|
39 bool expression_type_check (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
|
Chris@16
|
40 typedef typename type_traits<typename promote_traits<typename E1::value_type,
|
Chris@16
|
41 typename E2::value_type>::promote_type>::real_type real_type;
|
Chris@16
|
42 return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
|
Chris@16
|
43 }
|
Chris@16
|
44
|
Chris@16
|
45
|
Chris@16
|
46 template<class M, class E, class R>
|
Chris@16
|
47 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
48 void make_conformant (M &m, const matrix_expression<E> &e, row_major_tag, R) {
|
Chris@16
|
49 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
Chris@16
|
50 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
Chris@16
|
51 typedef R conformant_restrict_type;
|
Chris@16
|
52 typedef typename M::size_type size_type;
|
Chris@16
|
53 typedef typename M::difference_type difference_type;
|
Chris@16
|
54 typedef typename M::value_type value_type;
|
Chris@16
|
55 // FIXME unbounded_array with push_back maybe better
|
Chris@16
|
56 std::vector<std::pair<size_type, size_type> > index;
|
Chris@16
|
57 typename M::iterator1 it1 (m.begin1 ());
|
Chris@16
|
58 typename M::iterator1 it1_end (m.end1 ());
|
Chris@16
|
59 typename E::const_iterator1 it1e (e ().begin1 ());
|
Chris@16
|
60 typename E::const_iterator1 it1e_end (e ().end1 ());
|
Chris@16
|
61 while (it1 != it1_end && it1e != it1e_end) {
|
Chris@16
|
62 difference_type compare = it1.index1 () - it1e.index1 ();
|
Chris@16
|
63 if (compare == 0) {
|
Chris@16
|
64 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
65 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
66 typename M::iterator2 it2_end (it1.end ());
|
Chris@16
|
67 typename E::const_iterator2 it2e (it1e.begin ());
|
Chris@16
|
68 typename E::const_iterator2 it2e_end (it1e.end ());
|
Chris@16
|
69 #else
|
Chris@16
|
70 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
71 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
|
Chris@16
|
72 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@16
|
73 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
|
Chris@16
|
74 #endif
|
Chris@16
|
75 if (it2 != it2_end && it2e != it2e_end) {
|
Chris@16
|
76 size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
|
Chris@16
|
77 while (true) {
|
Chris@101
|
78 difference_type compare2 = it2_index - it2e_index;
|
Chris@101
|
79 if (compare2 == 0) {
|
Chris@16
|
80 ++ it2, ++ it2e;
|
Chris@16
|
81 if (it2 != it2_end && it2e != it2e_end) {
|
Chris@16
|
82 it2_index = it2.index2 ();
|
Chris@16
|
83 it2e_index = it2e.index2 ();
|
Chris@16
|
84 } else
|
Chris@16
|
85 break;
|
Chris@101
|
86 } else if (compare2 < 0) {
|
Chris@101
|
87 increment (it2, it2_end, - compare2);
|
Chris@16
|
88 if (it2 != it2_end)
|
Chris@16
|
89 it2_index = it2.index2 ();
|
Chris@16
|
90 else
|
Chris@16
|
91 break;
|
Chris@101
|
92 } else if (compare2 > 0) {
|
Chris@16
|
93 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
|
Chris@16
|
94 if (static_cast<value_type>(*it2e) != value_type/*zero*/())
|
Chris@16
|
95 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
|
Chris@16
|
96 ++ it2e;
|
Chris@16
|
97 if (it2e != it2e_end)
|
Chris@16
|
98 it2e_index = it2e.index2 ();
|
Chris@16
|
99 else
|
Chris@16
|
100 break;
|
Chris@16
|
101 }
|
Chris@16
|
102 }
|
Chris@16
|
103 }
|
Chris@16
|
104 while (it2e != it2e_end) {
|
Chris@16
|
105 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
|
Chris@16
|
106 if (static_cast<value_type>(*it2e) != value_type/*zero*/())
|
Chris@16
|
107 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
|
Chris@16
|
108 ++ it2e;
|
Chris@16
|
109 }
|
Chris@16
|
110 ++ it1, ++ it1e;
|
Chris@16
|
111 } else if (compare < 0) {
|
Chris@16
|
112 increment (it1, it1_end, - compare);
|
Chris@16
|
113 } else if (compare > 0) {
|
Chris@16
|
114 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
115 typename E::const_iterator2 it2e (it1e.begin ());
|
Chris@16
|
116 typename E::const_iterator2 it2e_end (it1e.end ());
|
Chris@16
|
117 #else
|
Chris@16
|
118 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@16
|
119 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
|
Chris@16
|
120 #endif
|
Chris@16
|
121 while (it2e != it2e_end) {
|
Chris@16
|
122 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
|
Chris@16
|
123 if (static_cast<value_type>(*it2e) != value_type/*zero*/())
|
Chris@16
|
124 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
|
Chris@16
|
125 ++ it2e;
|
Chris@16
|
126 }
|
Chris@16
|
127 ++ it1e;
|
Chris@16
|
128 }
|
Chris@16
|
129 }
|
Chris@16
|
130 while (it1e != it1e_end) {
|
Chris@16
|
131 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
132 typename E::const_iterator2 it2e (it1e.begin ());
|
Chris@16
|
133 typename E::const_iterator2 it2e_end (it1e.end ());
|
Chris@16
|
134 #else
|
Chris@16
|
135 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@16
|
136 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
|
Chris@16
|
137 #endif
|
Chris@16
|
138 while (it2e != it2e_end) {
|
Chris@16
|
139 if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
|
Chris@16
|
140 if (static_cast<value_type>(*it2e) != value_type/*zero*/())
|
Chris@16
|
141 index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
|
Chris@16
|
142 ++ it2e;
|
Chris@16
|
143 }
|
Chris@16
|
144 ++ it1e;
|
Chris@16
|
145 }
|
Chris@16
|
146 // ISSUE proxies require insert_element
|
Chris@16
|
147 for (size_type k = 0; k < index.size (); ++ k)
|
Chris@16
|
148 m (index [k].first, index [k].second) = value_type/*zero*/();
|
Chris@16
|
149 }
|
Chris@16
|
150 template<class M, class E, class R>
|
Chris@16
|
151 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
152 void make_conformant (M &m, const matrix_expression<E> &e, column_major_tag, R) {
|
Chris@16
|
153 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
Chris@16
|
154 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
Chris@16
|
155 typedef R conformant_restrict_type;
|
Chris@16
|
156 typedef typename M::size_type size_type;
|
Chris@16
|
157 typedef typename M::difference_type difference_type;
|
Chris@16
|
158 typedef typename M::value_type value_type;
|
Chris@16
|
159 std::vector<std::pair<size_type, size_type> > index;
|
Chris@16
|
160 typename M::iterator2 it2 (m.begin2 ());
|
Chris@16
|
161 typename M::iterator2 it2_end (m.end2 ());
|
Chris@16
|
162 typename E::const_iterator2 it2e (e ().begin2 ());
|
Chris@16
|
163 typename E::const_iterator2 it2e_end (e ().end2 ());
|
Chris@16
|
164 while (it2 != it2_end && it2e != it2e_end) {
|
Chris@16
|
165 difference_type compare = it2.index2 () - it2e.index2 ();
|
Chris@16
|
166 if (compare == 0) {
|
Chris@16
|
167 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
168 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
169 typename M::iterator1 it1_end (it2.end ());
|
Chris@16
|
170 typename E::const_iterator1 it1e (it2e.begin ());
|
Chris@16
|
171 typename E::const_iterator1 it1e_end (it2e.end ());
|
Chris@16
|
172 #else
|
Chris@16
|
173 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
174 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
|
Chris@16
|
175 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@16
|
176 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
|
Chris@16
|
177 #endif
|
Chris@16
|
178 if (it1 != it1_end && it1e != it1e_end) {
|
Chris@16
|
179 size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
|
Chris@16
|
180 while (true) {
|
Chris@101
|
181 difference_type compare2 = it1_index - it1e_index;
|
Chris@101
|
182 if (compare2 == 0) {
|
Chris@16
|
183 ++ it1, ++ it1e;
|
Chris@16
|
184 if (it1 != it1_end && it1e != it1e_end) {
|
Chris@16
|
185 it1_index = it1.index1 ();
|
Chris@16
|
186 it1e_index = it1e.index1 ();
|
Chris@16
|
187 } else
|
Chris@16
|
188 break;
|
Chris@101
|
189 } else if (compare2 < 0) {
|
Chris@101
|
190 increment (it1, it1_end, - compare2);
|
Chris@16
|
191 if (it1 != it1_end)
|
Chris@16
|
192 it1_index = it1.index1 ();
|
Chris@16
|
193 else
|
Chris@16
|
194 break;
|
Chris@101
|
195 } else if (compare2 > 0) {
|
Chris@16
|
196 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
|
Chris@16
|
197 if (static_cast<value_type>(*it1e) != value_type/*zero*/())
|
Chris@16
|
198 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
|
Chris@16
|
199 ++ it1e;
|
Chris@16
|
200 if (it1e != it1e_end)
|
Chris@16
|
201 it1e_index = it1e.index1 ();
|
Chris@16
|
202 else
|
Chris@16
|
203 break;
|
Chris@16
|
204 }
|
Chris@16
|
205 }
|
Chris@16
|
206 }
|
Chris@16
|
207 while (it1e != it1e_end) {
|
Chris@16
|
208 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
|
Chris@16
|
209 if (static_cast<value_type>(*it1e) != value_type/*zero*/())
|
Chris@16
|
210 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
|
Chris@16
|
211 ++ it1e;
|
Chris@16
|
212 }
|
Chris@16
|
213 ++ it2, ++ it2e;
|
Chris@16
|
214 } else if (compare < 0) {
|
Chris@16
|
215 increment (it2, it2_end, - compare);
|
Chris@16
|
216 } else if (compare > 0) {
|
Chris@16
|
217 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
218 typename E::const_iterator1 it1e (it2e.begin ());
|
Chris@16
|
219 typename E::const_iterator1 it1e_end (it2e.end ());
|
Chris@16
|
220 #else
|
Chris@16
|
221 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@16
|
222 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
|
Chris@16
|
223 #endif
|
Chris@16
|
224 while (it1e != it1e_end) {
|
Chris@16
|
225 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
|
Chris@16
|
226 if (static_cast<value_type>(*it1e) != value_type/*zero*/())
|
Chris@16
|
227 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
|
Chris@16
|
228 ++ it1e;
|
Chris@16
|
229 }
|
Chris@16
|
230 ++ it2e;
|
Chris@16
|
231 }
|
Chris@16
|
232 }
|
Chris@16
|
233 while (it2e != it2e_end) {
|
Chris@16
|
234 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
235 typename E::const_iterator1 it1e (it2e.begin ());
|
Chris@16
|
236 typename E::const_iterator1 it1e_end (it2e.end ());
|
Chris@16
|
237 #else
|
Chris@16
|
238 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@16
|
239 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
|
Chris@16
|
240 #endif
|
Chris@16
|
241 while (it1e != it1e_end) {
|
Chris@16
|
242 if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
|
Chris@16
|
243 if (static_cast<value_type>(*it1e) != value_type/*zero*/())
|
Chris@16
|
244 index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
|
Chris@16
|
245 ++ it1e;
|
Chris@16
|
246 }
|
Chris@16
|
247 ++ it2e;
|
Chris@16
|
248 }
|
Chris@16
|
249 // ISSUE proxies require insert_element
|
Chris@16
|
250 for (size_type k = 0; k < index.size (); ++ k)
|
Chris@16
|
251 m (index [k].first, index [k].second) = value_type/*zero*/();
|
Chris@16
|
252 }
|
Chris@16
|
253
|
Chris@16
|
254 }//namespace detail
|
Chris@16
|
255
|
Chris@16
|
256
|
Chris@16
|
257 // Explicitly iterating row major
|
Chris@16
|
258 template<template <class T1, class T2> class F, class M, class T>
|
Chris@16
|
259 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
260 void iterating_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
|
Chris@16
|
261 typedef F<typename M::iterator2::reference, T> functor_type;
|
Chris@16
|
262 typedef typename M::difference_type difference_type;
|
Chris@16
|
263 difference_type size1 (m.size1 ());
|
Chris@16
|
264 difference_type size2 (m.size2 ());
|
Chris@16
|
265 typename M::iterator1 it1 (m.begin1 ());
|
Chris@16
|
266 BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
|
Chris@16
|
267 while (-- size1 >= 0) {
|
Chris@16
|
268 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
269 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
270 #else
|
Chris@16
|
271 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
272 #endif
|
Chris@16
|
273 BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
|
Chris@16
|
274 difference_type temp_size2 (size2);
|
Chris@16
|
275 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
|
Chris@16
|
276 while (-- temp_size2 >= 0)
|
Chris@16
|
277 functor_type::apply (*it2, t), ++ it2;
|
Chris@16
|
278 #else
|
Chris@16
|
279 DD (temp_size2, 4, r, (functor_type::apply (*it2, t), ++ it2));
|
Chris@16
|
280 #endif
|
Chris@16
|
281 ++ it1;
|
Chris@16
|
282 }
|
Chris@16
|
283 }
|
Chris@16
|
284 // Explicitly iterating column major
|
Chris@16
|
285 template<template <class T1, class T2> class F, class M, class T>
|
Chris@16
|
286 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
287 void iterating_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
|
Chris@16
|
288 typedef F<typename M::iterator1::reference, T> functor_type;
|
Chris@16
|
289 typedef typename M::difference_type difference_type;
|
Chris@16
|
290 difference_type size2 (m.size2 ());
|
Chris@16
|
291 difference_type size1 (m.size1 ());
|
Chris@16
|
292 typename M::iterator2 it2 (m.begin2 ());
|
Chris@16
|
293 BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
|
Chris@16
|
294 while (-- size2 >= 0) {
|
Chris@16
|
295 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
296 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
297 #else
|
Chris@16
|
298 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
299 #endif
|
Chris@16
|
300 BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
|
Chris@16
|
301 difference_type temp_size1 (size1);
|
Chris@16
|
302 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
|
Chris@16
|
303 while (-- temp_size1 >= 0)
|
Chris@16
|
304 functor_type::apply (*it1, t), ++ it1;
|
Chris@16
|
305 #else
|
Chris@16
|
306 DD (temp_size1, 4, r, (functor_type::apply (*it1, t), ++ it1));
|
Chris@16
|
307 #endif
|
Chris@16
|
308 ++ it2;
|
Chris@16
|
309 }
|
Chris@16
|
310 }
|
Chris@16
|
311 // Explicitly indexing row major
|
Chris@16
|
312 template<template <class T1, class T2> class F, class M, class T>
|
Chris@16
|
313 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
314 void indexing_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
|
Chris@16
|
315 typedef F<typename M::reference, T> functor_type;
|
Chris@16
|
316 typedef typename M::size_type size_type;
|
Chris@16
|
317 size_type size1 (m.size1 ());
|
Chris@16
|
318 size_type size2 (m.size2 ());
|
Chris@16
|
319 for (size_type i = 0; i < size1; ++ i) {
|
Chris@16
|
320 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
|
Chris@16
|
321 for (size_type j = 0; j < size2; ++ j)
|
Chris@16
|
322 functor_type::apply (m (i, j), t);
|
Chris@16
|
323 #else
|
Chris@16
|
324 size_type j (0);
|
Chris@16
|
325 DD (size2, 4, r, (functor_type::apply (m (i, j), t), ++ j));
|
Chris@16
|
326 #endif
|
Chris@16
|
327 }
|
Chris@16
|
328 }
|
Chris@16
|
329 // Explicitly indexing column major
|
Chris@16
|
330 template<template <class T1, class T2> class F, class M, class T>
|
Chris@16
|
331 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
332 void indexing_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
|
Chris@16
|
333 typedef F<typename M::reference, T> functor_type;
|
Chris@16
|
334 typedef typename M::size_type size_type;
|
Chris@16
|
335 size_type size2 (m.size2 ());
|
Chris@16
|
336 size_type size1 (m.size1 ());
|
Chris@16
|
337 for (size_type j = 0; j < size2; ++ j) {
|
Chris@16
|
338 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
|
Chris@16
|
339 for (size_type i = 0; i < size1; ++ i)
|
Chris@16
|
340 functor_type::apply (m (i, j), t);
|
Chris@16
|
341 #else
|
Chris@16
|
342 size_type i (0);
|
Chris@16
|
343 DD (size1, 4, r, (functor_type::apply (m (i, j), t), ++ i));
|
Chris@16
|
344 #endif
|
Chris@16
|
345 }
|
Chris@16
|
346 }
|
Chris@16
|
347
|
Chris@16
|
348 // Dense (proxy) case
|
Chris@16
|
349 template<template <class T1, class T2> class F, class M, class T, class C>
|
Chris@16
|
350 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
351 void matrix_assign_scalar (M &m, const T &t, dense_proxy_tag, C) {
|
Chris@16
|
352 typedef C orientation_category;
|
Chris@16
|
353 #ifdef BOOST_UBLAS_USE_INDEXING
|
Chris@16
|
354 indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
|
Chris@16
|
355 #elif BOOST_UBLAS_USE_ITERATING
|
Chris@16
|
356 iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
|
Chris@16
|
357 #else
|
Chris@16
|
358 typedef typename M::size_type size_type;
|
Chris@16
|
359 size_type size1 (m.size1 ());
|
Chris@16
|
360 size_type size2 (m.size2 ());
|
Chris@16
|
361 if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
|
Chris@16
|
362 size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
|
Chris@16
|
363 iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
|
Chris@16
|
364 else
|
Chris@16
|
365 indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
|
Chris@16
|
366 #endif
|
Chris@16
|
367 }
|
Chris@16
|
368 // Packed (proxy) row major case
|
Chris@16
|
369 template<template <class T1, class T2> class F, class M, class T>
|
Chris@16
|
370 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
371 void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, row_major_tag) {
|
Chris@16
|
372 typedef F<typename M::iterator2::reference, T> functor_type;
|
Chris@16
|
373 typedef typename M::difference_type difference_type;
|
Chris@16
|
374 typename M::iterator1 it1 (m.begin1 ());
|
Chris@16
|
375 difference_type size1 (m.end1 () - it1);
|
Chris@16
|
376 while (-- size1 >= 0) {
|
Chris@16
|
377 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
378 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
379 difference_type size2 (it1.end () - it2);
|
Chris@16
|
380 #else
|
Chris@16
|
381 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
382 difference_type size2 (end (it1, iterator1_tag ()) - it2);
|
Chris@16
|
383 #endif
|
Chris@16
|
384 while (-- size2 >= 0)
|
Chris@16
|
385 functor_type::apply (*it2, t), ++ it2;
|
Chris@16
|
386 ++ it1;
|
Chris@16
|
387 }
|
Chris@16
|
388 }
|
Chris@16
|
389 // Packed (proxy) column major case
|
Chris@16
|
390 template<template <class T1, class T2> class F, class M, class T>
|
Chris@16
|
391 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
392 void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, column_major_tag) {
|
Chris@16
|
393 typedef F<typename M::iterator1::reference, T> functor_type;
|
Chris@16
|
394 typedef typename M::difference_type difference_type;
|
Chris@16
|
395 typename M::iterator2 it2 (m.begin2 ());
|
Chris@16
|
396 difference_type size2 (m.end2 () - it2);
|
Chris@16
|
397 while (-- size2 >= 0) {
|
Chris@16
|
398 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
399 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
400 difference_type size1 (it2.end () - it1);
|
Chris@16
|
401 #else
|
Chris@16
|
402 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
403 difference_type size1 (end (it2, iterator2_tag ()) - it1);
|
Chris@16
|
404 #endif
|
Chris@16
|
405 while (-- size1 >= 0)
|
Chris@16
|
406 functor_type::apply (*it1, t), ++ it1;
|
Chris@16
|
407 ++ it2;
|
Chris@16
|
408 }
|
Chris@16
|
409 }
|
Chris@16
|
410 // Sparse (proxy) row major case
|
Chris@16
|
411 template<template <class T1, class T2> class F, class M, class T>
|
Chris@16
|
412 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
413 void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, row_major_tag) {
|
Chris@16
|
414 typedef F<typename M::iterator2::reference, T> functor_type;
|
Chris@16
|
415 typename M::iterator1 it1 (m.begin1 ());
|
Chris@16
|
416 typename M::iterator1 it1_end (m.end1 ());
|
Chris@16
|
417 while (it1 != it1_end) {
|
Chris@16
|
418 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
419 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
420 typename M::iterator2 it2_end (it1.end ());
|
Chris@16
|
421 #else
|
Chris@16
|
422 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
423 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
|
Chris@16
|
424 #endif
|
Chris@16
|
425 while (it2 != it2_end)
|
Chris@16
|
426 functor_type::apply (*it2, t), ++ it2;
|
Chris@16
|
427 ++ it1;
|
Chris@16
|
428 }
|
Chris@16
|
429 }
|
Chris@16
|
430 // Sparse (proxy) column major case
|
Chris@16
|
431 template<template <class T1, class T2> class F, class M, class T>
|
Chris@16
|
432 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
433 void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, column_major_tag) {
|
Chris@16
|
434 typedef F<typename M::iterator1::reference, T> functor_type;
|
Chris@16
|
435 typename M::iterator2 it2 (m.begin2 ());
|
Chris@16
|
436 typename M::iterator2 it2_end (m.end2 ());
|
Chris@16
|
437 while (it2 != it2_end) {
|
Chris@16
|
438 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
439 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
440 typename M::iterator1 it1_end (it2.end ());
|
Chris@16
|
441 #else
|
Chris@16
|
442 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
443 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
|
Chris@16
|
444 #endif
|
Chris@16
|
445 while (it1 != it1_end)
|
Chris@16
|
446 functor_type::apply (*it1, t), ++ it1;
|
Chris@16
|
447 ++ it2;
|
Chris@16
|
448 }
|
Chris@16
|
449 }
|
Chris@16
|
450
|
Chris@16
|
451 // Dispatcher
|
Chris@16
|
452 template<template <class T1, class T2> class F, class M, class T>
|
Chris@16
|
453 BOOST_UBLAS_INLINE
|
Chris@16
|
454 void matrix_assign_scalar (M &m, const T &t) {
|
Chris@16
|
455 typedef typename M::storage_category storage_category;
|
Chris@16
|
456 typedef typename M::orientation_category orientation_category;
|
Chris@16
|
457 matrix_assign_scalar<F> (m, t, storage_category (), orientation_category ());
|
Chris@16
|
458 }
|
Chris@16
|
459
|
Chris@16
|
460 template<class SC, bool COMPUTED, class RI1, class RI2>
|
Chris@16
|
461 struct matrix_assign_traits {
|
Chris@16
|
462 typedef SC storage_category;
|
Chris@16
|
463 };
|
Chris@16
|
464
|
Chris@16
|
465 template<bool COMPUTED>
|
Chris@16
|
466 struct matrix_assign_traits<dense_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
|
Chris@16
|
467 typedef packed_tag storage_category;
|
Chris@16
|
468 };
|
Chris@16
|
469 template<>
|
Chris@16
|
470 struct matrix_assign_traits<dense_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
|
Chris@16
|
471 typedef sparse_tag storage_category;
|
Chris@16
|
472 };
|
Chris@16
|
473 template<>
|
Chris@16
|
474 struct matrix_assign_traits<dense_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
|
Chris@16
|
475 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
476 };
|
Chris@16
|
477
|
Chris@16
|
478 template<bool COMPUTED>
|
Chris@16
|
479 struct matrix_assign_traits<dense_proxy_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
|
Chris@16
|
480 typedef packed_proxy_tag storage_category;
|
Chris@16
|
481 };
|
Chris@16
|
482 template<bool COMPUTED>
|
Chris@16
|
483 struct matrix_assign_traits<dense_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
|
Chris@16
|
484 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
485 };
|
Chris@16
|
486
|
Chris@16
|
487 template<>
|
Chris@16
|
488 struct matrix_assign_traits<packed_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
|
Chris@16
|
489 typedef sparse_tag storage_category;
|
Chris@16
|
490 };
|
Chris@16
|
491 template<>
|
Chris@16
|
492 struct matrix_assign_traits<packed_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
|
Chris@16
|
493 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
494 };
|
Chris@16
|
495
|
Chris@16
|
496 template<bool COMPUTED>
|
Chris@16
|
497 struct matrix_assign_traits<packed_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
|
Chris@16
|
498 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
499 };
|
Chris@16
|
500
|
Chris@16
|
501 template<>
|
Chris@16
|
502 struct matrix_assign_traits<sparse_tag, true, dense_random_access_iterator_tag, dense_random_access_iterator_tag> {
|
Chris@16
|
503 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
504 };
|
Chris@16
|
505 template<>
|
Chris@16
|
506 struct matrix_assign_traits<sparse_tag, true, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
|
Chris@16
|
507 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
508 };
|
Chris@16
|
509 template<>
|
Chris@16
|
510 struct matrix_assign_traits<sparse_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
|
Chris@16
|
511 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
512 };
|
Chris@16
|
513
|
Chris@16
|
514 // Explicitly iterating row major
|
Chris@16
|
515 template<template <class T1, class T2> class F, class M, class E>
|
Chris@16
|
516 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
517 void iterating_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
|
Chris@16
|
518 typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
|
Chris@16
|
519 typedef typename M::difference_type difference_type;
|
Chris@16
|
520 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
|
Chris@16
|
521 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
|
Chris@16
|
522 typename M::iterator1 it1 (m.begin1 ());
|
Chris@16
|
523 BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
|
Chris@16
|
524 typename E::const_iterator1 it1e (e ().begin1 ());
|
Chris@16
|
525 BOOST_UBLAS_CHECK (size2 == 0 || e ().end1 () - it1e == size1, bad_size ());
|
Chris@16
|
526 while (-- size1 >= 0) {
|
Chris@16
|
527 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
528 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
529 typename E::const_iterator2 it2e (it1e.begin ());
|
Chris@16
|
530 #else
|
Chris@16
|
531 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
532 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@16
|
533 #endif
|
Chris@16
|
534 BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
|
Chris@16
|
535 BOOST_UBLAS_CHECK (it1e.end () - it2e == size2, bad_size ());
|
Chris@16
|
536 difference_type temp_size2 (size2);
|
Chris@16
|
537 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
|
Chris@16
|
538 while (-- temp_size2 >= 0)
|
Chris@16
|
539 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
|
Chris@16
|
540 #else
|
Chris@16
|
541 DD (temp_size2, 2, r, (functor_type::apply (*it2, *it2e), ++ it2, ++ it2e));
|
Chris@16
|
542 #endif
|
Chris@16
|
543 ++ it1, ++ it1e;
|
Chris@16
|
544 }
|
Chris@16
|
545 }
|
Chris@16
|
546 // Explicitly iterating column major
|
Chris@16
|
547 template<template <class T1, class T2> class F, class M, class E>
|
Chris@16
|
548 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
549 void iterating_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
|
Chris@16
|
550 typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
|
Chris@16
|
551 typedef typename M::difference_type difference_type;
|
Chris@16
|
552 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
|
Chris@16
|
553 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
|
Chris@16
|
554 typename M::iterator2 it2 (m.begin2 ());
|
Chris@16
|
555 BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
|
Chris@16
|
556 typename E::const_iterator2 it2e (e ().begin2 ());
|
Chris@16
|
557 BOOST_UBLAS_CHECK (size1 == 0 || e ().end2 () - it2e == size2, bad_size ());
|
Chris@16
|
558 while (-- size2 >= 0) {
|
Chris@16
|
559 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
560 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
561 typename E::const_iterator1 it1e (it2e.begin ());
|
Chris@16
|
562 #else
|
Chris@16
|
563 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
564 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@16
|
565 #endif
|
Chris@16
|
566 BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
|
Chris@16
|
567 BOOST_UBLAS_CHECK (it2e.end () - it1e == size1, bad_size ());
|
Chris@16
|
568 difference_type temp_size1 (size1);
|
Chris@16
|
569 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
|
Chris@16
|
570 while (-- temp_size1 >= 0)
|
Chris@16
|
571 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
|
Chris@16
|
572 #else
|
Chris@16
|
573 DD (temp_size1, 2, r, (functor_type::apply (*it1, *it1e), ++ it1, ++ it1e));
|
Chris@16
|
574 #endif
|
Chris@16
|
575 ++ it2, ++ it2e;
|
Chris@16
|
576 }
|
Chris@16
|
577 }
|
Chris@16
|
578 // Explicitly indexing row major
|
Chris@16
|
579 template<template <class T1, class T2> class F, class M, class E>
|
Chris@16
|
580 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
581 void indexing_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
|
Chris@16
|
582 typedef F<typename M::reference, typename E::value_type> functor_type;
|
Chris@16
|
583 typedef typename M::size_type size_type;
|
Chris@16
|
584 size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
|
Chris@16
|
585 size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
|
Chris@16
|
586 for (size_type i = 0; i < size1; ++ i) {
|
Chris@16
|
587 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
|
Chris@16
|
588 for (size_type j = 0; j < size2; ++ j)
|
Chris@16
|
589 functor_type::apply (m (i, j), e () (i, j));
|
Chris@16
|
590 #else
|
Chris@16
|
591 size_type j (0);
|
Chris@16
|
592 DD (size2, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ j));
|
Chris@16
|
593 #endif
|
Chris@16
|
594 }
|
Chris@16
|
595 }
|
Chris@16
|
596 // Explicitly indexing column major
|
Chris@16
|
597 template<template <class T1, class T2> class F, class M, class E>
|
Chris@16
|
598 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
599 void indexing_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
|
Chris@16
|
600 typedef F<typename M::reference, typename E::value_type> functor_type;
|
Chris@16
|
601 typedef typename M::size_type size_type;
|
Chris@16
|
602 size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
|
Chris@16
|
603 size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
|
Chris@16
|
604 for (size_type j = 0; j < size2; ++ j) {
|
Chris@16
|
605 #ifndef BOOST_UBLAS_USE_DUFF_DEVICE
|
Chris@16
|
606 for (size_type i = 0; i < size1; ++ i)
|
Chris@16
|
607 functor_type::apply (m (i, j), e () (i, j));
|
Chris@16
|
608 #else
|
Chris@16
|
609 size_type i (0);
|
Chris@16
|
610 DD (size1, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ i));
|
Chris@16
|
611 #endif
|
Chris@16
|
612 }
|
Chris@16
|
613 }
|
Chris@16
|
614
|
Chris@16
|
615 // Dense (proxy) case
|
Chris@16
|
616 template<template <class T1, class T2> class F, class R, class M, class E, class C>
|
Chris@16
|
617 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
618 void matrix_assign (M &m, const matrix_expression<E> &e, dense_proxy_tag, C) {
|
Chris@16
|
619 // R unnecessary, make_conformant not required
|
Chris@16
|
620 typedef C orientation_category;
|
Chris@16
|
621 #ifdef BOOST_UBLAS_USE_INDEXING
|
Chris@16
|
622 indexing_matrix_assign<F> (m, e, orientation_category ());
|
Chris@16
|
623 #elif BOOST_UBLAS_USE_ITERATING
|
Chris@16
|
624 iterating_matrix_assign<F> (m, e, orientation_category ());
|
Chris@16
|
625 #else
|
Chris@16
|
626 typedef typename M::difference_type difference_type;
|
Chris@16
|
627 size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
|
Chris@16
|
628 size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
|
Chris@16
|
629 if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
|
Chris@16
|
630 size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
|
Chris@16
|
631 iterating_matrix_assign<F> (m, e, orientation_category ());
|
Chris@16
|
632 else
|
Chris@16
|
633 indexing_matrix_assign<F> (m, e, orientation_category ());
|
Chris@16
|
634 #endif
|
Chris@16
|
635 }
|
Chris@16
|
636 // Packed (proxy) row major case
|
Chris@16
|
637 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
638 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
639 void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
|
Chris@16
|
640 typedef typename matrix_traits<E>::value_type expr_value_type;
|
Chris@16
|
641 typedef F<typename M::iterator2::reference, expr_value_type> functor_type;
|
Chris@16
|
642 // R unnecessary, make_conformant not required
|
Chris@16
|
643 typedef typename M::difference_type difference_type;
|
Chris@101
|
644
|
Chris@16
|
645 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
Chris@16
|
646 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
Chris@101
|
647
|
Chris@16
|
648 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@101
|
649 typedef typename M::value_type value_type;
|
Chris@16
|
650 matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
|
Chris@16
|
651 indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
|
Chris@16
|
652 indexing_matrix_assign<F> (cm, e, row_major_tag ());
|
Chris@16
|
653 #endif
|
Chris@16
|
654 typename M::iterator1 it1 (m.begin1 ());
|
Chris@16
|
655 typename M::iterator1 it1_end (m.end1 ());
|
Chris@16
|
656 typename E::const_iterator1 it1e (e ().begin1 ());
|
Chris@16
|
657 typename E::const_iterator1 it1e_end (e ().end1 ());
|
Chris@16
|
658 difference_type it1_size (it1_end - it1);
|
Chris@16
|
659 difference_type it1e_size (it1e_end - it1e);
|
Chris@16
|
660 difference_type diff1 (0);
|
Chris@16
|
661 if (it1_size > 0 && it1e_size > 0)
|
Chris@16
|
662 diff1 = it1.index1 () - it1e.index1 ();
|
Chris@16
|
663 if (diff1 != 0) {
|
Chris@16
|
664 difference_type size1 = (std::min) (diff1, it1e_size);
|
Chris@16
|
665 if (size1 > 0) {
|
Chris@16
|
666 it1e += size1;
|
Chris@16
|
667 it1e_size -= size1;
|
Chris@16
|
668 diff1 -= size1;
|
Chris@16
|
669 }
|
Chris@16
|
670 size1 = (std::min) (- diff1, it1_size);
|
Chris@16
|
671 if (size1 > 0) {
|
Chris@16
|
672 it1_size -= size1;
|
Chris@16
|
673 if (!functor_type::computed) {
|
Chris@16
|
674 while (-- size1 >= 0) { // zeroing
|
Chris@16
|
675 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
676 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
677 typename M::iterator2 it2_end (it1.end ());
|
Chris@16
|
678 #else
|
Chris@16
|
679 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
680 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
|
Chris@16
|
681 #endif
|
Chris@16
|
682 difference_type size2 (it2_end - it2);
|
Chris@16
|
683 while (-- size2 >= 0)
|
Chris@16
|
684 functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
|
Chris@16
|
685 ++ it1;
|
Chris@16
|
686 }
|
Chris@16
|
687 } else {
|
Chris@16
|
688 it1 += size1;
|
Chris@16
|
689 }
|
Chris@16
|
690 diff1 += size1;
|
Chris@16
|
691 }
|
Chris@16
|
692 }
|
Chris@16
|
693 difference_type size1 ((std::min) (it1_size, it1e_size));
|
Chris@16
|
694 it1_size -= size1;
|
Chris@16
|
695 it1e_size -= size1;
|
Chris@16
|
696 while (-- size1 >= 0) {
|
Chris@16
|
697 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
698 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
699 typename M::iterator2 it2_end (it1.end ());
|
Chris@16
|
700 typename E::const_iterator2 it2e (it1e.begin ());
|
Chris@16
|
701 typename E::const_iterator2 it2e_end (it1e.end ());
|
Chris@16
|
702 #else
|
Chris@16
|
703 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
704 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
|
Chris@16
|
705 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@16
|
706 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
|
Chris@16
|
707 #endif
|
Chris@16
|
708 difference_type it2_size (it2_end - it2);
|
Chris@16
|
709 difference_type it2e_size (it2e_end - it2e);
|
Chris@16
|
710 difference_type diff2 (0);
|
Chris@16
|
711 if (it2_size > 0 && it2e_size > 0) {
|
Chris@16
|
712 diff2 = it2.index2 () - it2e.index2 ();
|
Chris@16
|
713 difference_type size2 = (std::min) (diff2, it2e_size);
|
Chris@16
|
714 if (size2 > 0) {
|
Chris@16
|
715 it2e += size2;
|
Chris@16
|
716 it2e_size -= size2;
|
Chris@16
|
717 diff2 -= size2;
|
Chris@16
|
718 }
|
Chris@16
|
719 size2 = (std::min) (- diff2, it2_size);
|
Chris@16
|
720 if (size2 > 0) {
|
Chris@16
|
721 it2_size -= size2;
|
Chris@16
|
722 if (!functor_type::computed) {
|
Chris@16
|
723 while (-- size2 >= 0) // zeroing
|
Chris@16
|
724 functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
|
Chris@16
|
725 } else {
|
Chris@16
|
726 it2 += size2;
|
Chris@16
|
727 }
|
Chris@16
|
728 diff2 += size2;
|
Chris@16
|
729 }
|
Chris@16
|
730 }
|
Chris@16
|
731 difference_type size2 ((std::min) (it2_size, it2e_size));
|
Chris@16
|
732 it2_size -= size2;
|
Chris@16
|
733 it2e_size -= size2;
|
Chris@16
|
734 while (-- size2 >= 0)
|
Chris@16
|
735 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
|
Chris@16
|
736 size2 = it2_size;
|
Chris@16
|
737 if (!functor_type::computed) {
|
Chris@16
|
738 while (-- size2 >= 0) // zeroing
|
Chris@16
|
739 functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
|
Chris@16
|
740 } else {
|
Chris@16
|
741 it2 += size2;
|
Chris@16
|
742 }
|
Chris@16
|
743 ++ it1, ++ it1e;
|
Chris@16
|
744 }
|
Chris@16
|
745 size1 = it1_size;
|
Chris@16
|
746 if (!functor_type::computed) {
|
Chris@16
|
747 while (-- size1 >= 0) { // zeroing
|
Chris@16
|
748 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
749 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
750 typename M::iterator2 it2_end (it1.end ());
|
Chris@16
|
751 #else
|
Chris@16
|
752 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
753 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
|
Chris@16
|
754 #endif
|
Chris@16
|
755 difference_type size2 (it2_end - it2);
|
Chris@16
|
756 while (-- size2 >= 0)
|
Chris@16
|
757 functor_type::apply (*it2, expr_value_type/*zero*/()), ++ it2;
|
Chris@16
|
758 ++ it1;
|
Chris@16
|
759 }
|
Chris@16
|
760 } else {
|
Chris@16
|
761 it1 += size1;
|
Chris@16
|
762 }
|
Chris@16
|
763 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
764 if (! disable_type_check<bool>::value)
|
Chris@16
|
765 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
|
Chris@16
|
766 #endif
|
Chris@16
|
767 }
|
Chris@16
|
768 // Packed (proxy) column major case
|
Chris@16
|
769 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
770 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
771 void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
|
Chris@16
|
772 typedef typename matrix_traits<E>::value_type expr_value_type;
|
Chris@16
|
773 typedef F<typename M::iterator1::reference, expr_value_type> functor_type;
|
Chris@16
|
774 // R unnecessary, make_conformant not required
|
Chris@16
|
775 typedef typename M::difference_type difference_type;
|
Chris@101
|
776
|
Chris@16
|
777 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
Chris@16
|
778 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
Chris@101
|
779
|
Chris@16
|
780 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@101
|
781 typedef typename M::value_type value_type;
|
Chris@16
|
782 matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
|
Chris@16
|
783 indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
|
Chris@16
|
784 indexing_matrix_assign<F> (cm, e, column_major_tag ());
|
Chris@16
|
785 #endif
|
Chris@16
|
786 typename M::iterator2 it2 (m.begin2 ());
|
Chris@16
|
787 typename M::iterator2 it2_end (m.end2 ());
|
Chris@16
|
788 typename E::const_iterator2 it2e (e ().begin2 ());
|
Chris@16
|
789 typename E::const_iterator2 it2e_end (e ().end2 ());
|
Chris@16
|
790 difference_type it2_size (it2_end - it2);
|
Chris@16
|
791 difference_type it2e_size (it2e_end - it2e);
|
Chris@16
|
792 difference_type diff2 (0);
|
Chris@16
|
793 if (it2_size > 0 && it2e_size > 0)
|
Chris@16
|
794 diff2 = it2.index2 () - it2e.index2 ();
|
Chris@16
|
795 if (diff2 != 0) {
|
Chris@16
|
796 difference_type size2 = (std::min) (diff2, it2e_size);
|
Chris@16
|
797 if (size2 > 0) {
|
Chris@16
|
798 it2e += size2;
|
Chris@16
|
799 it2e_size -= size2;
|
Chris@16
|
800 diff2 -= size2;
|
Chris@16
|
801 }
|
Chris@16
|
802 size2 = (std::min) (- diff2, it2_size);
|
Chris@16
|
803 if (size2 > 0) {
|
Chris@16
|
804 it2_size -= size2;
|
Chris@16
|
805 if (!functor_type::computed) {
|
Chris@16
|
806 while (-- size2 >= 0) { // zeroing
|
Chris@16
|
807 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
808 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
809 typename M::iterator1 it1_end (it2.end ());
|
Chris@16
|
810 #else
|
Chris@16
|
811 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
812 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
|
Chris@16
|
813 #endif
|
Chris@16
|
814 difference_type size1 (it1_end - it1);
|
Chris@16
|
815 while (-- size1 >= 0)
|
Chris@16
|
816 functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
|
Chris@16
|
817 ++ it2;
|
Chris@16
|
818 }
|
Chris@16
|
819 } else {
|
Chris@16
|
820 it2 += size2;
|
Chris@16
|
821 }
|
Chris@16
|
822 diff2 += size2;
|
Chris@16
|
823 }
|
Chris@16
|
824 }
|
Chris@16
|
825 difference_type size2 ((std::min) (it2_size, it2e_size));
|
Chris@16
|
826 it2_size -= size2;
|
Chris@16
|
827 it2e_size -= size2;
|
Chris@16
|
828 while (-- size2 >= 0) {
|
Chris@16
|
829 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
830 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
831 typename M::iterator1 it1_end (it2.end ());
|
Chris@16
|
832 typename E::const_iterator1 it1e (it2e.begin ());
|
Chris@16
|
833 typename E::const_iterator1 it1e_end (it2e.end ());
|
Chris@16
|
834 #else
|
Chris@16
|
835 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
836 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
|
Chris@16
|
837 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@16
|
838 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
|
Chris@16
|
839 #endif
|
Chris@16
|
840 difference_type it1_size (it1_end - it1);
|
Chris@16
|
841 difference_type it1e_size (it1e_end - it1e);
|
Chris@16
|
842 difference_type diff1 (0);
|
Chris@16
|
843 if (it1_size > 0 && it1e_size > 0) {
|
Chris@16
|
844 diff1 = it1.index1 () - it1e.index1 ();
|
Chris@16
|
845 difference_type size1 = (std::min) (diff1, it1e_size);
|
Chris@16
|
846 if (size1 > 0) {
|
Chris@16
|
847 it1e += size1;
|
Chris@16
|
848 it1e_size -= size1;
|
Chris@16
|
849 diff1 -= size1;
|
Chris@16
|
850 }
|
Chris@16
|
851 size1 = (std::min) (- diff1, it1_size);
|
Chris@16
|
852 if (size1 > 0) {
|
Chris@16
|
853 it1_size -= size1;
|
Chris@16
|
854 if (!functor_type::computed) {
|
Chris@16
|
855 while (-- size1 >= 0) // zeroing
|
Chris@16
|
856 functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
|
Chris@16
|
857 } else {
|
Chris@16
|
858 it1 += size1;
|
Chris@16
|
859 }
|
Chris@16
|
860 diff1 += size1;
|
Chris@16
|
861 }
|
Chris@16
|
862 }
|
Chris@16
|
863 difference_type size1 ((std::min) (it1_size, it1e_size));
|
Chris@16
|
864 it1_size -= size1;
|
Chris@16
|
865 it1e_size -= size1;
|
Chris@16
|
866 while (-- size1 >= 0)
|
Chris@16
|
867 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
|
Chris@16
|
868 size1 = it1_size;
|
Chris@16
|
869 if (!functor_type::computed) {
|
Chris@16
|
870 while (-- size1 >= 0) // zeroing
|
Chris@16
|
871 functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
|
Chris@16
|
872 } else {
|
Chris@16
|
873 it1 += size1;
|
Chris@16
|
874 }
|
Chris@16
|
875 ++ it2, ++ it2e;
|
Chris@16
|
876 }
|
Chris@16
|
877 size2 = it2_size;
|
Chris@16
|
878 if (!functor_type::computed) {
|
Chris@16
|
879 while (-- size2 >= 0) { // zeroing
|
Chris@16
|
880 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
881 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
882 typename M::iterator1 it1_end (it2.end ());
|
Chris@16
|
883 #else
|
Chris@16
|
884 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
885 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
|
Chris@16
|
886 #endif
|
Chris@16
|
887 difference_type size1 (it1_end - it1);
|
Chris@16
|
888 while (-- size1 >= 0)
|
Chris@16
|
889 functor_type::apply (*it1, expr_value_type/*zero*/()), ++ it1;
|
Chris@16
|
890 ++ it2;
|
Chris@16
|
891 }
|
Chris@16
|
892 } else {
|
Chris@16
|
893 it2 += size2;
|
Chris@16
|
894 }
|
Chris@16
|
895 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
896 if (! disable_type_check<bool>::value)
|
Chris@16
|
897 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
|
Chris@16
|
898 #endif
|
Chris@16
|
899 }
|
Chris@16
|
900 // Sparse row major case
|
Chris@16
|
901 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
902 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
903 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, row_major_tag) {
|
Chris@16
|
904 typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
|
Chris@16
|
905 // R unnecessary, make_conformant not required
|
Chris@16
|
906 BOOST_STATIC_ASSERT ((!functor_type::computed));
|
Chris@16
|
907 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
Chris@16
|
908 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
Chris@16
|
909 typedef typename M::value_type value_type;
|
Chris@16
|
910 // Sparse type has no numeric constraints to check
|
Chris@16
|
911
|
Chris@16
|
912 m.clear ();
|
Chris@16
|
913 typename E::const_iterator1 it1e (e ().begin1 ());
|
Chris@16
|
914 typename E::const_iterator1 it1e_end (e ().end1 ());
|
Chris@16
|
915 while (it1e != it1e_end) {
|
Chris@16
|
916 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
917 typename E::const_iterator2 it2e (it1e.begin ());
|
Chris@16
|
918 typename E::const_iterator2 it2e_end (it1e.end ());
|
Chris@16
|
919 #else
|
Chris@16
|
920 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@16
|
921 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
|
Chris@16
|
922 #endif
|
Chris@16
|
923 while (it2e != it2e_end) {
|
Chris@16
|
924 value_type t (*it2e);
|
Chris@16
|
925 if (t != value_type/*zero*/())
|
Chris@16
|
926 m.insert_element (it2e.index1 (), it2e.index2 (), t);
|
Chris@16
|
927 ++ it2e;
|
Chris@16
|
928 }
|
Chris@16
|
929 ++ it1e;
|
Chris@16
|
930 }
|
Chris@16
|
931 }
|
Chris@16
|
932 // Sparse column major case
|
Chris@16
|
933 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
934 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
935 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, column_major_tag) {
|
Chris@16
|
936 typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
|
Chris@16
|
937 // R unnecessary, make_conformant not required
|
Chris@16
|
938 BOOST_STATIC_ASSERT ((!functor_type::computed));
|
Chris@16
|
939 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
Chris@16
|
940 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
Chris@16
|
941 typedef typename M::value_type value_type;
|
Chris@16
|
942 // Sparse type has no numeric constraints to check
|
Chris@16
|
943
|
Chris@16
|
944 m.clear ();
|
Chris@16
|
945 typename E::const_iterator2 it2e (e ().begin2 ());
|
Chris@16
|
946 typename E::const_iterator2 it2e_end (e ().end2 ());
|
Chris@16
|
947 while (it2e != it2e_end) {
|
Chris@16
|
948 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
949 typename E::const_iterator1 it1e (it2e.begin ());
|
Chris@16
|
950 typename E::const_iterator1 it1e_end (it2e.end ());
|
Chris@16
|
951 #else
|
Chris@16
|
952 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@16
|
953 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
|
Chris@16
|
954 #endif
|
Chris@16
|
955 while (it1e != it1e_end) {
|
Chris@16
|
956 value_type t (*it1e);
|
Chris@16
|
957 if (t != value_type/*zero*/())
|
Chris@16
|
958 m.insert_element (it1e.index1 (), it1e.index2 (), t);
|
Chris@16
|
959 ++ it1e;
|
Chris@16
|
960 }
|
Chris@16
|
961 ++ it2e;
|
Chris@16
|
962 }
|
Chris@16
|
963 }
|
Chris@16
|
964 // Sparse proxy or functional row major case
|
Chris@16
|
965 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
966 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
967 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
|
Chris@16
|
968 typedef typename matrix_traits<E>::value_type expr_value_type;
|
Chris@16
|
969 typedef F<typename M::iterator2::reference, expr_value_type> functor_type;
|
Chris@16
|
970 typedef R conformant_restrict_type;
|
Chris@16
|
971 typedef typename M::size_type size_type;
|
Chris@16
|
972 typedef typename M::difference_type difference_type;
|
Chris@101
|
973
|
Chris@16
|
974 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
Chris@16
|
975 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
Chris@101
|
976
|
Chris@16
|
977 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@101
|
978 typedef typename M::value_type value_type;
|
Chris@16
|
979 matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
|
Chris@16
|
980 indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
|
Chris@16
|
981 indexing_matrix_assign<F> (cm, e, row_major_tag ());
|
Chris@16
|
982 #endif
|
Chris@16
|
983 detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
|
Chris@16
|
984
|
Chris@16
|
985 typename M::iterator1 it1 (m.begin1 ());
|
Chris@16
|
986 typename M::iterator1 it1_end (m.end1 ());
|
Chris@16
|
987 typename E::const_iterator1 it1e (e ().begin1 ());
|
Chris@16
|
988 typename E::const_iterator1 it1e_end (e ().end1 ());
|
Chris@16
|
989 while (it1 != it1_end && it1e != it1e_end) {
|
Chris@16
|
990 difference_type compare = it1.index1 () - it1e.index1 ();
|
Chris@16
|
991 if (compare == 0) {
|
Chris@16
|
992 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
993 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
994 typename M::iterator2 it2_end (it1.end ());
|
Chris@16
|
995 typename E::const_iterator2 it2e (it1e.begin ());
|
Chris@16
|
996 typename E::const_iterator2 it2e_end (it1e.end ());
|
Chris@16
|
997 #else
|
Chris@16
|
998 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
999 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
|
Chris@16
|
1000 typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@16
|
1001 typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
|
Chris@16
|
1002 #endif
|
Chris@16
|
1003 if (it2 != it2_end && it2e != it2e_end) {
|
Chris@16
|
1004 size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
|
Chris@16
|
1005 while (true) {
|
Chris@101
|
1006 difference_type compare2 = it2_index - it2e_index;
|
Chris@101
|
1007 if (compare2 == 0) {
|
Chris@16
|
1008 functor_type::apply (*it2, *it2e);
|
Chris@16
|
1009 ++ it2, ++ it2e;
|
Chris@16
|
1010 if (it2 != it2_end && it2e != it2e_end) {
|
Chris@16
|
1011 it2_index = it2.index2 ();
|
Chris@16
|
1012 it2e_index = it2e.index2 ();
|
Chris@16
|
1013 } else
|
Chris@16
|
1014 break;
|
Chris@101
|
1015 } else if (compare2 < 0) {
|
Chris@16
|
1016 if (!functor_type::computed) {
|
Chris@16
|
1017 functor_type::apply (*it2, expr_value_type/*zero*/());
|
Chris@16
|
1018 ++ it2;
|
Chris@16
|
1019 } else
|
Chris@101
|
1020 increment (it2, it2_end, - compare2);
|
Chris@16
|
1021 if (it2 != it2_end)
|
Chris@16
|
1022 it2_index = it2.index2 ();
|
Chris@16
|
1023 else
|
Chris@16
|
1024 break;
|
Chris@101
|
1025 } else if (compare2 > 0) {
|
Chris@101
|
1026 increment (it2e, it2e_end, compare2);
|
Chris@16
|
1027 if (it2e != it2e_end)
|
Chris@16
|
1028 it2e_index = it2e.index2 ();
|
Chris@16
|
1029 else
|
Chris@16
|
1030 break;
|
Chris@16
|
1031 }
|
Chris@16
|
1032 }
|
Chris@16
|
1033 }
|
Chris@16
|
1034 if (!functor_type::computed) {
|
Chris@16
|
1035 while (it2 != it2_end) { // zeroing
|
Chris@16
|
1036 functor_type::apply (*it2, expr_value_type/*zero*/());
|
Chris@16
|
1037 ++ it2;
|
Chris@16
|
1038 }
|
Chris@16
|
1039 } else {
|
Chris@16
|
1040 it2 = it2_end;
|
Chris@16
|
1041 }
|
Chris@16
|
1042 ++ it1, ++ it1e;
|
Chris@16
|
1043 } else if (compare < 0) {
|
Chris@16
|
1044 if (!functor_type::computed) {
|
Chris@16
|
1045 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1046 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
1047 typename M::iterator2 it2_end (it1.end ());
|
Chris@16
|
1048 #else
|
Chris@16
|
1049 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
1050 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
|
Chris@16
|
1051 #endif
|
Chris@16
|
1052 while (it2 != it2_end) { // zeroing
|
Chris@16
|
1053 functor_type::apply (*it2, expr_value_type/*zero*/());
|
Chris@16
|
1054 ++ it2;
|
Chris@16
|
1055 }
|
Chris@16
|
1056 ++ it1;
|
Chris@16
|
1057 } else {
|
Chris@16
|
1058 increment (it1, it1_end, - compare);
|
Chris@16
|
1059 }
|
Chris@16
|
1060 } else if (compare > 0) {
|
Chris@16
|
1061 increment (it1e, it1e_end, compare);
|
Chris@16
|
1062 }
|
Chris@16
|
1063 }
|
Chris@16
|
1064 if (!functor_type::computed) {
|
Chris@16
|
1065 while (it1 != it1_end) {
|
Chris@16
|
1066 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1067 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
1068 typename M::iterator2 it2_end (it1.end ());
|
Chris@16
|
1069 #else
|
Chris@16
|
1070 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
1071 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
|
Chris@16
|
1072 #endif
|
Chris@16
|
1073 while (it2 != it2_end) { // zeroing
|
Chris@16
|
1074 functor_type::apply (*it2, expr_value_type/*zero*/());
|
Chris@16
|
1075 ++ it2;
|
Chris@16
|
1076 }
|
Chris@16
|
1077 ++ it1;
|
Chris@16
|
1078 }
|
Chris@16
|
1079 } else {
|
Chris@16
|
1080 it1 = it1_end;
|
Chris@16
|
1081 }
|
Chris@16
|
1082 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
1083 if (! disable_type_check<bool>::value)
|
Chris@16
|
1084 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
|
Chris@16
|
1085 #endif
|
Chris@16
|
1086 }
|
Chris@16
|
1087 // Sparse proxy or functional column major case
|
Chris@16
|
1088 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
1089 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
1090 void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
|
Chris@16
|
1091 typedef typename matrix_traits<E>::value_type expr_value_type;
|
Chris@16
|
1092 typedef F<typename M::iterator1::reference, expr_value_type> functor_type;
|
Chris@16
|
1093 typedef R conformant_restrict_type;
|
Chris@16
|
1094 typedef typename M::size_type size_type;
|
Chris@16
|
1095 typedef typename M::difference_type difference_type;
|
Chris@101
|
1096
|
Chris@16
|
1097 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
Chris@16
|
1098 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
Chris@101
|
1099
|
Chris@16
|
1100 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@101
|
1101 typedef typename M::value_type value_type;
|
Chris@16
|
1102 matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
|
Chris@16
|
1103 indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
|
Chris@16
|
1104 indexing_matrix_assign<F> (cm, e, column_major_tag ());
|
Chris@16
|
1105 #endif
|
Chris@16
|
1106 detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
|
Chris@16
|
1107
|
Chris@16
|
1108 typename M::iterator2 it2 (m.begin2 ());
|
Chris@16
|
1109 typename M::iterator2 it2_end (m.end2 ());
|
Chris@16
|
1110 typename E::const_iterator2 it2e (e ().begin2 ());
|
Chris@16
|
1111 typename E::const_iterator2 it2e_end (e ().end2 ());
|
Chris@16
|
1112 while (it2 != it2_end && it2e != it2e_end) {
|
Chris@16
|
1113 difference_type compare = it2.index2 () - it2e.index2 ();
|
Chris@16
|
1114 if (compare == 0) {
|
Chris@16
|
1115 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1116 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
1117 typename M::iterator1 it1_end (it2.end ());
|
Chris@16
|
1118 typename E::const_iterator1 it1e (it2e.begin ());
|
Chris@16
|
1119 typename E::const_iterator1 it1e_end (it2e.end ());
|
Chris@16
|
1120 #else
|
Chris@16
|
1121 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
1122 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
|
Chris@16
|
1123 typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@16
|
1124 typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
|
Chris@16
|
1125 #endif
|
Chris@16
|
1126 if (it1 != it1_end && it1e != it1e_end) {
|
Chris@16
|
1127 size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
|
Chris@16
|
1128 while (true) {
|
Chris@101
|
1129 difference_type compare2 = it1_index - it1e_index;
|
Chris@101
|
1130 if (compare2 == 0) {
|
Chris@16
|
1131 functor_type::apply (*it1, *it1e);
|
Chris@16
|
1132 ++ it1, ++ it1e;
|
Chris@16
|
1133 if (it1 != it1_end && it1e != it1e_end) {
|
Chris@16
|
1134 it1_index = it1.index1 ();
|
Chris@16
|
1135 it1e_index = it1e.index1 ();
|
Chris@16
|
1136 } else
|
Chris@16
|
1137 break;
|
Chris@101
|
1138 } else if (compare2 < 0) {
|
Chris@16
|
1139 if (!functor_type::computed) {
|
Chris@16
|
1140 functor_type::apply (*it1, expr_value_type/*zero*/()); // zeroing
|
Chris@16
|
1141 ++ it1;
|
Chris@16
|
1142 } else
|
Chris@101
|
1143 increment (it1, it1_end, - compare2);
|
Chris@16
|
1144 if (it1 != it1_end)
|
Chris@16
|
1145 it1_index = it1.index1 ();
|
Chris@16
|
1146 else
|
Chris@16
|
1147 break;
|
Chris@101
|
1148 } else if (compare2 > 0) {
|
Chris@101
|
1149 increment (it1e, it1e_end, compare2);
|
Chris@16
|
1150 if (it1e != it1e_end)
|
Chris@16
|
1151 it1e_index = it1e.index1 ();
|
Chris@16
|
1152 else
|
Chris@16
|
1153 break;
|
Chris@16
|
1154 }
|
Chris@16
|
1155 }
|
Chris@16
|
1156 }
|
Chris@16
|
1157 if (!functor_type::computed) {
|
Chris@16
|
1158 while (it1 != it1_end) { // zeroing
|
Chris@16
|
1159 functor_type::apply (*it1, expr_value_type/*zero*/());
|
Chris@16
|
1160 ++ it1;
|
Chris@16
|
1161 }
|
Chris@16
|
1162 } else {
|
Chris@16
|
1163 it1 = it1_end;
|
Chris@16
|
1164 }
|
Chris@16
|
1165 ++ it2, ++ it2e;
|
Chris@16
|
1166 } else if (compare < 0) {
|
Chris@16
|
1167 if (!functor_type::computed) {
|
Chris@16
|
1168 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1169 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
1170 typename M::iterator1 it1_end (it2.end ());
|
Chris@16
|
1171 #else
|
Chris@16
|
1172 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
1173 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
|
Chris@16
|
1174 #endif
|
Chris@16
|
1175 while (it1 != it1_end) { // zeroing
|
Chris@16
|
1176 functor_type::apply (*it1, expr_value_type/*zero*/());
|
Chris@16
|
1177 ++ it1;
|
Chris@16
|
1178 }
|
Chris@16
|
1179 ++ it2;
|
Chris@16
|
1180 } else {
|
Chris@16
|
1181 increment (it2, it2_end, - compare);
|
Chris@16
|
1182 }
|
Chris@16
|
1183 } else if (compare > 0) {
|
Chris@16
|
1184 increment (it2e, it2e_end, compare);
|
Chris@16
|
1185 }
|
Chris@16
|
1186 }
|
Chris@16
|
1187 if (!functor_type::computed) {
|
Chris@16
|
1188 while (it2 != it2_end) {
|
Chris@16
|
1189 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1190 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
1191 typename M::iterator1 it1_end (it2.end ());
|
Chris@16
|
1192 #else
|
Chris@16
|
1193 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
1194 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
|
Chris@16
|
1195 #endif
|
Chris@16
|
1196 while (it1 != it1_end) { // zeroing
|
Chris@16
|
1197 functor_type::apply (*it1, expr_value_type/*zero*/());
|
Chris@16
|
1198 ++ it1;
|
Chris@16
|
1199 }
|
Chris@16
|
1200 ++ it2;
|
Chris@16
|
1201 }
|
Chris@16
|
1202 } else {
|
Chris@16
|
1203 it2 = it2_end;
|
Chris@16
|
1204 }
|
Chris@16
|
1205 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
1206 if (! disable_type_check<bool>::value)
|
Chris@16
|
1207 BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
|
Chris@16
|
1208 #endif
|
Chris@16
|
1209 }
|
Chris@16
|
1210
|
Chris@16
|
1211 // Dispatcher
|
Chris@16
|
1212 template<template <class T1, class T2> class F, class M, class E>
|
Chris@16
|
1213 BOOST_UBLAS_INLINE
|
Chris@16
|
1214 void matrix_assign (M &m, const matrix_expression<E> &e) {
|
Chris@16
|
1215 typedef typename matrix_assign_traits<typename M::storage_category,
|
Chris@16
|
1216 F<typename M::reference, typename E::value_type>::computed,
|
Chris@16
|
1217 typename E::const_iterator1::iterator_category,
|
Chris@16
|
1218 typename E::const_iterator2::iterator_category>::storage_category storage_category;
|
Chris@16
|
1219 // give preference to matrix M's orientation if known
|
Chris@16
|
1220 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
|
Chris@16
|
1221 typename E::orientation_category ,
|
Chris@16
|
1222 typename M::orientation_category >::type orientation_category;
|
Chris@16
|
1223 typedef basic_full<typename M::size_type> unrestricted;
|
Chris@16
|
1224 matrix_assign<F, unrestricted> (m, e, storage_category (), orientation_category ());
|
Chris@16
|
1225 }
|
Chris@16
|
1226 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
1227 BOOST_UBLAS_INLINE
|
Chris@16
|
1228 void matrix_assign (M &m, const matrix_expression<E> &e) {
|
Chris@16
|
1229 typedef R conformant_restrict_type;
|
Chris@16
|
1230 typedef typename matrix_assign_traits<typename M::storage_category,
|
Chris@16
|
1231 F<typename M::reference, typename E::value_type>::computed,
|
Chris@16
|
1232 typename E::const_iterator1::iterator_category,
|
Chris@16
|
1233 typename E::const_iterator2::iterator_category>::storage_category storage_category;
|
Chris@16
|
1234 // give preference to matrix M's orientation if known
|
Chris@16
|
1235 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
|
Chris@16
|
1236 typename E::orientation_category ,
|
Chris@16
|
1237 typename M::orientation_category >::type orientation_category;
|
Chris@16
|
1238 matrix_assign<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
|
Chris@16
|
1239 }
|
Chris@16
|
1240
|
Chris@16
|
1241 template<class SC, class RI1, class RI2>
|
Chris@16
|
1242 struct matrix_swap_traits {
|
Chris@16
|
1243 typedef SC storage_category;
|
Chris@16
|
1244 };
|
Chris@16
|
1245
|
Chris@16
|
1246 template<>
|
Chris@16
|
1247 struct matrix_swap_traits<dense_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
|
Chris@16
|
1248 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
1249 };
|
Chris@16
|
1250
|
Chris@16
|
1251 template<>
|
Chris@16
|
1252 struct matrix_swap_traits<packed_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
|
Chris@16
|
1253 typedef sparse_proxy_tag storage_category;
|
Chris@16
|
1254 };
|
Chris@16
|
1255
|
Chris@16
|
1256 // Dense (proxy) row major case
|
Chris@16
|
1257 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
1258 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
1259 void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, row_major_tag) {
|
Chris@16
|
1260 typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
|
Chris@16
|
1261 // R unnecessary, make_conformant not required
|
Chris@101
|
1262 //typedef typename M::size_type size_type; // gcc is complaining that this is not used, although this is not right
|
Chris@16
|
1263 typedef typename M::difference_type difference_type;
|
Chris@16
|
1264 typename M::iterator1 it1 (m.begin1 ());
|
Chris@16
|
1265 typename E::iterator1 it1e (e ().begin1 ());
|
Chris@101
|
1266 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (e ().end1 () - it1e)));
|
Chris@16
|
1267 while (-- size1 >= 0) {
|
Chris@16
|
1268 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1269 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
1270 typename E::iterator2 it2e (it1e.begin ());
|
Chris@101
|
1271 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (it1e.end () - it2e)));
|
Chris@16
|
1272 #else
|
Chris@16
|
1273 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
1274 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@101
|
1275 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (end (it1e, iterator1_tag ()) - it2e)));
|
Chris@16
|
1276 #endif
|
Chris@16
|
1277 while (-- size2 >= 0)
|
Chris@16
|
1278 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
|
Chris@16
|
1279 ++ it1, ++ it1e;
|
Chris@16
|
1280 }
|
Chris@16
|
1281 }
|
Chris@16
|
1282 // Dense (proxy) column major case
|
Chris@16
|
1283 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
1284 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
1285 void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, column_major_tag) {
|
Chris@16
|
1286 typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
|
Chris@16
|
1287 // R unnecessary, make_conformant not required
|
Chris@101
|
1288 // typedef typename M::size_type size_type; // gcc is complaining that this is not used, although this is not right
|
Chris@16
|
1289 typedef typename M::difference_type difference_type;
|
Chris@16
|
1290 typename M::iterator2 it2 (m.begin2 ());
|
Chris@16
|
1291 typename E::iterator2 it2e (e ().begin2 ());
|
Chris@101
|
1292 difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), typename M::size_type (e ().end2 () - it2e)));
|
Chris@16
|
1293 while (-- size2 >= 0) {
|
Chris@16
|
1294 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1295 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
1296 typename E::iterator1 it1e (it2e.begin ());
|
Chris@101
|
1297 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (it2e.end () - it1e)));
|
Chris@16
|
1298 #else
|
Chris@16
|
1299 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
1300 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@101
|
1301 difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), typename M::size_type (end (it2e, iterator2_tag ()) - it1e)));
|
Chris@16
|
1302 #endif
|
Chris@16
|
1303 while (-- size1 >= 0)
|
Chris@16
|
1304 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
|
Chris@16
|
1305 ++ it2, ++ it2e;
|
Chris@16
|
1306 }
|
Chris@16
|
1307 }
|
Chris@16
|
1308 // Packed (proxy) row major case
|
Chris@16
|
1309 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
1310 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
1311 void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
|
Chris@16
|
1312 typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
|
Chris@16
|
1313 // R unnecessary, make_conformant not required
|
Chris@16
|
1314 typedef typename M::difference_type difference_type;
|
Chris@16
|
1315 typename M::iterator1 it1 (m.begin1 ());
|
Chris@16
|
1316 typename E::iterator1 it1e (e ().begin1 ());
|
Chris@16
|
1317 difference_type size1 (BOOST_UBLAS_SAME (m.end1 () - it1, e ().end1 () - it1e));
|
Chris@16
|
1318 while (-- size1 >= 0) {
|
Chris@16
|
1319 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1320 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
1321 typename E::iterator2 it2e (it1e.begin ());
|
Chris@16
|
1322 difference_type size2 (BOOST_UBLAS_SAME (it1.end () - it2, it1e.end () - it2e));
|
Chris@16
|
1323 #else
|
Chris@16
|
1324 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
1325 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@16
|
1326 difference_type size2 (BOOST_UBLAS_SAME (end (it1, iterator1_tag ()) - it2, end (it1e, iterator1_tag ()) - it2e));
|
Chris@16
|
1327 #endif
|
Chris@16
|
1328 while (-- size2 >= 0)
|
Chris@16
|
1329 functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
|
Chris@16
|
1330 ++ it1, ++ it1e;
|
Chris@16
|
1331 }
|
Chris@16
|
1332 }
|
Chris@16
|
1333 // Packed (proxy) column major case
|
Chris@16
|
1334 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
1335 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
1336 void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
|
Chris@16
|
1337 typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
|
Chris@16
|
1338 // R unnecessary, make_conformant not required
|
Chris@16
|
1339 typedef typename M::difference_type difference_type;
|
Chris@16
|
1340 typename M::iterator2 it2 (m.begin2 ());
|
Chris@16
|
1341 typename E::iterator2 it2e (e ().begin2 ());
|
Chris@16
|
1342 difference_type size2 (BOOST_UBLAS_SAME (m.end2 () - it2, e ().end2 () - it2e));
|
Chris@16
|
1343 while (-- size2 >= 0) {
|
Chris@16
|
1344 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1345 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
1346 typename E::iterator1 it1e (it2e.begin ());
|
Chris@16
|
1347 difference_type size1 (BOOST_UBLAS_SAME (it2.end () - it1, it2e.end () - it1e));
|
Chris@16
|
1348 #else
|
Chris@16
|
1349 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
1350 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@16
|
1351 difference_type size1 (BOOST_UBLAS_SAME (end (it2, iterator2_tag ()) - it1, end (it2e, iterator2_tag ()) - it1e));
|
Chris@16
|
1352 #endif
|
Chris@16
|
1353 while (-- size1 >= 0)
|
Chris@16
|
1354 functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
|
Chris@16
|
1355 ++ it2, ++ it2e;
|
Chris@16
|
1356 }
|
Chris@16
|
1357 }
|
Chris@16
|
1358 // Sparse (proxy) row major case
|
Chris@16
|
1359 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
1360 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
1361 void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
|
Chris@16
|
1362 typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
|
Chris@16
|
1363 typedef R conformant_restrict_type;
|
Chris@16
|
1364 typedef typename M::size_type size_type;
|
Chris@16
|
1365 typedef typename M::difference_type difference_type;
|
Chris@16
|
1366 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
Chris@16
|
1367 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
Chris@16
|
1368
|
Chris@16
|
1369 detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
|
Chris@16
|
1370 // FIXME should be a seperate restriction for E
|
Chris@16
|
1371 detail::make_conformant (e (), m, row_major_tag (), conformant_restrict_type ());
|
Chris@16
|
1372
|
Chris@16
|
1373 typename M::iterator1 it1 (m.begin1 ());
|
Chris@16
|
1374 typename M::iterator1 it1_end (m.end1 ());
|
Chris@16
|
1375 typename E::iterator1 it1e (e ().begin1 ());
|
Chris@16
|
1376 typename E::iterator1 it1e_end (e ().end1 ());
|
Chris@16
|
1377 while (it1 != it1_end && it1e != it1e_end) {
|
Chris@16
|
1378 difference_type compare = it1.index1 () - it1e.index1 ();
|
Chris@16
|
1379 if (compare == 0) {
|
Chris@16
|
1380 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1381 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
1382 typename M::iterator2 it2_end (it1.end ());
|
Chris@16
|
1383 typename E::iterator2 it2e (it1e.begin ());
|
Chris@16
|
1384 typename E::iterator2 it2e_end (it1e.end ());
|
Chris@16
|
1385 #else
|
Chris@16
|
1386 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
1387 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
|
Chris@16
|
1388 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@16
|
1389 typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
|
Chris@16
|
1390 #endif
|
Chris@16
|
1391 if (it2 != it2_end && it2e != it2e_end) {
|
Chris@16
|
1392 size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
|
Chris@16
|
1393 while (true) {
|
Chris@101
|
1394 difference_type compare2 = it2_index - it2e_index;
|
Chris@101
|
1395 if (compare2 == 0) {
|
Chris@16
|
1396 functor_type::apply (*it2, *it2e);
|
Chris@16
|
1397 ++ it2, ++ it2e;
|
Chris@16
|
1398 if (it2 != it2_end && it2e != it2e_end) {
|
Chris@16
|
1399 it2_index = it2.index2 ();
|
Chris@16
|
1400 it2e_index = it2e.index2 ();
|
Chris@16
|
1401 } else
|
Chris@16
|
1402 break;
|
Chris@101
|
1403 } else if (compare2 < 0) {
|
Chris@101
|
1404 increment (it2, it2_end, - compare2);
|
Chris@16
|
1405 if (it2 != it2_end)
|
Chris@16
|
1406 it2_index = it2.index2 ();
|
Chris@16
|
1407 else
|
Chris@16
|
1408 break;
|
Chris@101
|
1409 } else if (compare2 > 0) {
|
Chris@101
|
1410 increment (it2e, it2e_end, compare2);
|
Chris@16
|
1411 if (it2e != it2e_end)
|
Chris@16
|
1412 it2e_index = it2e.index2 ();
|
Chris@16
|
1413 else
|
Chris@16
|
1414 break;
|
Chris@16
|
1415 }
|
Chris@16
|
1416 }
|
Chris@16
|
1417 }
|
Chris@16
|
1418 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
1419 increment (it2e, it2e_end);
|
Chris@16
|
1420 increment (it2, it2_end);
|
Chris@16
|
1421 #endif
|
Chris@16
|
1422 ++ it1, ++ it1e;
|
Chris@16
|
1423 } else if (compare < 0) {
|
Chris@16
|
1424 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
1425 while (it1.index1 () < it1e.index1 ()) {
|
Chris@16
|
1426 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1427 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
1428 typename M::iterator2 it2_end (it1.end ());
|
Chris@16
|
1429 #else
|
Chris@16
|
1430 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
1431 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
|
Chris@16
|
1432 #endif
|
Chris@16
|
1433 increment (it2, it2_end);
|
Chris@16
|
1434 ++ it1;
|
Chris@16
|
1435 }
|
Chris@16
|
1436 #else
|
Chris@16
|
1437 increment (it1, it1_end, - compare);
|
Chris@16
|
1438 #endif
|
Chris@16
|
1439 } else if (compare > 0) {
|
Chris@16
|
1440 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
1441 while (it1e.index1 () < it1.index1 ()) {
|
Chris@16
|
1442 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1443 typename E::iterator2 it2e (it1e.begin ());
|
Chris@16
|
1444 typename E::iterator2 it2e_end (it1e.end ());
|
Chris@16
|
1445 #else
|
Chris@16
|
1446 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@16
|
1447 typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
|
Chris@16
|
1448 #endif
|
Chris@16
|
1449 increment (it2e, it2e_end);
|
Chris@16
|
1450 ++ it1e;
|
Chris@16
|
1451 }
|
Chris@16
|
1452 #else
|
Chris@16
|
1453 increment (it1e, it1e_end, compare);
|
Chris@16
|
1454 #endif
|
Chris@16
|
1455 }
|
Chris@16
|
1456 }
|
Chris@16
|
1457 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
1458 while (it1e != it1e_end) {
|
Chris@16
|
1459 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1460 typename E::iterator2 it2e (it1e.begin ());
|
Chris@16
|
1461 typename E::iterator2 it2e_end (it1e.end ());
|
Chris@16
|
1462 #else
|
Chris@16
|
1463 typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
|
Chris@16
|
1464 typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
|
Chris@16
|
1465 #endif
|
Chris@16
|
1466 increment (it2e, it2e_end);
|
Chris@16
|
1467 ++ it1e;
|
Chris@16
|
1468 }
|
Chris@16
|
1469 while (it1 != it1_end) {
|
Chris@16
|
1470 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1471 typename M::iterator2 it2 (it1.begin ());
|
Chris@16
|
1472 typename M::iterator2 it2_end (it1.end ());
|
Chris@16
|
1473 #else
|
Chris@16
|
1474 typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
|
Chris@16
|
1475 typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
|
Chris@16
|
1476 #endif
|
Chris@16
|
1477 increment (it2, it2_end);
|
Chris@16
|
1478 ++ it1;
|
Chris@16
|
1479 }
|
Chris@16
|
1480 #endif
|
Chris@16
|
1481 }
|
Chris@16
|
1482 // Sparse (proxy) column major case
|
Chris@16
|
1483 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
1484 // BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
|
Chris@16
|
1485 void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
|
Chris@16
|
1486 typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
|
Chris@16
|
1487 typedef R conformant_restrict_type;
|
Chris@16
|
1488 typedef typename M::size_type size_type;
|
Chris@16
|
1489 typedef typename M::difference_type difference_type;
|
Chris@101
|
1490
|
Chris@16
|
1491 BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
|
Chris@16
|
1492 BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
|
Chris@16
|
1493
|
Chris@16
|
1494 detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
|
Chris@16
|
1495 // FIXME should be a seperate restriction for E
|
Chris@16
|
1496 detail::make_conformant (e (), m, column_major_tag (), conformant_restrict_type ());
|
Chris@16
|
1497
|
Chris@16
|
1498 typename M::iterator2 it2 (m.begin2 ());
|
Chris@16
|
1499 typename M::iterator2 it2_end (m.end2 ());
|
Chris@16
|
1500 typename E::iterator2 it2e (e ().begin2 ());
|
Chris@16
|
1501 typename E::iterator2 it2e_end (e ().end2 ());
|
Chris@16
|
1502 while (it2 != it2_end && it2e != it2e_end) {
|
Chris@16
|
1503 difference_type compare = it2.index2 () - it2e.index2 ();
|
Chris@16
|
1504 if (compare == 0) {
|
Chris@16
|
1505 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1506 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
1507 typename M::iterator1 it1_end (it2.end ());
|
Chris@16
|
1508 typename E::iterator1 it1e (it2e.begin ());
|
Chris@16
|
1509 typename E::iterator1 it1e_end (it2e.end ());
|
Chris@16
|
1510 #else
|
Chris@16
|
1511 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
1512 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
|
Chris@16
|
1513 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@16
|
1514 typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
|
Chris@16
|
1515 #endif
|
Chris@16
|
1516 if (it1 != it1_end && it1e != it1e_end) {
|
Chris@16
|
1517 size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
|
Chris@16
|
1518 while (true) {
|
Chris@101
|
1519 difference_type compare2 = it1_index - it1e_index;
|
Chris@101
|
1520 if (compare2 == 0) {
|
Chris@16
|
1521 functor_type::apply (*it1, *it1e);
|
Chris@16
|
1522 ++ it1, ++ it1e;
|
Chris@16
|
1523 if (it1 != it1_end && it1e != it1e_end) {
|
Chris@16
|
1524 it1_index = it1.index1 ();
|
Chris@16
|
1525 it1e_index = it1e.index1 ();
|
Chris@16
|
1526 } else
|
Chris@16
|
1527 break;
|
Chris@101
|
1528 } else if (compare2 < 0) {
|
Chris@101
|
1529 increment (it1, it1_end, - compare2);
|
Chris@16
|
1530 if (it1 != it1_end)
|
Chris@16
|
1531 it1_index = it1.index1 ();
|
Chris@16
|
1532 else
|
Chris@16
|
1533 break;
|
Chris@101
|
1534 } else if (compare2 > 0) {
|
Chris@101
|
1535 increment (it1e, it1e_end, compare2);
|
Chris@16
|
1536 if (it1e != it1e_end)
|
Chris@16
|
1537 it1e_index = it1e.index1 ();
|
Chris@16
|
1538 else
|
Chris@16
|
1539 break;
|
Chris@16
|
1540 }
|
Chris@16
|
1541 }
|
Chris@16
|
1542 }
|
Chris@16
|
1543 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
1544 increment (it1e, it1e_end);
|
Chris@16
|
1545 increment (it1, it1_end);
|
Chris@16
|
1546 #endif
|
Chris@16
|
1547 ++ it2, ++ it2e;
|
Chris@16
|
1548 } else if (compare < 0) {
|
Chris@16
|
1549 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
1550 while (it2.index2 () < it2e.index2 ()) {
|
Chris@16
|
1551 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1552 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
1553 typename M::iterator1 it1_end (it2.end ());
|
Chris@16
|
1554 #else
|
Chris@16
|
1555 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
1556 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
|
Chris@16
|
1557 #endif
|
Chris@16
|
1558 increment (it1, it1_end);
|
Chris@16
|
1559 ++ it2;
|
Chris@16
|
1560 }
|
Chris@16
|
1561 #else
|
Chris@16
|
1562 increment (it2, it2_end, - compare);
|
Chris@16
|
1563 #endif
|
Chris@16
|
1564 } else if (compare > 0) {
|
Chris@16
|
1565 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
1566 while (it2e.index2 () < it2.index2 ()) {
|
Chris@16
|
1567 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1568 typename E::iterator1 it1e (it2e.begin ());
|
Chris@16
|
1569 typename E::iterator1 it1e_end (it2e.end ());
|
Chris@16
|
1570 #else
|
Chris@16
|
1571 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@16
|
1572 typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
|
Chris@16
|
1573 #endif
|
Chris@16
|
1574 increment (it1e, it1e_end);
|
Chris@16
|
1575 ++ it2e;
|
Chris@16
|
1576 }
|
Chris@16
|
1577 #else
|
Chris@16
|
1578 increment (it2e, it2e_end, compare);
|
Chris@16
|
1579 #endif
|
Chris@16
|
1580 }
|
Chris@16
|
1581 }
|
Chris@16
|
1582 #if BOOST_UBLAS_TYPE_CHECK
|
Chris@16
|
1583 while (it2e != it2e_end) {
|
Chris@16
|
1584 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1585 typename E::iterator1 it1e (it2e.begin ());
|
Chris@16
|
1586 typename E::iterator1 it1e_end (it2e.end ());
|
Chris@16
|
1587 #else
|
Chris@16
|
1588 typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
|
Chris@16
|
1589 typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
|
Chris@16
|
1590 #endif
|
Chris@16
|
1591 increment (it1e, it1e_end);
|
Chris@16
|
1592 ++ it2e;
|
Chris@16
|
1593 }
|
Chris@16
|
1594 while (it2 != it2_end) {
|
Chris@16
|
1595 #ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
|
Chris@16
|
1596 typename M::iterator1 it1 (it2.begin ());
|
Chris@16
|
1597 typename M::iterator1 it1_end (it2.end ());
|
Chris@16
|
1598 #else
|
Chris@16
|
1599 typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
|
Chris@16
|
1600 typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
|
Chris@16
|
1601 #endif
|
Chris@16
|
1602 increment (it1, it1_end);
|
Chris@16
|
1603 ++ it2;
|
Chris@16
|
1604 }
|
Chris@16
|
1605 #endif
|
Chris@16
|
1606 }
|
Chris@16
|
1607
|
Chris@16
|
1608 // Dispatcher
|
Chris@16
|
1609 template<template <class T1, class T2> class F, class M, class E>
|
Chris@16
|
1610 BOOST_UBLAS_INLINE
|
Chris@16
|
1611 void matrix_swap (M &m, matrix_expression<E> &e) {
|
Chris@16
|
1612 typedef typename matrix_swap_traits<typename M::storage_category,
|
Chris@16
|
1613 typename E::const_iterator1::iterator_category,
|
Chris@16
|
1614 typename E::const_iterator2::iterator_category>::storage_category storage_category;
|
Chris@16
|
1615 // give preference to matrix M's orientation if known
|
Chris@16
|
1616 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
|
Chris@16
|
1617 typename E::orientation_category ,
|
Chris@16
|
1618 typename M::orientation_category >::type orientation_category;
|
Chris@16
|
1619 typedef basic_full<typename M::size_type> unrestricted;
|
Chris@16
|
1620 matrix_swap<F, unrestricted> (m, e, storage_category (), orientation_category ());
|
Chris@16
|
1621 }
|
Chris@16
|
1622 template<template <class T1, class T2> class F, class R, class M, class E>
|
Chris@16
|
1623 BOOST_UBLAS_INLINE
|
Chris@16
|
1624 void matrix_swap (M &m, matrix_expression<E> &e) {
|
Chris@16
|
1625 typedef R conformant_restrict_type;
|
Chris@16
|
1626 typedef typename matrix_swap_traits<typename M::storage_category,
|
Chris@16
|
1627 typename E::const_iterator1::iterator_category,
|
Chris@16
|
1628 typename E::const_iterator2::iterator_category>::storage_category storage_category;
|
Chris@16
|
1629 // give preference to matrix M's orientation if known
|
Chris@16
|
1630 typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
|
Chris@16
|
1631 typename E::orientation_category ,
|
Chris@16
|
1632 typename M::orientation_category >::type orientation_category;
|
Chris@16
|
1633 matrix_swap<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
|
Chris@16
|
1634 }
|
Chris@16
|
1635
|
Chris@16
|
1636 }}}
|
Chris@16
|
1637
|
Chris@16
|
1638 #endif
|