2
// Copyright (c) 2000-2002
3
// Joerg Walter, Mathias Koch
5
// Distributed under the Boost Software License, Version 1.0. (See
6
// accompanying file LICENSE_1_0.txt or copy at
7
// http://www.boost.org/LICENSE_1_0.txt)
9
// The authors gratefully acknowledge the support of
10
// GeNeSys mbH & Co. KG in producing this work.
13
#ifndef _BOOST_UBLAS_MATRIX_ASSIGN_
14
#define _BOOST_UBLAS_MATRIX_ASSIGN_
16
// Required for make_conformant storage
19
// Iterators based on ideas of Jeremy Siek
21
namespace boost { namespace numeric { namespace ublas {
24
// Weak equality check - useful to compare equality two arbitary matrix expression results.
25
// Since the actual expressions are unknown, we check for and arbitary error bound
26
// on the relative error.
27
// For a linear expression the infinity norm makes sense as we do not know how the elements will be
28
// combined in the expression. False positive results are inevitable for arbirary expressions!
29
template<class E1, class E2, class S>
31
bool equals (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2, S epsilon, S min_norm) {
32
return norm_inf (e1 - e2) < epsilon *
33
std::max<S> (std::max<S> (norm_inf (e1), norm_inf (e2)), min_norm);
36
template<class E1, class E2>
38
bool expression_type_check (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
39
typedef typename type_traits<typename promote_traits<typename E1::value_type,
40
typename E2::value_type>::promote_type>::real_type real_type;
41
return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
45
template<class M, class E, class R>
46
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
47
void make_conformant (M &m, const matrix_expression<E> &e, row_major_tag, R) {
48
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
49
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
50
typedef R conformant_restrict_type;
51
typedef typename M::size_type size_type;
52
typedef typename M::difference_type difference_type;
53
typedef typename M::value_type value_type;
54
// FIXME unbounded_array with push_back maybe better
55
std::vector<std::pair<size_type, size_type> > index;
56
typename M::iterator1 it1 (m.begin1 ());
57
typename M::iterator1 it1_end (m.end1 ());
58
typename E::const_iterator1 it1e (e ().begin1 ());
59
typename E::const_iterator1 it1e_end (e ().end1 ());
60
while (it1 != it1_end && it1e != it1e_end) {
61
difference_type compare = it1.index1 () - it1e.index1 ();
63
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
64
typename M::iterator2 it2 (it1.begin ());
65
typename M::iterator2 it2_end (it1.end ());
66
typename E::const_iterator2 it2e (it1e.begin ());
67
typename E::const_iterator2 it2e_end (it1e.end ());
69
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
70
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
71
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
72
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
74
if (it2 != it2_end && it2e != it2e_end) {
75
size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
77
difference_type compare = it2_index - it2e_index;
80
if (it2 != it2_end && it2e != it2e_end) {
81
it2_index = it2.index2 ();
82
it2e_index = it2e.index2 ();
85
} else if (compare < 0) {
86
increment (it2, it2_end, - compare);
88
it2_index = it2.index2 ();
91
} else if (compare > 0) {
92
if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
93
if (*it2e != value_type/*zero*/())
94
index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
97
it2e_index = it2e.index2 ();
103
while (it2e != it2e_end) {
104
if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
105
if (*it2e != value_type/*zero*/())
106
index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
110
} else if (compare < 0) {
111
increment (it1, it1_end, - compare);
112
} else if (compare > 0) {
113
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
114
typename E::const_iterator2 it2e (it1e.begin ());
115
typename E::const_iterator2 it2e_end (it1e.end ());
117
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
118
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
120
while (it2e != it2e_end) {
121
if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
122
if (*it2e != value_type/*zero*/())
123
index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
129
while (it1e != it1e_end) {
130
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
131
typename E::const_iterator2 it2e (it1e.begin ());
132
typename E::const_iterator2 it2e_end (it1e.end ());
134
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
135
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
137
while (it2e != it2e_end) {
138
if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
139
if (*it2e != value_type/*zero*/())
140
index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
145
// ISSUE proxies require insert_element
146
for (size_type k = 0; k < index.size (); ++ k)
147
m (index [k].first, index [k].second) = value_type/*zero*/();
149
template<class M, class E, class R>
150
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
151
void make_conformant (M &m, const matrix_expression<E> &e, column_major_tag, R) {
152
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
153
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
154
typedef R conformant_restrict_type;
155
typedef typename M::size_type size_type;
156
typedef typename M::difference_type difference_type;
157
typedef typename M::value_type value_type;
158
std::vector<std::pair<size_type, size_type> > index;
159
typename M::iterator2 it2 (m.begin2 ());
160
typename M::iterator2 it2_end (m.end2 ());
161
typename E::const_iterator2 it2e (e ().begin2 ());
162
typename E::const_iterator2 it2e_end (e ().end2 ());
163
while (it2 != it2_end && it2e != it2e_end) {
164
difference_type compare = it2.index2 () - it2e.index2 ();
166
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
167
typename M::iterator1 it1 (it2.begin ());
168
typename M::iterator1 it1_end (it2.end ());
169
typename E::const_iterator1 it1e (it2e.begin ());
170
typename E::const_iterator1 it1e_end (it2e.end ());
172
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
173
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
174
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
175
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
177
if (it1 != it1_end && it1e != it1e_end) {
178
size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
180
difference_type compare = it1_index - it1e_index;
183
if (it1 != it1_end && it1e != it1e_end) {
184
it1_index = it1.index1 ();
185
it1e_index = it1e.index1 ();
188
} else if (compare < 0) {
189
increment (it1, it1_end, - compare);
191
it1_index = it1.index1 ();
194
} else if (compare > 0) {
195
if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
196
if (*it1e != value_type/*zero*/())
197
index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
199
if (it1e != it1e_end)
200
it1e_index = it1e.index1 ();
206
while (it1e != it1e_end) {
207
if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
208
if (*it1e != value_type/*zero*/())
209
index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
213
} else if (compare < 0) {
214
increment (it2, it2_end, - compare);
215
} else if (compare > 0) {
216
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
217
typename E::const_iterator1 it1e (it2e.begin ());
218
typename E::const_iterator1 it1e_end (it2e.end ());
220
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
221
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
223
while (it1e != it1e_end) {
224
if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
225
if (*it1e != value_type/*zero*/())
226
index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
232
while (it2e != it2e_end) {
233
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
234
typename E::const_iterator1 it1e (it2e.begin ());
235
typename E::const_iterator1 it1e_end (it2e.end ());
237
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
238
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
240
while (it1e != it1e_end) {
241
if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
242
if (*it1e != value_type/*zero*/())
243
index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
248
// ISSUE proxies require insert_element
249
for (size_type k = 0; k < index.size (); ++ k)
250
m (index [k].first, index [k].second) = value_type/*zero*/();
256
// Explicitly iterating row major
257
template<template <class T1, class T2> class F, class M, class T>
258
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
259
void iterating_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
260
typedef F<typename M::iterator2::reference, T> functor_type;
261
typedef typename M::difference_type difference_type;
262
difference_type size1 (m.size1 ());
263
difference_type size2 (m.size2 ());
264
typename M::iterator1 it1 (m.begin1 ());
265
BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
266
while (-- size1 >= 0) {
267
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
268
typename M::iterator2 it2 (it1.begin ());
270
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
272
BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
273
difference_type temp_size2 (size2);
274
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
275
while (-- temp_size2 >= 0)
276
functor_type::apply (*it2, t), ++ it2;
278
DD (temp_size2, 4, r, (functor_type::apply (*it2, t), ++ it2));
283
// Explicitly iterating column major
284
template<template <class T1, class T2> class F, class M, class T>
285
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
286
void iterating_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
287
typedef F<typename M::iterator1::reference, T> functor_type;
288
typedef typename M::difference_type difference_type;
289
difference_type size2 (m.size2 ());
290
difference_type size1 (m.size1 ());
291
typename M::iterator2 it2 (m.begin2 ());
292
BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
293
while (-- size2 >= 0) {
294
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
295
typename M::iterator1 it1 (it2.begin ());
297
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
299
BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
300
difference_type temp_size1 (size1);
301
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
302
while (-- temp_size1 >= 0)
303
functor_type::apply (*it1, t), ++ it1;
305
DD (temp_size1, 4, r, (functor_type::apply (*it1, t), ++ it1));
310
// Explicitly indexing row major
311
template<template <class T1, class T2> class F, class M, class T>
312
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
313
void indexing_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
314
typedef F<typename M::reference, T> functor_type;
315
typedef typename M::size_type size_type;
316
size_type size1 (m.size1 ());
317
size_type size2 (m.size2 ());
318
for (size_type i = 0; i < size1; ++ i) {
319
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
320
for (size_type j = 0; j < size2; ++ j)
321
functor_type::apply (m (i, j), t);
324
DD (size2, 4, r, (functor_type::apply (m (i, j), t), ++ j));
328
// Explicitly indexing column major
329
template<template <class T1, class T2> class F, class M, class T>
330
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
331
void indexing_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
332
typedef F<typename M::reference, T> functor_type;
333
typedef typename M::size_type size_type;
334
size_type size2 (m.size2 ());
335
size_type size1 (m.size1 ());
336
for (size_type j = 0; j < size2; ++ j) {
337
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
338
for (size_type i = 0; i < size1; ++ i)
339
functor_type::apply (m (i, j), t);
342
DD (size1, 4, r, (functor_type::apply (m (i, j), t), ++ i));
347
// Dense (proxy) case
348
template<template <class T1, class T2> class F, class M, class T, class C>
349
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
350
void matrix_assign_scalar (M &m, const T &t, dense_proxy_tag, C) {
351
typedef C orientation_category;
352
#ifdef BOOST_UBLAS_USE_INDEXING
353
indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
354
#elif BOOST_UBLAS_USE_ITERATING
355
iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
357
typedef typename M::size_type size_type;
358
size_type size1 (m.size1 ());
359
size_type size2 (m.size2 ());
360
if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
361
size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
362
iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
364
indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
367
// Packed (proxy) row major case
368
template<template <class T1, class T2> class F, class M, class T>
369
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
370
void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, row_major_tag) {
371
typedef F<typename M::iterator2::reference, T> functor_type;
372
typedef typename M::difference_type difference_type;
373
typename M::iterator1 it1 (m.begin1 ());
374
difference_type size1 (m.end1 () - it1);
375
while (-- size1 >= 0) {
376
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
377
typename M::iterator2 it2 (it1.begin ());
378
difference_type size2 (it1.end () - it2);
380
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
381
difference_type size2 (end (it1, iterator1_tag ()) - it2);
383
while (-- size2 >= 0)
384
functor_type::apply (*it2, t), ++ it2;
388
// Packed (proxy) column major case
389
template<template <class T1, class T2> class F, class M, class T>
390
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
391
void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, column_major_tag) {
392
typedef F<typename M::iterator1::reference, T> functor_type;
393
typedef typename M::difference_type difference_type;
394
typename M::iterator2 it2 (m.begin2 ());
395
difference_type size2 (m.end2 () - it2);
396
while (-- size2 >= 0) {
397
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
398
typename M::iterator1 it1 (it2.begin ());
399
difference_type size1 (it2.end () - it1);
401
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
402
difference_type size1 (end (it2, iterator2_tag ()) - it1);
404
while (-- size1 >= 0)
405
functor_type::apply (*it1, t), ++ it1;
409
// Sparse (proxy) row major case
410
template<template <class T1, class T2> class F, class M, class T>
411
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
412
void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, row_major_tag) {
413
typedef F<typename M::iterator2::reference, T> functor_type;
414
typename M::iterator1 it1 (m.begin1 ());
415
typename M::iterator1 it1_end (m.end1 ());
416
while (it1 != it1_end) {
417
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
418
typename M::iterator2 it2 (it1.begin ());
419
typename M::iterator2 it2_end (it1.end ());
421
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
422
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
424
while (it2 != it2_end)
425
functor_type::apply (*it2, t), ++ it2;
429
// Sparse (proxy) column major case
430
template<template <class T1, class T2> class F, class M, class T>
431
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
432
void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, column_major_tag) {
433
typedef F<typename M::iterator1::reference, T> functor_type;
434
typename M::iterator2 it2 (m.begin2 ());
435
typename M::iterator2 it2_end (m.end2 ());
436
while (it2 != it2_end) {
437
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
438
typename M::iterator1 it1 (it2.begin ());
439
typename M::iterator1 it1_end (it2.end ());
441
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
442
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
444
while (it1 != it1_end)
445
functor_type::apply (*it1, t), ++ it1;
451
template<template <class T1, class T2> class F, class M, class T>
453
void matrix_assign_scalar (M &m, const T &t) {
454
typedef typename M::storage_category storage_category;
455
typedef typename M::orientation_category orientation_category;
456
matrix_assign_scalar<F> (m, t, storage_category (), orientation_category ());
459
template<class SC, bool COMPUTED, class RI1, class RI2>
460
struct matrix_assign_traits {
461
typedef SC storage_category;
464
template<bool COMPUTED>
465
struct matrix_assign_traits<dense_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
466
typedef packed_tag storage_category;
469
struct matrix_assign_traits<dense_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
470
typedef sparse_tag storage_category;
473
struct matrix_assign_traits<dense_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
474
typedef sparse_proxy_tag storage_category;
477
template<bool COMPUTED>
478
struct matrix_assign_traits<dense_proxy_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
479
typedef packed_proxy_tag storage_category;
481
template<bool COMPUTED>
482
struct matrix_assign_traits<dense_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
483
typedef sparse_proxy_tag storage_category;
487
struct matrix_assign_traits<packed_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
488
typedef sparse_tag storage_category;
491
struct matrix_assign_traits<packed_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
492
typedef sparse_proxy_tag storage_category;
495
template<bool COMPUTED>
496
struct matrix_assign_traits<packed_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
497
typedef sparse_proxy_tag storage_category;
501
struct matrix_assign_traits<sparse_tag, true, dense_random_access_iterator_tag, dense_random_access_iterator_tag> {
502
typedef sparse_proxy_tag storage_category;
505
struct matrix_assign_traits<sparse_tag, true, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
506
typedef sparse_proxy_tag storage_category;
509
struct matrix_assign_traits<sparse_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
510
typedef sparse_proxy_tag storage_category;
513
// Explicitly iterating row major
514
template<template <class T1, class T2> class F, class M, class E>
515
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
516
void iterating_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
517
typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
518
typedef typename M::difference_type difference_type;
519
difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
520
difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
521
typename M::iterator1 it1 (m.begin1 ());
522
BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
523
typename E::const_iterator1 it1e (e ().begin1 ());
524
BOOST_UBLAS_CHECK (size2 == 0 || e ().end1 () - it1e == size1, bad_size ());
525
while (-- size1 >= 0) {
526
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
527
typename M::iterator2 it2 (it1.begin ());
528
typename E::const_iterator2 it2e (it1e.begin ());
530
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
531
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
533
BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
534
BOOST_UBLAS_CHECK (it1e.end () - it2e == size2, bad_size ());
535
difference_type temp_size2 (size2);
536
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
537
while (-- temp_size2 >= 0)
538
functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
540
DD (temp_size2, 2, r, (functor_type::apply (*it2, *it2e), ++ it2, ++ it2e));
545
// Explicitly iterating column major
546
template<template <class T1, class T2> class F, class M, class E>
547
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
548
void iterating_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
549
typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
550
typedef typename M::difference_type difference_type;
551
difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
552
difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
553
typename M::iterator2 it2 (m.begin2 ());
554
BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
555
typename E::const_iterator2 it2e (e ().begin2 ());
556
BOOST_UBLAS_CHECK (size1 == 0 || e ().end2 () - it2e == size2, bad_size ());
557
while (-- size2 >= 0) {
558
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
559
typename M::iterator1 it1 (it2.begin ());
560
typename E::const_iterator1 it1e (it2e.begin ());
562
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
563
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
565
BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
566
BOOST_UBLAS_CHECK (it2e.end () - it1e == size1, bad_size ());
567
difference_type temp_size1 (size1);
568
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
569
while (-- temp_size1 >= 0)
570
functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
572
DD (temp_size1, 2, r, (functor_type::apply (*it1, *it1e), ++ it1, ++ it1e));
577
// Explicitly indexing row major
578
template<template <class T1, class T2> class F, class M, class E>
579
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
580
void indexing_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
581
typedef F<typename M::reference, typename E::value_type> functor_type;
582
typedef typename M::size_type size_type;
583
size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
584
size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
585
for (size_type i = 0; i < size1; ++ i) {
586
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
587
for (size_type j = 0; j < size2; ++ j)
588
functor_type::apply (m (i, j), e () (i, j));
591
DD (size2, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ j));
595
// Explicitly indexing column major
596
template<template <class T1, class T2> class F, class M, class E>
597
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
598
void indexing_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
599
typedef F<typename M::reference, typename E::value_type> functor_type;
600
typedef typename M::size_type size_type;
601
size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
602
size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
603
for (size_type j = 0; j < size2; ++ j) {
604
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
605
for (size_type i = 0; i < size1; ++ i)
606
functor_type::apply (m (i, j), e () (i, j));
609
DD (size1, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ i));
614
// Dense (proxy) case
615
template<template <class T1, class T2> class F, class R, class M, class E, class C>
616
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
617
void matrix_assign (M &m, const matrix_expression<E> &e, dense_proxy_tag, C) {
618
// R unnecessary, make_conformant not required
619
typedef C orientation_category;
620
#ifdef BOOST_UBLAS_USE_INDEXING
621
indexing_matrix_assign<F> (m, e, orientation_category ());
622
#elif BOOST_UBLAS_USE_ITERATING
623
iterating_matrix_assign<F> (m, e, orientation_category ());
625
typedef typename M::difference_type difference_type;
626
size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
627
size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
628
if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
629
size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
630
iterating_matrix_assign<F> (m, e, orientation_category ());
632
indexing_matrix_assign<F> (m, e, orientation_category ());
635
// Packed (proxy) row major case
636
template<template <class T1, class T2> class F, class R, class M, class E>
637
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
638
void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
639
typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
640
// R unnecessary, make_conformant not required
641
typedef typename M::difference_type difference_type;
642
typedef typename M::value_type value_type;
643
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
644
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
645
#if BOOST_UBLAS_TYPE_CHECK
646
matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
647
indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
648
indexing_matrix_assign<F> (cm, e, row_major_tag ());
650
typename M::iterator1 it1 (m.begin1 ());
651
typename M::iterator1 it1_end (m.end1 ());
652
typename E::const_iterator1 it1e (e ().begin1 ());
653
typename E::const_iterator1 it1e_end (e ().end1 ());
654
difference_type it1_size (it1_end - it1);
655
difference_type it1e_size (it1e_end - it1e);
656
difference_type diff1 (0);
657
if (it1_size > 0 && it1e_size > 0)
658
diff1 = it1.index1 () - it1e.index1 ();
660
difference_type size1 = (std::min) (diff1, it1e_size);
666
size1 = (std::min) (- diff1, it1_size);
669
if (!functor_type::computed) {
670
while (-- size1 >= 0) { // zeroing
671
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
672
typename M::iterator2 it2 (it1.begin ());
673
typename M::iterator2 it2_end (it1.end ());
675
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
676
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
678
difference_type size2 (it2_end - it2);
679
while (-- size2 >= 0)
680
functor_type::apply (*it2, value_type/*zero*/()), ++ it2;
689
difference_type size1 ((std::min) (it1_size, it1e_size));
692
while (-- size1 >= 0) {
693
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
694
typename M::iterator2 it2 (it1.begin ());
695
typename M::iterator2 it2_end (it1.end ());
696
typename E::const_iterator2 it2e (it1e.begin ());
697
typename E::const_iterator2 it2e_end (it1e.end ());
699
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
700
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
701
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
702
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
704
difference_type it2_size (it2_end - it2);
705
difference_type it2e_size (it2e_end - it2e);
706
difference_type diff2 (0);
707
if (it2_size > 0 && it2e_size > 0) {
708
diff2 = it2.index2 () - it2e.index2 ();
709
difference_type size2 = (std::min) (diff2, it2e_size);
715
size2 = (std::min) (- diff2, it2_size);
718
if (!functor_type::computed) {
719
while (-- size2 >= 0) // zeroing
720
functor_type::apply (*it2, value_type/*zero*/()), ++ it2;
727
difference_type size2 ((std::min) (it2_size, it2e_size));
730
while (-- size2 >= 0)
731
functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
733
if (!functor_type::computed) {
734
while (-- size2 >= 0) // zeroing
735
functor_type::apply (*it2, value_type/*zero*/()), ++ it2;
742
if (!functor_type::computed) {
743
while (-- size1 >= 0) { // zeroing
744
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
745
typename M::iterator2 it2 (it1.begin ());
746
typename M::iterator2 it2_end (it1.end ());
748
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
749
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
751
difference_type size2 (it2_end - it2);
752
while (-- size2 >= 0)
753
functor_type::apply (*it2, value_type/*zero*/()), ++ it2;
759
#if BOOST_UBLAS_TYPE_CHECK
760
if (! disable_type_check<bool>::value)
761
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
764
// Packed (proxy) column major case
765
template<template <class T1, class T2> class F, class R, class M, class E>
766
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
767
void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
768
typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
769
// R unnecessary, make_conformant not required
770
typedef typename M::difference_type difference_type;
771
typedef typename M::value_type value_type;
772
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
773
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
774
#if BOOST_UBLAS_TYPE_CHECK
775
matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
776
indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
777
indexing_matrix_assign<F> (cm, e, column_major_tag ());
779
typename M::iterator2 it2 (m.begin2 ());
780
typename M::iterator2 it2_end (m.end2 ());
781
typename E::const_iterator2 it2e (e ().begin2 ());
782
typename E::const_iterator2 it2e_end (e ().end2 ());
783
difference_type it2_size (it2_end - it2);
784
difference_type it2e_size (it2e_end - it2e);
785
difference_type diff2 (0);
786
if (it2_size > 0 && it2e_size > 0)
787
diff2 = it2.index2 () - it2e.index2 ();
789
difference_type size2 = (std::min) (diff2, it2e_size);
795
size2 = (std::min) (- diff2, it2_size);
798
if (!functor_type::computed) {
799
while (-- size2 >= 0) { // zeroing
800
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
801
typename M::iterator1 it1 (it2.begin ());
802
typename M::iterator1 it1_end (it2.end ());
804
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
805
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
807
difference_type size1 (it1_end - it1);
808
while (-- size1 >= 0)
809
functor_type::apply (*it1, value_type/*zero*/()), ++ it1;
818
difference_type size2 ((std::min) (it2_size, it2e_size));
821
while (-- size2 >= 0) {
822
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
823
typename M::iterator1 it1 (it2.begin ());
824
typename M::iterator1 it1_end (it2.end ());
825
typename E::const_iterator1 it1e (it2e.begin ());
826
typename E::const_iterator1 it1e_end (it2e.end ());
828
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
829
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
830
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
831
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
833
difference_type it1_size (it1_end - it1);
834
difference_type it1e_size (it1e_end - it1e);
835
difference_type diff1 (0);
836
if (it1_size > 0 && it1e_size > 0) {
837
diff1 = it1.index1 () - it1e.index1 ();
838
difference_type size1 = (std::min) (diff1, it1e_size);
844
size1 = (std::min) (- diff1, it1_size);
847
if (!functor_type::computed) {
848
while (-- size1 >= 0) // zeroing
849
functor_type::apply (*it1, value_type/*zero*/()), ++ it1;
856
difference_type size1 ((std::min) (it1_size, it1e_size));
859
while (-- size1 >= 0)
860
functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
862
if (!functor_type::computed) {
863
while (-- size1 >= 0) // zeroing
864
functor_type::apply (*it1, value_type/*zero*/()), ++ it1;
871
if (!functor_type::computed) {
872
while (-- size2 >= 0) { // zeroing
873
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
874
typename M::iterator1 it1 (it2.begin ());
875
typename M::iterator1 it1_end (it2.end ());
877
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
878
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
880
difference_type size1 (it1_end - it1);
881
while (-- size1 >= 0)
882
functor_type::apply (*it1, value_type/*zero*/()), ++ it1;
888
#if BOOST_UBLAS_TYPE_CHECK
889
if (! disable_type_check<bool>::value)
890
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
893
// Sparse row major case
894
template<template <class T1, class T2> class F, class R, class M, class E>
895
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
896
void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, row_major_tag) {
897
typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
898
// R unnecessary, make_conformant not required
899
BOOST_STATIC_ASSERT ((!functor_type::computed));
900
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
901
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
902
typedef typename M::value_type value_type;
903
// Sparse type has no numeric constraints to check
906
typename E::const_iterator1 it1e (e ().begin1 ());
907
typename E::const_iterator1 it1e_end (e ().end1 ());
908
while (it1e != it1e_end) {
909
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
910
typename E::const_iterator2 it2e (it1e.begin ());
911
typename E::const_iterator2 it2e_end (it1e.end ());
913
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
914
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
916
while (it2e != it2e_end) {
917
value_type t (*it2e);
918
if (t != value_type/*zero*/())
919
m.insert_element (it2e.index1 (), it2e.index2 (), t);
925
// Sparse column major case
926
template<template <class T1, class T2> class F, class R, class M, class E>
927
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
928
void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, column_major_tag) {
929
typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
930
// R unnecessary, make_conformant not required
931
BOOST_STATIC_ASSERT ((!functor_type::computed));
932
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
933
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
934
typedef typename M::value_type value_type;
935
// Sparse type has no numeric constraints to check
938
typename E::const_iterator2 it2e (e ().begin2 ());
939
typename E::const_iterator2 it2e_end (e ().end2 ());
940
while (it2e != it2e_end) {
941
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
942
typename E::const_iterator1 it1e (it2e.begin ());
943
typename E::const_iterator1 it1e_end (it2e.end ());
945
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
946
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
948
while (it1e != it1e_end) {
949
value_type t (*it1e);
950
if (t != value_type/*zero*/())
951
m.insert_element (it1e.index1 (), it1e.index2 (), t);
957
// Sparse proxy or functional row major case
958
template<template <class T1, class T2> class F, class R, class M, class E>
959
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
960
void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
961
typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
962
typedef R conformant_restrict_type;
963
typedef typename M::size_type size_type;
964
typedef typename M::difference_type difference_type;
965
typedef typename M::value_type value_type;
966
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
967
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
968
#if BOOST_UBLAS_TYPE_CHECK
969
matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
970
indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
971
indexing_matrix_assign<F> (cm, e, row_major_tag ());
973
detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
975
typename M::iterator1 it1 (m.begin1 ());
976
typename M::iterator1 it1_end (m.end1 ());
977
typename E::const_iterator1 it1e (e ().begin1 ());
978
typename E::const_iterator1 it1e_end (e ().end1 ());
979
while (it1 != it1_end && it1e != it1e_end) {
980
difference_type compare = it1.index1 () - it1e.index1 ();
982
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
983
typename M::iterator2 it2 (it1.begin ());
984
typename M::iterator2 it2_end (it1.end ());
985
typename E::const_iterator2 it2e (it1e.begin ());
986
typename E::const_iterator2 it2e_end (it1e.end ());
988
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
989
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
990
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
991
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
993
if (it2 != it2_end && it2e != it2e_end) {
994
size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
996
difference_type compare = it2_index - it2e_index;
998
functor_type::apply (*it2, *it2e);
1000
if (it2 != it2_end && it2e != it2e_end) {
1001
it2_index = it2.index2 ();
1002
it2e_index = it2e.index2 ();
1005
} else if (compare < 0) {
1006
if (!functor_type::computed) {
1007
functor_type::apply (*it2, value_type/*zero*/());
1010
increment (it2, it2_end, - compare);
1012
it2_index = it2.index2 ();
1015
} else if (compare > 0) {
1016
increment (it2e, it2e_end, compare);
1017
if (it2e != it2e_end)
1018
it2e_index = it2e.index2 ();
1024
if (!functor_type::computed) {
1025
while (it2 != it2_end) { // zeroing
1026
functor_type::apply (*it2, value_type/*zero*/());
1033
} else if (compare < 0) {
1034
if (!functor_type::computed) {
1035
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1036
typename M::iterator2 it2 (it1.begin ());
1037
typename M::iterator2 it2_end (it1.end ());
1039
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1040
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1042
while (it2 != it2_end) { // zeroing
1043
functor_type::apply (*it2, value_type/*zero*/());
1048
increment (it1, it1_end, - compare);
1050
} else if (compare > 0) {
1051
increment (it1e, it1e_end, compare);
1054
if (!functor_type::computed) {
1055
while (it1 != it1_end) {
1056
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1057
typename M::iterator2 it2 (it1.begin ());
1058
typename M::iterator2 it2_end (it1.end ());
1060
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1061
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1063
while (it2 != it2_end) { // zeroing
1064
functor_type::apply (*it2, value_type/*zero*/());
1072
#if BOOST_UBLAS_TYPE_CHECK
1073
if (! disable_type_check<bool>::value)
1074
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
1077
// Sparse proxy or functional column major case
1078
template<template <class T1, class T2> class F, class R, class M, class E>
1079
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1080
void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
1081
typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
1082
typedef R conformant_restrict_type;
1083
typedef typename M::size_type size_type;
1084
typedef typename M::difference_type difference_type;
1085
typedef typename M::value_type value_type;
1086
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
1087
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
1088
#if BOOST_UBLAS_TYPE_CHECK
1089
matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
1090
indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
1091
indexing_matrix_assign<F> (cm, e, column_major_tag ());
1093
detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
1095
typename M::iterator2 it2 (m.begin2 ());
1096
typename M::iterator2 it2_end (m.end2 ());
1097
typename E::const_iterator2 it2e (e ().begin2 ());
1098
typename E::const_iterator2 it2e_end (e ().end2 ());
1099
while (it2 != it2_end && it2e != it2e_end) {
1100
difference_type compare = it2.index2 () - it2e.index2 ();
1102
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1103
typename M::iterator1 it1 (it2.begin ());
1104
typename M::iterator1 it1_end (it2.end ());
1105
typename E::const_iterator1 it1e (it2e.begin ());
1106
typename E::const_iterator1 it1e_end (it2e.end ());
1108
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1109
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1110
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
1111
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
1113
if (it1 != it1_end && it1e != it1e_end) {
1114
size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
1116
difference_type compare = it1_index - it1e_index;
1118
functor_type::apply (*it1, *it1e);
1120
if (it1 != it1_end && it1e != it1e_end) {
1121
it1_index = it1.index1 ();
1122
it1e_index = it1e.index1 ();
1125
} else if (compare < 0) {
1126
if (!functor_type::computed) {
1127
functor_type::apply (*it1, value_type/*zero*/()); // zeroing
1130
increment (it1, it1_end, - compare);
1132
it1_index = it1.index1 ();
1135
} else if (compare > 0) {
1136
increment (it1e, it1e_end, compare);
1137
if (it1e != it1e_end)
1138
it1e_index = it1e.index1 ();
1144
if (!functor_type::computed) {
1145
while (it1 != it1_end) { // zeroing
1146
functor_type::apply (*it1, value_type/*zero*/());
1153
} else if (compare < 0) {
1154
if (!functor_type::computed) {
1155
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1156
typename M::iterator1 it1 (it2.begin ());
1157
typename M::iterator1 it1_end (it2.end ());
1159
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1160
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1162
while (it1 != it1_end) { // zeroing
1163
functor_type::apply (*it1, value_type/*zero*/());
1168
increment (it2, it2_end, - compare);
1170
} else if (compare > 0) {
1171
increment (it2e, it2e_end, compare);
1174
if (!functor_type::computed) {
1175
while (it2 != it2_end) {
1176
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1177
typename M::iterator1 it1 (it2.begin ());
1178
typename M::iterator1 it1_end (it2.end ());
1180
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1181
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1183
while (it1 != it1_end) { // zeroing
1184
functor_type::apply (*it1, value_type/*zero*/());
1192
#if BOOST_UBLAS_TYPE_CHECK
1193
if (! disable_type_check<bool>::value)
1194
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
1199
template<template <class T1, class T2> class F, class M, class E>
1201
void matrix_assign (M &m, const matrix_expression<E> &e) {
1202
typedef typename matrix_assign_traits<typename M::storage_category,
1203
F<typename M::reference, typename E::value_type>::computed,
1204
typename E::const_iterator1::iterator_category,
1205
typename E::const_iterator2::iterator_category>::storage_category storage_category;
1206
// give preference to matrix M's orientation if known
1207
typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1208
typename E::orientation_category ,
1209
typename M::orientation_category >::type orientation_category;
1210
typedef basic_full<typename M::size_type> unrestricted;
1211
matrix_assign<F, unrestricted> (m, e, storage_category (), orientation_category ());
1213
template<template <class T1, class T2> class F, class R, class M, class E>
1215
void matrix_assign (M &m, const matrix_expression<E> &e) {
1216
typedef R conformant_restrict_type;
1217
typedef typename matrix_assign_traits<typename M::storage_category,
1218
F<typename M::reference, typename E::value_type>::computed,
1219
typename E::const_iterator1::iterator_category,
1220
typename E::const_iterator2::iterator_category>::storage_category storage_category;
1221
// give preference to matrix M's orientation if known
1222
typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1223
typename E::orientation_category ,
1224
typename M::orientation_category >::type orientation_category;
1225
matrix_assign<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
1228
template<class SC, class RI1, class RI2>
1229
struct matrix_swap_traits {
1230
typedef SC storage_category;
1234
struct matrix_swap_traits<dense_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
1235
typedef sparse_proxy_tag storage_category;
1239
struct matrix_swap_traits<packed_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
1240
typedef sparse_proxy_tag storage_category;
1243
// Dense (proxy) row major case
1244
template<template <class T1, class T2> class F, class R, class M, class E>
1245
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1246
void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, row_major_tag) {
1247
typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
1248
// R unnecessary, make_conformant not required
1249
typedef typename M::size_type size_type;
1250
typedef typename M::difference_type difference_type;
1251
typename M::iterator1 it1 (m.begin1 ());
1252
typename E::iterator1 it1e (e ().begin1 ());
1253
difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), size_type (e ().end1 () - it1e)));
1254
while (-- size1 >= 0) {
1255
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1256
typename M::iterator2 it2 (it1.begin ());
1257
typename E::iterator2 it2e (it1e.begin ());
1258
difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), size_type (it1e.end () - it2e)));
1260
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1261
typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1262
difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), size_type (end (it1e, iterator1_tag ()) - it2e)));
1264
while (-- size2 >= 0)
1265
functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
1269
// Dense (proxy) column major case
1270
template<template <class T1, class T2> class F, class R, class M, class E>
1271
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1272
void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, column_major_tag) {
1273
typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
1274
// R unnecessary, make_conformant not required
1275
typedef typename M::size_type size_type;
1276
typedef typename M::difference_type difference_type;
1277
typename M::iterator2 it2 (m.begin2 ());
1278
typename E::iterator2 it2e (e ().begin2 ());
1279
difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), size_type (e ().end2 () - it2e)));
1280
while (-- size2 >= 0) {
1281
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1282
typename M::iterator1 it1 (it2.begin ());
1283
typename E::iterator1 it1e (it2e.begin ());
1284
difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), size_type (it2e.end () - it1e)));
1286
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1287
typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1288
difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), size_type (end (it2e, iterator2_tag ()) - it1e)));
1290
while (-- size1 >= 0)
1291
functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
1295
// Packed (proxy) row major case
1296
template<template <class T1, class T2> class F, class R, class M, class E>
1297
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1298
void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
1299
typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
1300
// R unnecessary, make_conformant not required
1301
typedef typename M::size_type size_type;
1302
typedef typename M::difference_type difference_type;
1303
typename M::iterator1 it1 (m.begin1 ());
1304
typename E::iterator1 it1e (e ().begin1 ());
1305
difference_type size1 (BOOST_UBLAS_SAME (m.end1 () - it1, e ().end1 () - it1e));
1306
while (-- size1 >= 0) {
1307
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1308
typename M::iterator2 it2 (it1.begin ());
1309
typename E::iterator2 it2e (it1e.begin ());
1310
difference_type size2 (BOOST_UBLAS_SAME (it1.end () - it2, it1e.end () - it2e));
1312
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1313
typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1314
difference_type size2 (BOOST_UBLAS_SAME (end (it1, iterator1_tag ()) - it2, end (it1e, iterator1_tag ()) - it2e));
1316
while (-- size2 >= 0)
1317
functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
1321
// Packed (proxy) column major case
1322
template<template <class T1, class T2> class F, class R, class M, class E>
1323
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1324
void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
1325
typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
1326
// R unnecessary, make_conformant not required
1327
typedef typename M::size_type size_type;
1328
typedef typename M::difference_type difference_type;
1329
typename M::iterator2 it2 (m.begin2 ());
1330
typename E::iterator2 it2e (e ().begin2 ());
1331
difference_type size2 (BOOST_UBLAS_SAME (m.end2 () - it2, e ().end2 () - it2e));
1332
while (-- size2 >= 0) {
1333
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1334
typename M::iterator1 it1 (it2.begin ());
1335
typename E::iterator1 it1e (it2e.begin ());
1336
difference_type size1 (BOOST_UBLAS_SAME (it2.end () - it1, it2e.end () - it1e));
1338
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1339
typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1340
difference_type size1 (BOOST_UBLAS_SAME (end (it2, iterator2_tag ()) - it1, end (it2e, iterator2_tag ()) - it1e));
1342
while (-- size1 >= 0)
1343
functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
1347
// Sparse (proxy) row major case
1348
template<template <class T1, class T2> class F, class R, class M, class E>
1349
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1350
void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
1351
typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
1352
typedef R conformant_restrict_type;
1353
typedef typename M::size_type size_type;
1354
typedef typename M::difference_type difference_type;
1355
typedef typename M::value_type value_type;
1356
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
1357
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
1359
detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
1360
// FIXME should be a seperate restriction for E
1361
detail::make_conformant (e (), m, row_major_tag (), conformant_restrict_type ());
1363
typename M::iterator1 it1 (m.begin1 ());
1364
typename M::iterator1 it1_end (m.end1 ());
1365
typename E::iterator1 it1e (e ().begin1 ());
1366
typename E::iterator1 it1e_end (e ().end1 ());
1367
while (it1 != it1_end && it1e != it1e_end) {
1368
difference_type compare = it1.index1 () - it1e.index1 ();
1370
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1371
typename M::iterator2 it2 (it1.begin ());
1372
typename M::iterator2 it2_end (it1.end ());
1373
typename E::iterator2 it2e (it1e.begin ());
1374
typename E::iterator2 it2e_end (it1e.end ());
1376
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1377
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1378
typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1379
typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
1381
if (it2 != it2_end && it2e != it2e_end) {
1382
size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
1384
difference_type compare = it2_index - it2e_index;
1386
functor_type::apply (*it2, *it2e);
1388
if (it2 != it2_end && it2e != it2e_end) {
1389
it2_index = it2.index2 ();
1390
it2e_index = it2e.index2 ();
1393
} else if (compare < 0) {
1394
increment (it2, it2_end, - compare);
1396
it2_index = it2.index2 ();
1399
} else if (compare > 0) {
1400
increment (it2e, it2e_end, compare);
1401
if (it2e != it2e_end)
1402
it2e_index = it2e.index2 ();
1408
#if BOOST_UBLAS_TYPE_CHECK
1409
increment (it2e, it2e_end);
1410
increment (it2, it2_end);
1413
} else if (compare < 0) {
1414
#if BOOST_UBLAS_TYPE_CHECK
1415
while (it1.index1 () < it1e.index1 ()) {
1416
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1417
typename M::iterator2 it2 (it1.begin ());
1418
typename M::iterator2 it2_end (it1.end ());
1420
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1421
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1423
increment (it2, it2_end);
1427
increment (it1, it1_end, - compare);
1429
} else if (compare > 0) {
1430
#if BOOST_UBLAS_TYPE_CHECK
1431
while (it1e.index1 () < it1.index1 ()) {
1432
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1433
typename E::iterator2 it2e (it1e.begin ());
1434
typename E::iterator2 it2e_end (it1e.end ());
1436
typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1437
typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
1439
increment (it2e, it2e_end);
1443
increment (it1e, it1e_end, compare);
1447
#if BOOST_UBLAS_TYPE_CHECK
1448
while (it1e != it1e_end) {
1449
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1450
typename E::iterator2 it2e (it1e.begin ());
1451
typename E::iterator2 it2e_end (it1e.end ());
1453
typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1454
typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
1456
increment (it2e, it2e_end);
1459
while (it1 != it1_end) {
1460
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1461
typename M::iterator2 it2 (it1.begin ());
1462
typename M::iterator2 it2_end (it1.end ());
1464
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1465
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1467
increment (it2, it2_end);
1472
// Sparse (proxy) column major case
1473
template<template <class T1, class T2> class F, class R, class M, class E>
1474
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1475
void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
1476
typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
1477
typedef R conformant_restrict_type;
1478
typedef typename M::size_type size_type;
1479
typedef typename M::difference_type difference_type;
1480
typedef typename M::value_type value_type;
1481
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
1482
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
1484
detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
1485
// FIXME should be a seperate restriction for E
1486
detail::make_conformant (e (), m, column_major_tag (), conformant_restrict_type ());
1488
typename M::iterator2 it2 (m.begin2 ());
1489
typename M::iterator2 it2_end (m.end2 ());
1490
typename E::iterator2 it2e (e ().begin2 ());
1491
typename E::iterator2 it2e_end (e ().end2 ());
1492
while (it2 != it2_end && it2e != it2e_end) {
1493
difference_type compare = it2.index2 () - it2e.index2 ();
1495
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1496
typename M::iterator1 it1 (it2.begin ());
1497
typename M::iterator1 it1_end (it2.end ());
1498
typename E::iterator1 it1e (it2e.begin ());
1499
typename E::iterator1 it1e_end (it2e.end ());
1501
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1502
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1503
typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1504
typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
1506
if (it1 != it1_end && it1e != it1e_end) {
1507
size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
1509
difference_type compare = it1_index - it1e_index;
1511
functor_type::apply (*it1, *it1e);
1513
if (it1 != it1_end && it1e != it1e_end) {
1514
it1_index = it1.index1 ();
1515
it1e_index = it1e.index1 ();
1518
} else if (compare < 0) {
1519
increment (it1, it1_end, - compare);
1521
it1_index = it1.index1 ();
1524
} else if (compare > 0) {
1525
increment (it1e, it1e_end, compare);
1526
if (it1e != it1e_end)
1527
it1e_index = it1e.index1 ();
1533
#if BOOST_UBLAS_TYPE_CHECK
1534
increment (it1e, it1e_end);
1535
increment (it1, it1_end);
1538
} else if (compare < 0) {
1539
#if BOOST_UBLAS_TYPE_CHECK
1540
while (it2.index2 () < it2e.index2 ()) {
1541
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1542
typename M::iterator1 it1 (it2.begin ());
1543
typename M::iterator1 it1_end (it2.end ());
1545
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1546
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1548
increment (it1, it1_end);
1552
increment (it2, it2_end, - compare);
1554
} else if (compare > 0) {
1555
#if BOOST_UBLAS_TYPE_CHECK
1556
while (it2e.index2 () < it2.index2 ()) {
1557
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1558
typename E::iterator1 it1e (it2e.begin ());
1559
typename E::iterator1 it1e_end (it2e.end ());
1561
typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1562
typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
1564
increment (it1e, it1e_end);
1568
increment (it2e, it2e_end, compare);
1572
#if BOOST_UBLAS_TYPE_CHECK
1573
while (it2e != it2e_end) {
1574
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1575
typename E::iterator1 it1e (it2e.begin ());
1576
typename E::iterator1 it1e_end (it2e.end ());
1578
typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1579
typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
1581
increment (it1e, it1e_end);
1584
while (it2 != it2_end) {
1585
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1586
typename M::iterator1 it1 (it2.begin ());
1587
typename M::iterator1 it1_end (it2.end ());
1589
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1590
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1592
increment (it1, it1_end);
1599
template<template <class T1, class T2> class F, class M, class E>
1601
void matrix_swap (M &m, matrix_expression<E> &e) {
1602
typedef typename matrix_swap_traits<typename M::storage_category,
1603
typename E::const_iterator1::iterator_category,
1604
typename E::const_iterator2::iterator_category>::storage_category storage_category;
1605
// give preference to matrix M's orientation if known
1606
typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1607
typename E::orientation_category ,
1608
typename M::orientation_category >::type orientation_category;
1609
typedef basic_full<typename M::size_type> unrestricted;
1610
matrix_swap<F, unrestricted> (m, e, storage_category (), orientation_category ());
1612
template<template <class T1, class T2> class F, class R, class M, class E>
1614
void matrix_swap (M &m, matrix_expression<E> &e) {
1615
typedef R conformant_restrict_type;
1616
typedef typename matrix_swap_traits<typename M::storage_category,
1617
typename E::const_iterator1::iterator_category,
1618
typename E::const_iterator2::iterator_category>::storage_category storage_category;
1619
// give preference to matrix M's orientation if known
1620
typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1621
typename E::orientation_category ,
1622
typename M::orientation_category >::type orientation_category;
1623
matrix_swap<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
2
// Copyright (c) 2000-2002
3
// Joerg Walter, Mathias Koch
5
// Distributed under the Boost Software License, Version 1.0. (See
6
// accompanying file LICENSE_1_0.txt or copy at
7
// http://www.boost.org/LICENSE_1_0.txt)
9
// The authors gratefully acknowledge the support of
10
// GeNeSys mbH & Co. KG in producing this work.
13
#ifndef _BOOST_UBLAS_MATRIX_ASSIGN_
14
#define _BOOST_UBLAS_MATRIX_ASSIGN_
16
// Required for make_conformant storage
19
// Iterators based on ideas of Jeremy Siek
21
namespace boost { namespace numeric { namespace ublas {
24
// Weak equality check - useful to compare equality two arbitary matrix expression results.
25
// Since the actual expressions are unknown, we check for and arbitary error bound
26
// on the relative error.
27
// For a linear expression the infinity norm makes sense as we do not know how the elements will be
28
// combined in the expression. False positive results are inevitable for arbirary expressions!
29
template<class E1, class E2, class S>
31
bool equals (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2, S epsilon, S min_norm) {
32
return norm_inf (e1 - e2) < epsilon *
33
std::max<S> (std::max<S> (norm_inf (e1), norm_inf (e2)), min_norm);
36
template<class E1, class E2>
38
bool expression_type_check (const matrix_expression<E1> &e1, const matrix_expression<E2> &e2) {
39
typedef typename type_traits<typename promote_traits<typename E1::value_type,
40
typename E2::value_type>::promote_type>::real_type real_type;
41
return equals (e1, e2, BOOST_UBLAS_TYPE_CHECK_EPSILON, BOOST_UBLAS_TYPE_CHECK_MIN);
45
template<class M, class E, class R>
46
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
47
void make_conformant (M &m, const matrix_expression<E> &e, row_major_tag, R) {
48
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
49
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
50
typedef R conformant_restrict_type;
51
typedef typename M::size_type size_type;
52
typedef typename M::difference_type difference_type;
53
typedef typename M::value_type value_type;
54
// FIXME unbounded_array with push_back maybe better
55
std::vector<std::pair<size_type, size_type> > index;
56
typename M::iterator1 it1 (m.begin1 ());
57
typename M::iterator1 it1_end (m.end1 ());
58
typename E::const_iterator1 it1e (e ().begin1 ());
59
typename E::const_iterator1 it1e_end (e ().end1 ());
60
while (it1 != it1_end && it1e != it1e_end) {
61
difference_type compare = it1.index1 () - it1e.index1 ();
63
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
64
typename M::iterator2 it2 (it1.begin ());
65
typename M::iterator2 it2_end (it1.end ());
66
typename E::const_iterator2 it2e (it1e.begin ());
67
typename E::const_iterator2 it2e_end (it1e.end ());
69
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
70
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
71
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
72
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
74
if (it2 != it2_end && it2e != it2e_end) {
75
size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
77
difference_type compare = it2_index - it2e_index;
80
if (it2 != it2_end && it2e != it2e_end) {
81
it2_index = it2.index2 ();
82
it2e_index = it2e.index2 ();
85
} else if (compare < 0) {
86
increment (it2, it2_end, - compare);
88
it2_index = it2.index2 ();
91
} else if (compare > 0) {
92
if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
93
if (*it2e != value_type/*zero*/())
94
index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
97
it2e_index = it2e.index2 ();
103
while (it2e != it2e_end) {
104
if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
105
if (*it2e != value_type/*zero*/())
106
index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
110
} else if (compare < 0) {
111
increment (it1, it1_end, - compare);
112
} else if (compare > 0) {
113
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
114
typename E::const_iterator2 it2e (it1e.begin ());
115
typename E::const_iterator2 it2e_end (it1e.end ());
117
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
118
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
120
while (it2e != it2e_end) {
121
if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
122
if (*it2e != value_type/*zero*/())
123
index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
129
while (it1e != it1e_end) {
130
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
131
typename E::const_iterator2 it2e (it1e.begin ());
132
typename E::const_iterator2 it2e_end (it1e.end ());
134
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
135
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
137
while (it2e != it2e_end) {
138
if (conformant_restrict_type::other (it2e.index1 (), it2e.index2 ()))
139
if (*it2e != value_type/*zero*/())
140
index.push_back (std::pair<size_type, size_type> (it2e.index1 (), it2e.index2 ()));
145
// ISSUE proxies require insert_element
146
for (size_type k = 0; k < index.size (); ++ k)
147
m (index [k].first, index [k].second) = value_type/*zero*/();
149
template<class M, class E, class R>
150
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
151
void make_conformant (M &m, const matrix_expression<E> &e, column_major_tag, R) {
152
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
153
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
154
typedef R conformant_restrict_type;
155
typedef typename M::size_type size_type;
156
typedef typename M::difference_type difference_type;
157
typedef typename M::value_type value_type;
158
std::vector<std::pair<size_type, size_type> > index;
159
typename M::iterator2 it2 (m.begin2 ());
160
typename M::iterator2 it2_end (m.end2 ());
161
typename E::const_iterator2 it2e (e ().begin2 ());
162
typename E::const_iterator2 it2e_end (e ().end2 ());
163
while (it2 != it2_end && it2e != it2e_end) {
164
difference_type compare = it2.index2 () - it2e.index2 ();
166
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
167
typename M::iterator1 it1 (it2.begin ());
168
typename M::iterator1 it1_end (it2.end ());
169
typename E::const_iterator1 it1e (it2e.begin ());
170
typename E::const_iterator1 it1e_end (it2e.end ());
172
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
173
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
174
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
175
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
177
if (it1 != it1_end && it1e != it1e_end) {
178
size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
180
difference_type compare = it1_index - it1e_index;
183
if (it1 != it1_end && it1e != it1e_end) {
184
it1_index = it1.index1 ();
185
it1e_index = it1e.index1 ();
188
} else if (compare < 0) {
189
increment (it1, it1_end, - compare);
191
it1_index = it1.index1 ();
194
} else if (compare > 0) {
195
if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
196
if (*it1e != value_type/*zero*/())
197
index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
199
if (it1e != it1e_end)
200
it1e_index = it1e.index1 ();
206
while (it1e != it1e_end) {
207
if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
208
if (*it1e != value_type/*zero*/())
209
index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
213
} else if (compare < 0) {
214
increment (it2, it2_end, - compare);
215
} else if (compare > 0) {
216
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
217
typename E::const_iterator1 it1e (it2e.begin ());
218
typename E::const_iterator1 it1e_end (it2e.end ());
220
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
221
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
223
while (it1e != it1e_end) {
224
if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
225
if (*it1e != value_type/*zero*/())
226
index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
232
while (it2e != it2e_end) {
233
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
234
typename E::const_iterator1 it1e (it2e.begin ());
235
typename E::const_iterator1 it1e_end (it2e.end ());
237
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
238
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
240
while (it1e != it1e_end) {
241
if (conformant_restrict_type::other (it1e.index1 (), it1e.index2 ()))
242
if (*it1e != value_type/*zero*/())
243
index.push_back (std::pair<size_type, size_type> (it1e.index1 (), it1e.index2 ()));
248
// ISSUE proxies require insert_element
249
for (size_type k = 0; k < index.size (); ++ k)
250
m (index [k].first, index [k].second) = value_type/*zero*/();
256
// Explicitly iterating row major
257
template<template <class T1, class T2> class F, class M, class T>
258
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
259
void iterating_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
260
typedef F<typename M::iterator2::reference, T> functor_type;
261
typedef typename M::difference_type difference_type;
262
difference_type size1 (m.size1 ());
263
difference_type size2 (m.size2 ());
264
typename M::iterator1 it1 (m.begin1 ());
265
BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
266
while (-- size1 >= 0) {
267
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
268
typename M::iterator2 it2 (it1.begin ());
270
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
272
BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
273
difference_type temp_size2 (size2);
274
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
275
while (-- temp_size2 >= 0)
276
functor_type::apply (*it2, t), ++ it2;
278
DD (temp_size2, 4, r, (functor_type::apply (*it2, t), ++ it2));
283
// Explicitly iterating column major
284
template<template <class T1, class T2> class F, class M, class T>
285
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
286
void iterating_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
287
typedef F<typename M::iterator1::reference, T> functor_type;
288
typedef typename M::difference_type difference_type;
289
difference_type size2 (m.size2 ());
290
difference_type size1 (m.size1 ());
291
typename M::iterator2 it2 (m.begin2 ());
292
BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
293
while (-- size2 >= 0) {
294
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
295
typename M::iterator1 it1 (it2.begin ());
297
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
299
BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
300
difference_type temp_size1 (size1);
301
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
302
while (-- temp_size1 >= 0)
303
functor_type::apply (*it1, t), ++ it1;
305
DD (temp_size1, 4, r, (functor_type::apply (*it1, t), ++ it1));
310
// Explicitly indexing row major
311
template<template <class T1, class T2> class F, class M, class T>
312
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
313
void indexing_matrix_assign_scalar (M &m, const T &t, row_major_tag) {
314
typedef F<typename M::reference, T> functor_type;
315
typedef typename M::size_type size_type;
316
size_type size1 (m.size1 ());
317
size_type size2 (m.size2 ());
318
for (size_type i = 0; i < size1; ++ i) {
319
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
320
for (size_type j = 0; j < size2; ++ j)
321
functor_type::apply (m (i, j), t);
324
DD (size2, 4, r, (functor_type::apply (m (i, j), t), ++ j));
328
// Explicitly indexing column major
329
template<template <class T1, class T2> class F, class M, class T>
330
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
331
void indexing_matrix_assign_scalar (M &m, const T &t, column_major_tag) {
332
typedef F<typename M::reference, T> functor_type;
333
typedef typename M::size_type size_type;
334
size_type size2 (m.size2 ());
335
size_type size1 (m.size1 ());
336
for (size_type j = 0; j < size2; ++ j) {
337
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
338
for (size_type i = 0; i < size1; ++ i)
339
functor_type::apply (m (i, j), t);
342
DD (size1, 4, r, (functor_type::apply (m (i, j), t), ++ i));
347
// Dense (proxy) case
348
template<template <class T1, class T2> class F, class M, class T, class C>
349
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
350
void matrix_assign_scalar (M &m, const T &t, dense_proxy_tag, C) {
351
typedef C orientation_category;
352
#ifdef BOOST_UBLAS_USE_INDEXING
353
indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
354
#elif BOOST_UBLAS_USE_ITERATING
355
iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
357
typedef typename M::size_type size_type;
358
size_type size1 (m.size1 ());
359
size_type size2 (m.size2 ());
360
if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
361
size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
362
iterating_matrix_assign_scalar<F> (m, t, orientation_category ());
364
indexing_matrix_assign_scalar<F> (m, t, orientation_category ());
367
// Packed (proxy) row major case
368
template<template <class T1, class T2> class F, class M, class T>
369
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
370
void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, row_major_tag) {
371
typedef F<typename M::iterator2::reference, T> functor_type;
372
typedef typename M::difference_type difference_type;
373
typename M::iterator1 it1 (m.begin1 ());
374
difference_type size1 (m.end1 () - it1);
375
while (-- size1 >= 0) {
376
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
377
typename M::iterator2 it2 (it1.begin ());
378
difference_type size2 (it1.end () - it2);
380
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
381
difference_type size2 (end (it1, iterator1_tag ()) - it2);
383
while (-- size2 >= 0)
384
functor_type::apply (*it2, t), ++ it2;
388
// Packed (proxy) column major case
389
template<template <class T1, class T2> class F, class M, class T>
390
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
391
void matrix_assign_scalar (M &m, const T &t, packed_proxy_tag, column_major_tag) {
392
typedef F<typename M::iterator1::reference, T> functor_type;
393
typedef typename M::difference_type difference_type;
394
typename M::iterator2 it2 (m.begin2 ());
395
difference_type size2 (m.end2 () - it2);
396
while (-- size2 >= 0) {
397
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
398
typename M::iterator1 it1 (it2.begin ());
399
difference_type size1 (it2.end () - it1);
401
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
402
difference_type size1 (end (it2, iterator2_tag ()) - it1);
404
while (-- size1 >= 0)
405
functor_type::apply (*it1, t), ++ it1;
409
// Sparse (proxy) row major case
410
template<template <class T1, class T2> class F, class M, class T>
411
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
412
void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, row_major_tag) {
413
typedef F<typename M::iterator2::reference, T> functor_type;
414
typename M::iterator1 it1 (m.begin1 ());
415
typename M::iterator1 it1_end (m.end1 ());
416
while (it1 != it1_end) {
417
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
418
typename M::iterator2 it2 (it1.begin ());
419
typename M::iterator2 it2_end (it1.end ());
421
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
422
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
424
while (it2 != it2_end)
425
functor_type::apply (*it2, t), ++ it2;
429
// Sparse (proxy) column major case
430
template<template <class T1, class T2> class F, class M, class T>
431
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
432
void matrix_assign_scalar (M &m, const T &t, sparse_proxy_tag, column_major_tag) {
433
typedef F<typename M::iterator1::reference, T> functor_type;
434
typename M::iterator2 it2 (m.begin2 ());
435
typename M::iterator2 it2_end (m.end2 ());
436
while (it2 != it2_end) {
437
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
438
typename M::iterator1 it1 (it2.begin ());
439
typename M::iterator1 it1_end (it2.end ());
441
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
442
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
444
while (it1 != it1_end)
445
functor_type::apply (*it1, t), ++ it1;
451
template<template <class T1, class T2> class F, class M, class T>
453
void matrix_assign_scalar (M &m, const T &t) {
454
typedef typename M::storage_category storage_category;
455
typedef typename M::orientation_category orientation_category;
456
matrix_assign_scalar<F> (m, t, storage_category (), orientation_category ());
459
template<class SC, bool COMPUTED, class RI1, class RI2>
460
struct matrix_assign_traits {
461
typedef SC storage_category;
464
template<bool COMPUTED>
465
struct matrix_assign_traits<dense_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
466
typedef packed_tag storage_category;
469
struct matrix_assign_traits<dense_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
470
typedef sparse_tag storage_category;
473
struct matrix_assign_traits<dense_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
474
typedef sparse_proxy_tag storage_category;
477
template<bool COMPUTED>
478
struct matrix_assign_traits<dense_proxy_tag, COMPUTED, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
479
typedef packed_proxy_tag storage_category;
481
template<bool COMPUTED>
482
struct matrix_assign_traits<dense_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
483
typedef sparse_proxy_tag storage_category;
487
struct matrix_assign_traits<packed_tag, false, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
488
typedef sparse_tag storage_category;
491
struct matrix_assign_traits<packed_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
492
typedef sparse_proxy_tag storage_category;
495
template<bool COMPUTED>
496
struct matrix_assign_traits<packed_proxy_tag, COMPUTED, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
497
typedef sparse_proxy_tag storage_category;
501
struct matrix_assign_traits<sparse_tag, true, dense_random_access_iterator_tag, dense_random_access_iterator_tag> {
502
typedef sparse_proxy_tag storage_category;
505
struct matrix_assign_traits<sparse_tag, true, packed_random_access_iterator_tag, packed_random_access_iterator_tag> {
506
typedef sparse_proxy_tag storage_category;
509
struct matrix_assign_traits<sparse_tag, true, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
510
typedef sparse_proxy_tag storage_category;
513
// Explicitly iterating row major
514
template<template <class T1, class T2> class F, class M, class E>
515
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
516
void iterating_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
517
typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
518
typedef typename M::difference_type difference_type;
519
difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
520
difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
521
typename M::iterator1 it1 (m.begin1 ());
522
BOOST_UBLAS_CHECK (size2 == 0 || m.end1 () - it1 == size1, bad_size ());
523
typename E::const_iterator1 it1e (e ().begin1 ());
524
BOOST_UBLAS_CHECK (size2 == 0 || e ().end1 () - it1e == size1, bad_size ());
525
while (-- size1 >= 0) {
526
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
527
typename M::iterator2 it2 (it1.begin ());
528
typename E::const_iterator2 it2e (it1e.begin ());
530
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
531
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
533
BOOST_UBLAS_CHECK (it1.end () - it2 == size2, bad_size ());
534
BOOST_UBLAS_CHECK (it1e.end () - it2e == size2, bad_size ());
535
difference_type temp_size2 (size2);
536
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
537
while (-- temp_size2 >= 0)
538
functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
540
DD (temp_size2, 2, r, (functor_type::apply (*it2, *it2e), ++ it2, ++ it2e));
545
// Explicitly iterating column major
546
template<template <class T1, class T2> class F, class M, class E>
547
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
548
void iterating_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
549
typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
550
typedef typename M::difference_type difference_type;
551
difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
552
difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
553
typename M::iterator2 it2 (m.begin2 ());
554
BOOST_UBLAS_CHECK (size1 == 0 || m.end2 () - it2 == size2, bad_size ());
555
typename E::const_iterator2 it2e (e ().begin2 ());
556
BOOST_UBLAS_CHECK (size1 == 0 || e ().end2 () - it2e == size2, bad_size ());
557
while (-- size2 >= 0) {
558
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
559
typename M::iterator1 it1 (it2.begin ());
560
typename E::const_iterator1 it1e (it2e.begin ());
562
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
563
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
565
BOOST_UBLAS_CHECK (it2.end () - it1 == size1, bad_size ());
566
BOOST_UBLAS_CHECK (it2e.end () - it1e == size1, bad_size ());
567
difference_type temp_size1 (size1);
568
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
569
while (-- temp_size1 >= 0)
570
functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
572
DD (temp_size1, 2, r, (functor_type::apply (*it1, *it1e), ++ it1, ++ it1e));
577
// Explicitly indexing row major
578
template<template <class T1, class T2> class F, class M, class E>
579
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
580
void indexing_matrix_assign (M &m, const matrix_expression<E> &e, row_major_tag) {
581
typedef F<typename M::reference, typename E::value_type> functor_type;
582
typedef typename M::size_type size_type;
583
size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
584
size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
585
for (size_type i = 0; i < size1; ++ i) {
586
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
587
for (size_type j = 0; j < size2; ++ j)
588
functor_type::apply (m (i, j), e () (i, j));
591
DD (size2, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ j));
595
// Explicitly indexing column major
596
template<template <class T1, class T2> class F, class M, class E>
597
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
598
void indexing_matrix_assign (M &m, const matrix_expression<E> &e, column_major_tag) {
599
typedef F<typename M::reference, typename E::value_type> functor_type;
600
typedef typename M::size_type size_type;
601
size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
602
size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
603
for (size_type j = 0; j < size2; ++ j) {
604
#ifndef BOOST_UBLAS_USE_DUFF_DEVICE
605
for (size_type i = 0; i < size1; ++ i)
606
functor_type::apply (m (i, j), e () (i, j));
609
DD (size1, 2, r, (functor_type::apply (m (i, j), e () (i, j)), ++ i));
614
// Dense (proxy) case
615
template<template <class T1, class T2> class F, class R, class M, class E, class C>
616
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
617
void matrix_assign (M &m, const matrix_expression<E> &e, dense_proxy_tag, C) {
618
// R unnecessary, make_conformant not required
619
typedef C orientation_category;
620
#ifdef BOOST_UBLAS_USE_INDEXING
621
indexing_matrix_assign<F> (m, e, orientation_category ());
622
#elif BOOST_UBLAS_USE_ITERATING
623
iterating_matrix_assign<F> (m, e, orientation_category ());
625
typedef typename M::difference_type difference_type;
626
size_type size1 (BOOST_UBLAS_SAME (m.size1 (), e ().size1 ()));
627
size_type size2 (BOOST_UBLAS_SAME (m.size2 (), e ().size2 ()));
628
if (size1 >= BOOST_UBLAS_ITERATOR_THRESHOLD &&
629
size2 >= BOOST_UBLAS_ITERATOR_THRESHOLD)
630
iterating_matrix_assign<F> (m, e, orientation_category ());
632
indexing_matrix_assign<F> (m, e, orientation_category ());
635
// Packed (proxy) row major case
636
template<template <class T1, class T2> class F, class R, class M, class E>
637
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
638
void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
639
typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
640
// R unnecessary, make_conformant not required
641
typedef typename M::difference_type difference_type;
642
typedef typename M::value_type value_type;
643
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
644
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
645
#if BOOST_UBLAS_TYPE_CHECK
646
matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
647
indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
648
indexing_matrix_assign<F> (cm, e, row_major_tag ());
650
typename M::iterator1 it1 (m.begin1 ());
651
typename M::iterator1 it1_end (m.end1 ());
652
typename E::const_iterator1 it1e (e ().begin1 ());
653
typename E::const_iterator1 it1e_end (e ().end1 ());
654
difference_type it1_size (it1_end - it1);
655
difference_type it1e_size (it1e_end - it1e);
656
difference_type diff1 (0);
657
if (it1_size > 0 && it1e_size > 0)
658
diff1 = it1.index1 () - it1e.index1 ();
660
difference_type size1 = (std::min) (diff1, it1e_size);
666
size1 = (std::min) (- diff1, it1_size);
669
if (!functor_type::computed) {
670
while (-- size1 >= 0) { // zeroing
671
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
672
typename M::iterator2 it2 (it1.begin ());
673
typename M::iterator2 it2_end (it1.end ());
675
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
676
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
678
difference_type size2 (it2_end - it2);
679
while (-- size2 >= 0)
680
functor_type::apply (*it2, value_type/*zero*/()), ++ it2;
689
difference_type size1 ((std::min) (it1_size, it1e_size));
692
while (-- size1 >= 0) {
693
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
694
typename M::iterator2 it2 (it1.begin ());
695
typename M::iterator2 it2_end (it1.end ());
696
typename E::const_iterator2 it2e (it1e.begin ());
697
typename E::const_iterator2 it2e_end (it1e.end ());
699
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
700
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
701
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
702
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
704
difference_type it2_size (it2_end - it2);
705
difference_type it2e_size (it2e_end - it2e);
706
difference_type diff2 (0);
707
if (it2_size > 0 && it2e_size > 0) {
708
diff2 = it2.index2 () - it2e.index2 ();
709
difference_type size2 = (std::min) (diff2, it2e_size);
715
size2 = (std::min) (- diff2, it2_size);
718
if (!functor_type::computed) {
719
while (-- size2 >= 0) // zeroing
720
functor_type::apply (*it2, value_type/*zero*/()), ++ it2;
727
difference_type size2 ((std::min) (it2_size, it2e_size));
730
while (-- size2 >= 0)
731
functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
733
if (!functor_type::computed) {
734
while (-- size2 >= 0) // zeroing
735
functor_type::apply (*it2, value_type/*zero*/()), ++ it2;
742
if (!functor_type::computed) {
743
while (-- size1 >= 0) { // zeroing
744
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
745
typename M::iterator2 it2 (it1.begin ());
746
typename M::iterator2 it2_end (it1.end ());
748
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
749
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
751
difference_type size2 (it2_end - it2);
752
while (-- size2 >= 0)
753
functor_type::apply (*it2, value_type/*zero*/()), ++ it2;
759
#if BOOST_UBLAS_TYPE_CHECK
760
if (! disable_type_check<bool>::value)
761
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
764
// Packed (proxy) column major case
765
template<template <class T1, class T2> class F, class R, class M, class E>
766
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
767
void matrix_assign (M &m, const matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
768
typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
769
// R unnecessary, make_conformant not required
770
typedef typename M::difference_type difference_type;
771
typedef typename M::value_type value_type;
772
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
773
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
774
#if BOOST_UBLAS_TYPE_CHECK
775
matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
776
indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
777
indexing_matrix_assign<F> (cm, e, column_major_tag ());
779
typename M::iterator2 it2 (m.begin2 ());
780
typename M::iterator2 it2_end (m.end2 ());
781
typename E::const_iterator2 it2e (e ().begin2 ());
782
typename E::const_iterator2 it2e_end (e ().end2 ());
783
difference_type it2_size (it2_end - it2);
784
difference_type it2e_size (it2e_end - it2e);
785
difference_type diff2 (0);
786
if (it2_size > 0 && it2e_size > 0)
787
diff2 = it2.index2 () - it2e.index2 ();
789
difference_type size2 = (std::min) (diff2, it2e_size);
795
size2 = (std::min) (- diff2, it2_size);
798
if (!functor_type::computed) {
799
while (-- size2 >= 0) { // zeroing
800
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
801
typename M::iterator1 it1 (it2.begin ());
802
typename M::iterator1 it1_end (it2.end ());
804
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
805
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
807
difference_type size1 (it1_end - it1);
808
while (-- size1 >= 0)
809
functor_type::apply (*it1, value_type/*zero*/()), ++ it1;
818
difference_type size2 ((std::min) (it2_size, it2e_size));
821
while (-- size2 >= 0) {
822
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
823
typename M::iterator1 it1 (it2.begin ());
824
typename M::iterator1 it1_end (it2.end ());
825
typename E::const_iterator1 it1e (it2e.begin ());
826
typename E::const_iterator1 it1e_end (it2e.end ());
828
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
829
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
830
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
831
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
833
difference_type it1_size (it1_end - it1);
834
difference_type it1e_size (it1e_end - it1e);
835
difference_type diff1 (0);
836
if (it1_size > 0 && it1e_size > 0) {
837
diff1 = it1.index1 () - it1e.index1 ();
838
difference_type size1 = (std::min) (diff1, it1e_size);
844
size1 = (std::min) (- diff1, it1_size);
847
if (!functor_type::computed) {
848
while (-- size1 >= 0) // zeroing
849
functor_type::apply (*it1, value_type/*zero*/()), ++ it1;
856
difference_type size1 ((std::min) (it1_size, it1e_size));
859
while (-- size1 >= 0)
860
functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
862
if (!functor_type::computed) {
863
while (-- size1 >= 0) // zeroing
864
functor_type::apply (*it1, value_type/*zero*/()), ++ it1;
871
if (!functor_type::computed) {
872
while (-- size2 >= 0) { // zeroing
873
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
874
typename M::iterator1 it1 (it2.begin ());
875
typename M::iterator1 it1_end (it2.end ());
877
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
878
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
880
difference_type size1 (it1_end - it1);
881
while (-- size1 >= 0)
882
functor_type::apply (*it1, value_type/*zero*/()), ++ it1;
888
#if BOOST_UBLAS_TYPE_CHECK
889
if (! disable_type_check<bool>::value)
890
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
893
// Sparse row major case
894
template<template <class T1, class T2> class F, class R, class M, class E>
895
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
896
void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, row_major_tag) {
897
typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
898
// R unnecessary, make_conformant not required
899
BOOST_STATIC_ASSERT ((!functor_type::computed));
900
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
901
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
902
typedef typename M::value_type value_type;
903
// Sparse type has no numeric constraints to check
906
typename E::const_iterator1 it1e (e ().begin1 ());
907
typename E::const_iterator1 it1e_end (e ().end1 ());
908
while (it1e != it1e_end) {
909
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
910
typename E::const_iterator2 it2e (it1e.begin ());
911
typename E::const_iterator2 it2e_end (it1e.end ());
913
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
914
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
916
while (it2e != it2e_end) {
917
value_type t (*it2e);
918
if (t != value_type/*zero*/())
919
m.insert_element (it2e.index1 (), it2e.index2 (), t);
925
// Sparse column major case
926
template<template <class T1, class T2> class F, class R, class M, class E>
927
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
928
void matrix_assign (M &m, const matrix_expression<E> &e, sparse_tag, column_major_tag) {
929
typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
930
// R unnecessary, make_conformant not required
931
BOOST_STATIC_ASSERT ((!functor_type::computed));
932
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
933
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
934
typedef typename M::value_type value_type;
935
// Sparse type has no numeric constraints to check
938
typename E::const_iterator2 it2e (e ().begin2 ());
939
typename E::const_iterator2 it2e_end (e ().end2 ());
940
while (it2e != it2e_end) {
941
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
942
typename E::const_iterator1 it1e (it2e.begin ());
943
typename E::const_iterator1 it1e_end (it2e.end ());
945
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
946
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
948
while (it1e != it1e_end) {
949
value_type t (*it1e);
950
if (t != value_type/*zero*/())
951
m.insert_element (it1e.index1 (), it1e.index2 (), t);
957
// Sparse proxy or functional row major case
958
template<template <class T1, class T2> class F, class R, class M, class E>
959
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
960
void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
961
typedef F<typename M::iterator2::reference, typename E::value_type> functor_type;
962
typedef R conformant_restrict_type;
963
typedef typename M::size_type size_type;
964
typedef typename M::difference_type difference_type;
965
typedef typename M::value_type value_type;
966
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
967
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
968
#if BOOST_UBLAS_TYPE_CHECK
969
matrix<value_type, row_major> cm (m.size1 (), m.size2 ());
970
indexing_matrix_assign<scalar_assign> (cm, m, row_major_tag ());
971
indexing_matrix_assign<F> (cm, e, row_major_tag ());
973
detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
975
typename M::iterator1 it1 (m.begin1 ());
976
typename M::iterator1 it1_end (m.end1 ());
977
typename E::const_iterator1 it1e (e ().begin1 ());
978
typename E::const_iterator1 it1e_end (e ().end1 ());
979
while (it1 != it1_end && it1e != it1e_end) {
980
difference_type compare = it1.index1 () - it1e.index1 ();
982
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
983
typename M::iterator2 it2 (it1.begin ());
984
typename M::iterator2 it2_end (it1.end ());
985
typename E::const_iterator2 it2e (it1e.begin ());
986
typename E::const_iterator2 it2e_end (it1e.end ());
988
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
989
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
990
typename E::const_iterator2 it2e (begin (it1e, iterator1_tag ()));
991
typename E::const_iterator2 it2e_end (end (it1e, iterator1_tag ()));
993
if (it2 != it2_end && it2e != it2e_end) {
994
size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
996
difference_type compare = it2_index - it2e_index;
998
functor_type::apply (*it2, *it2e);
1000
if (it2 != it2_end && it2e != it2e_end) {
1001
it2_index = it2.index2 ();
1002
it2e_index = it2e.index2 ();
1005
} else if (compare < 0) {
1006
if (!functor_type::computed) {
1007
functor_type::apply (*it2, value_type/*zero*/());
1010
increment (it2, it2_end, - compare);
1012
it2_index = it2.index2 ();
1015
} else if (compare > 0) {
1016
increment (it2e, it2e_end, compare);
1017
if (it2e != it2e_end)
1018
it2e_index = it2e.index2 ();
1024
if (!functor_type::computed) {
1025
while (it2 != it2_end) { // zeroing
1026
functor_type::apply (*it2, value_type/*zero*/());
1033
} else if (compare < 0) {
1034
if (!functor_type::computed) {
1035
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1036
typename M::iterator2 it2 (it1.begin ());
1037
typename M::iterator2 it2_end (it1.end ());
1039
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1040
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1042
while (it2 != it2_end) { // zeroing
1043
functor_type::apply (*it2, value_type/*zero*/());
1048
increment (it1, it1_end, - compare);
1050
} else if (compare > 0) {
1051
increment (it1e, it1e_end, compare);
1054
if (!functor_type::computed) {
1055
while (it1 != it1_end) {
1056
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1057
typename M::iterator2 it2 (it1.begin ());
1058
typename M::iterator2 it2_end (it1.end ());
1060
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1061
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1063
while (it2 != it2_end) { // zeroing
1064
functor_type::apply (*it2, value_type/*zero*/());
1072
#if BOOST_UBLAS_TYPE_CHECK
1073
if (! disable_type_check<bool>::value)
1074
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
1077
// Sparse proxy or functional column major case
1078
template<template <class T1, class T2> class F, class R, class M, class E>
1079
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1080
void matrix_assign (M &m, const matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
1081
typedef F<typename M::iterator1::reference, typename E::value_type> functor_type;
1082
typedef R conformant_restrict_type;
1083
typedef typename M::size_type size_type;
1084
typedef typename M::difference_type difference_type;
1085
typedef typename M::value_type value_type;
1086
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
1087
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
1088
#if BOOST_UBLAS_TYPE_CHECK
1089
matrix<value_type, column_major> cm (m.size1 (), m.size2 ());
1090
indexing_matrix_assign<scalar_assign> (cm, m, column_major_tag ());
1091
indexing_matrix_assign<F> (cm, e, column_major_tag ());
1093
detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
1095
typename M::iterator2 it2 (m.begin2 ());
1096
typename M::iterator2 it2_end (m.end2 ());
1097
typename E::const_iterator2 it2e (e ().begin2 ());
1098
typename E::const_iterator2 it2e_end (e ().end2 ());
1099
while (it2 != it2_end && it2e != it2e_end) {
1100
difference_type compare = it2.index2 () - it2e.index2 ();
1102
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1103
typename M::iterator1 it1 (it2.begin ());
1104
typename M::iterator1 it1_end (it2.end ());
1105
typename E::const_iterator1 it1e (it2e.begin ());
1106
typename E::const_iterator1 it1e_end (it2e.end ());
1108
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1109
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1110
typename E::const_iterator1 it1e (begin (it2e, iterator2_tag ()));
1111
typename E::const_iterator1 it1e_end (end (it2e, iterator2_tag ()));
1113
if (it1 != it1_end && it1e != it1e_end) {
1114
size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
1116
difference_type compare = it1_index - it1e_index;
1118
functor_type::apply (*it1, *it1e);
1120
if (it1 != it1_end && it1e != it1e_end) {
1121
it1_index = it1.index1 ();
1122
it1e_index = it1e.index1 ();
1125
} else if (compare < 0) {
1126
if (!functor_type::computed) {
1127
functor_type::apply (*it1, value_type/*zero*/()); // zeroing
1130
increment (it1, it1_end, - compare);
1132
it1_index = it1.index1 ();
1135
} else if (compare > 0) {
1136
increment (it1e, it1e_end, compare);
1137
if (it1e != it1e_end)
1138
it1e_index = it1e.index1 ();
1144
if (!functor_type::computed) {
1145
while (it1 != it1_end) { // zeroing
1146
functor_type::apply (*it1, value_type/*zero*/());
1153
} else if (compare < 0) {
1154
if (!functor_type::computed) {
1155
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1156
typename M::iterator1 it1 (it2.begin ());
1157
typename M::iterator1 it1_end (it2.end ());
1159
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1160
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1162
while (it1 != it1_end) { // zeroing
1163
functor_type::apply (*it1, value_type/*zero*/());
1168
increment (it2, it2_end, - compare);
1170
} else if (compare > 0) {
1171
increment (it2e, it2e_end, compare);
1174
if (!functor_type::computed) {
1175
while (it2 != it2_end) {
1176
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1177
typename M::iterator1 it1 (it2.begin ());
1178
typename M::iterator1 it1_end (it2.end ());
1180
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1181
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1183
while (it1 != it1_end) { // zeroing
1184
functor_type::apply (*it1, value_type/*zero*/());
1192
#if BOOST_UBLAS_TYPE_CHECK
1193
if (! disable_type_check<bool>::value)
1194
BOOST_UBLAS_CHECK (detail::expression_type_check (m, cm), external_logic ());
1199
template<template <class T1, class T2> class F, class M, class E>
1201
void matrix_assign (M &m, const matrix_expression<E> &e) {
1202
typedef typename matrix_assign_traits<typename M::storage_category,
1203
F<typename M::reference, typename E::value_type>::computed,
1204
typename E::const_iterator1::iterator_category,
1205
typename E::const_iterator2::iterator_category>::storage_category storage_category;
1206
// give preference to matrix M's orientation if known
1207
typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1208
typename E::orientation_category ,
1209
typename M::orientation_category >::type orientation_category;
1210
typedef basic_full<typename M::size_type> unrestricted;
1211
matrix_assign<F, unrestricted> (m, e, storage_category (), orientation_category ());
1213
template<template <class T1, class T2> class F, class R, class M, class E>
1215
void matrix_assign (M &m, const matrix_expression<E> &e) {
1216
typedef R conformant_restrict_type;
1217
typedef typename matrix_assign_traits<typename M::storage_category,
1218
F<typename M::reference, typename E::value_type>::computed,
1219
typename E::const_iterator1::iterator_category,
1220
typename E::const_iterator2::iterator_category>::storage_category storage_category;
1221
// give preference to matrix M's orientation if known
1222
typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1223
typename E::orientation_category ,
1224
typename M::orientation_category >::type orientation_category;
1225
matrix_assign<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());
1228
template<class SC, class RI1, class RI2>
1229
struct matrix_swap_traits {
1230
typedef SC storage_category;
1234
struct matrix_swap_traits<dense_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
1235
typedef sparse_proxy_tag storage_category;
1239
struct matrix_swap_traits<packed_proxy_tag, sparse_bidirectional_iterator_tag, sparse_bidirectional_iterator_tag> {
1240
typedef sparse_proxy_tag storage_category;
1243
// Dense (proxy) row major case
1244
template<template <class T1, class T2> class F, class R, class M, class E>
1245
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1246
void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, row_major_tag) {
1247
typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
1248
// R unnecessary, make_conformant not required
1249
typedef typename M::size_type size_type;
1250
typedef typename M::difference_type difference_type;
1251
typename M::iterator1 it1 (m.begin1 ());
1252
typename E::iterator1 it1e (e ().begin1 ());
1253
difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), size_type (e ().end1 () - it1e)));
1254
while (-- size1 >= 0) {
1255
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1256
typename M::iterator2 it2 (it1.begin ());
1257
typename E::iterator2 it2e (it1e.begin ());
1258
difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), size_type (it1e.end () - it2e)));
1260
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1261
typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1262
difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), size_type (end (it1e, iterator1_tag ()) - it2e)));
1264
while (-- size2 >= 0)
1265
functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
1269
// Dense (proxy) column major case
1270
template<template <class T1, class T2> class F, class R, class M, class E>
1271
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1272
void matrix_swap (M &m, matrix_expression<E> &e, dense_proxy_tag, column_major_tag) {
1273
typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
1274
// R unnecessary, make_conformant not required
1275
typedef typename M::size_type size_type;
1276
typedef typename M::difference_type difference_type;
1277
typename M::iterator2 it2 (m.begin2 ());
1278
typename E::iterator2 it2e (e ().begin2 ());
1279
difference_type size2 (BOOST_UBLAS_SAME (m.size2 (), size_type (e ().end2 () - it2e)));
1280
while (-- size2 >= 0) {
1281
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1282
typename M::iterator1 it1 (it2.begin ());
1283
typename E::iterator1 it1e (it2e.begin ());
1284
difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), size_type (it2e.end () - it1e)));
1286
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1287
typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1288
difference_type size1 (BOOST_UBLAS_SAME (m.size1 (), size_type (end (it2e, iterator2_tag ()) - it1e)));
1290
while (-- size1 >= 0)
1291
functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
1295
// Packed (proxy) row major case
1296
template<template <class T1, class T2> class F, class R, class M, class E>
1297
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1298
void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, row_major_tag) {
1299
typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
1300
// R unnecessary, make_conformant not required
1301
typedef typename M::size_type size_type;
1302
typedef typename M::difference_type difference_type;
1303
typename M::iterator1 it1 (m.begin1 ());
1304
typename E::iterator1 it1e (e ().begin1 ());
1305
difference_type size1 (BOOST_UBLAS_SAME (m.end1 () - it1, e ().end1 () - it1e));
1306
while (-- size1 >= 0) {
1307
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1308
typename M::iterator2 it2 (it1.begin ());
1309
typename E::iterator2 it2e (it1e.begin ());
1310
difference_type size2 (BOOST_UBLAS_SAME (it1.end () - it2, it1e.end () - it2e));
1312
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1313
typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1314
difference_type size2 (BOOST_UBLAS_SAME (end (it1, iterator1_tag ()) - it2, end (it1e, iterator1_tag ()) - it2e));
1316
while (-- size2 >= 0)
1317
functor_type::apply (*it2, *it2e), ++ it2, ++ it2e;
1321
// Packed (proxy) column major case
1322
template<template <class T1, class T2> class F, class R, class M, class E>
1323
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1324
void matrix_swap (M &m, matrix_expression<E> &e, packed_proxy_tag, column_major_tag) {
1325
typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
1326
// R unnecessary, make_conformant not required
1327
typedef typename M::size_type size_type;
1328
typedef typename M::difference_type difference_type;
1329
typename M::iterator2 it2 (m.begin2 ());
1330
typename E::iterator2 it2e (e ().begin2 ());
1331
difference_type size2 (BOOST_UBLAS_SAME (m.end2 () - it2, e ().end2 () - it2e));
1332
while (-- size2 >= 0) {
1333
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1334
typename M::iterator1 it1 (it2.begin ());
1335
typename E::iterator1 it1e (it2e.begin ());
1336
difference_type size1 (BOOST_UBLAS_SAME (it2.end () - it1, it2e.end () - it1e));
1338
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1339
typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1340
difference_type size1 (BOOST_UBLAS_SAME (end (it2, iterator2_tag ()) - it1, end (it2e, iterator2_tag ()) - it1e));
1342
while (-- size1 >= 0)
1343
functor_type::apply (*it1, *it1e), ++ it1, ++ it1e;
1347
// Sparse (proxy) row major case
1348
template<template <class T1, class T2> class F, class R, class M, class E>
1349
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1350
void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, row_major_tag) {
1351
typedef F<typename M::iterator2::reference, typename E::reference> functor_type;
1352
typedef R conformant_restrict_type;
1353
typedef typename M::size_type size_type;
1354
typedef typename M::difference_type difference_type;
1355
typedef typename M::value_type value_type;
1356
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
1357
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
1359
detail::make_conformant (m, e, row_major_tag (), conformant_restrict_type ());
1360
// FIXME should be a seperate restriction for E
1361
detail::make_conformant (e (), m, row_major_tag (), conformant_restrict_type ());
1363
typename M::iterator1 it1 (m.begin1 ());
1364
typename M::iterator1 it1_end (m.end1 ());
1365
typename E::iterator1 it1e (e ().begin1 ());
1366
typename E::iterator1 it1e_end (e ().end1 ());
1367
while (it1 != it1_end && it1e != it1e_end) {
1368
difference_type compare = it1.index1 () - it1e.index1 ();
1370
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1371
typename M::iterator2 it2 (it1.begin ());
1372
typename M::iterator2 it2_end (it1.end ());
1373
typename E::iterator2 it2e (it1e.begin ());
1374
typename E::iterator2 it2e_end (it1e.end ());
1376
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1377
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1378
typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1379
typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
1381
if (it2 != it2_end && it2e != it2e_end) {
1382
size_type it2_index = it2.index2 (), it2e_index = it2e.index2 ();
1384
difference_type compare = it2_index - it2e_index;
1386
functor_type::apply (*it2, *it2e);
1388
if (it2 != it2_end && it2e != it2e_end) {
1389
it2_index = it2.index2 ();
1390
it2e_index = it2e.index2 ();
1393
} else if (compare < 0) {
1394
increment (it2, it2_end, - compare);
1396
it2_index = it2.index2 ();
1399
} else if (compare > 0) {
1400
increment (it2e, it2e_end, compare);
1401
if (it2e != it2e_end)
1402
it2e_index = it2e.index2 ();
1408
#if BOOST_UBLAS_TYPE_CHECK
1409
increment (it2e, it2e_end);
1410
increment (it2, it2_end);
1413
} else if (compare < 0) {
1414
#if BOOST_UBLAS_TYPE_CHECK
1415
while (it1.index1 () < it1e.index1 ()) {
1416
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1417
typename M::iterator2 it2 (it1.begin ());
1418
typename M::iterator2 it2_end (it1.end ());
1420
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1421
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1423
increment (it2, it2_end);
1427
increment (it1, it1_end, - compare);
1429
} else if (compare > 0) {
1430
#if BOOST_UBLAS_TYPE_CHECK
1431
while (it1e.index1 () < it1.index1 ()) {
1432
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1433
typename E::iterator2 it2e (it1e.begin ());
1434
typename E::iterator2 it2e_end (it1e.end ());
1436
typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1437
typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
1439
increment (it2e, it2e_end);
1443
increment (it1e, it1e_end, compare);
1447
#if BOOST_UBLAS_TYPE_CHECK
1448
while (it1e != it1e_end) {
1449
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1450
typename E::iterator2 it2e (it1e.begin ());
1451
typename E::iterator2 it2e_end (it1e.end ());
1453
typename E::iterator2 it2e (begin (it1e, iterator1_tag ()));
1454
typename E::iterator2 it2e_end (end (it1e, iterator1_tag ()));
1456
increment (it2e, it2e_end);
1459
while (it1 != it1_end) {
1460
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1461
typename M::iterator2 it2 (it1.begin ());
1462
typename M::iterator2 it2_end (it1.end ());
1464
typename M::iterator2 it2 (begin (it1, iterator1_tag ()));
1465
typename M::iterator2 it2_end (end (it1, iterator1_tag ()));
1467
increment (it2, it2_end);
1472
// Sparse (proxy) column major case
1473
template<template <class T1, class T2> class F, class R, class M, class E>
1474
// BOOST_UBLAS_INLINE This function seems to be big. So we do not let the compiler inline it.
1475
void matrix_swap (M &m, matrix_expression<E> &e, sparse_proxy_tag, column_major_tag) {
1476
typedef F<typename M::iterator1::reference, typename E::reference> functor_type;
1477
typedef R conformant_restrict_type;
1478
typedef typename M::size_type size_type;
1479
typedef typename M::difference_type difference_type;
1480
typedef typename M::value_type value_type;
1481
BOOST_UBLAS_CHECK (m.size1 () == e ().size1 (), bad_size ());
1482
BOOST_UBLAS_CHECK (m.size2 () == e ().size2 (), bad_size ());
1484
detail::make_conformant (m, e, column_major_tag (), conformant_restrict_type ());
1485
// FIXME should be a seperate restriction for E
1486
detail::make_conformant (e (), m, column_major_tag (), conformant_restrict_type ());
1488
typename M::iterator2 it2 (m.begin2 ());
1489
typename M::iterator2 it2_end (m.end2 ());
1490
typename E::iterator2 it2e (e ().begin2 ());
1491
typename E::iterator2 it2e_end (e ().end2 ());
1492
while (it2 != it2_end && it2e != it2e_end) {
1493
difference_type compare = it2.index2 () - it2e.index2 ();
1495
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1496
typename M::iterator1 it1 (it2.begin ());
1497
typename M::iterator1 it1_end (it2.end ());
1498
typename E::iterator1 it1e (it2e.begin ());
1499
typename E::iterator1 it1e_end (it2e.end ());
1501
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1502
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1503
typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1504
typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
1506
if (it1 != it1_end && it1e != it1e_end) {
1507
size_type it1_index = it1.index1 (), it1e_index = it1e.index1 ();
1509
difference_type compare = it1_index - it1e_index;
1511
functor_type::apply (*it1, *it1e);
1513
if (it1 != it1_end && it1e != it1e_end) {
1514
it1_index = it1.index1 ();
1515
it1e_index = it1e.index1 ();
1518
} else if (compare < 0) {
1519
increment (it1, it1_end, - compare);
1521
it1_index = it1.index1 ();
1524
} else if (compare > 0) {
1525
increment (it1e, it1e_end, compare);
1526
if (it1e != it1e_end)
1527
it1e_index = it1e.index1 ();
1533
#if BOOST_UBLAS_TYPE_CHECK
1534
increment (it1e, it1e_end);
1535
increment (it1, it1_end);
1538
} else if (compare < 0) {
1539
#if BOOST_UBLAS_TYPE_CHECK
1540
while (it2.index2 () < it2e.index2 ()) {
1541
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1542
typename M::iterator1 it1 (it2.begin ());
1543
typename M::iterator1 it1_end (it2.end ());
1545
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1546
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1548
increment (it1, it1_end);
1552
increment (it2, it2_end, - compare);
1554
} else if (compare > 0) {
1555
#if BOOST_UBLAS_TYPE_CHECK
1556
while (it2e.index2 () < it2.index2 ()) {
1557
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1558
typename E::iterator1 it1e (it2e.begin ());
1559
typename E::iterator1 it1e_end (it2e.end ());
1561
typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1562
typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
1564
increment (it1e, it1e_end);
1568
increment (it2e, it2e_end, compare);
1572
#if BOOST_UBLAS_TYPE_CHECK
1573
while (it2e != it2e_end) {
1574
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1575
typename E::iterator1 it1e (it2e.begin ());
1576
typename E::iterator1 it1e_end (it2e.end ());
1578
typename E::iterator1 it1e (begin (it2e, iterator2_tag ()));
1579
typename E::iterator1 it1e_end (end (it2e, iterator2_tag ()));
1581
increment (it1e, it1e_end);
1584
while (it2 != it2_end) {
1585
#ifndef BOOST_UBLAS_NO_NESTED_CLASS_RELATION
1586
typename M::iterator1 it1 (it2.begin ());
1587
typename M::iterator1 it1_end (it2.end ());
1589
typename M::iterator1 it1 (begin (it2, iterator2_tag ()));
1590
typename M::iterator1 it1_end (end (it2, iterator2_tag ()));
1592
increment (it1, it1_end);
1599
template<template <class T1, class T2> class F, class M, class E>
1601
void matrix_swap (M &m, matrix_expression<E> &e) {
1602
typedef typename matrix_swap_traits<typename M::storage_category,
1603
typename E::const_iterator1::iterator_category,
1604
typename E::const_iterator2::iterator_category>::storage_category storage_category;
1605
// give preference to matrix M's orientation if known
1606
typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1607
typename E::orientation_category ,
1608
typename M::orientation_category >::type orientation_category;
1609
typedef basic_full<typename M::size_type> unrestricted;
1610
matrix_swap<F, unrestricted> (m, e, storage_category (), orientation_category ());
1612
template<template <class T1, class T2> class F, class R, class M, class E>
1614
void matrix_swap (M &m, matrix_expression<E> &e) {
1615
typedef R conformant_restrict_type;
1616
typedef typename matrix_swap_traits<typename M::storage_category,
1617
typename E::const_iterator1::iterator_category,
1618
typename E::const_iterator2::iterator_category>::storage_category storage_category;
1619
// give preference to matrix M's orientation if known
1620
typedef typename boost::mpl::if_<boost::is_same<typename M::orientation_category, unknown_orientation_tag>,
1621
typename E::orientation_category ,
1622
typename M::orientation_category >::type orientation_category;
1623
matrix_swap<F, conformant_restrict_type> (m, e, storage_category (), orientation_category ());