File: assignment_examples.cpp

package info (click to toggle)
boost1.88 1.88.0-1
  • links: PTS, VCS
  • area: main
  • in suites: sid, trixie
  • size: 576,932 kB
  • sloc: cpp: 4,149,234; xml: 136,789; ansic: 35,092; python: 33,910; asm: 5,698; sh: 4,604; ada: 1,681; makefile: 1,633; pascal: 1,139; perl: 1,124; sql: 640; yacc: 478; ruby: 271; java: 77; lisp: 24; csh: 6
file content (319 lines) | stat: -rw-r--r-- 9,241 bytes parent folder | download | duplicates (10)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
//
//  Copyright (c) 2010 Athanasios Iliopoulos
//
//  Distributed under the Boost Software License, Version 1.0. (See
//  accompanying file LICENSE_1_0.txt or copy at
//  http://www.boost.org/LICENSE_1_0.txt)
//

#include <boost/numeric/ublas/assignment.hpp>
#include <boost/numeric/ublas/vector.hpp>
#include <boost/numeric/ublas/vector_proxy.hpp>
#include <boost/numeric/ublas/matrix_proxy.hpp>
#include <boost/numeric/ublas/vector_sparse.hpp>
#include <boost/numeric/ublas/matrix_sparse.hpp>
#include <boost/numeric/ublas/io.hpp>
#include <boost/numeric/ublas/matrix.hpp>

using namespace boost::numeric::ublas;

int main() {
        // Simple vector fill
    vector<double> a(3);
    a <<= 0, 1, 2;
    std::cout << a << std::endl;
    // [ 0 1 2]

    // Vector from vector
    vector<double> b(7);
    b <<= a, 10, a;
    std::cout << b << std::endl;
    // [ 0 1 2 10 0 1 2]

    // Simple matrix fill
    matrix<double> A(3,3);
    A <<= 0, 1, 2,
         3, 4, 5,
         6, 7, 8;
    std::cout << A << std::endl;
    // [ 0 1 2 ]
    // [ 3 4 5 ]
    // [ 6 7 8 ]

    // Matrix from vector
    A <<= 0, 1, 2,
         3, 4, 5,
         a;
    std::cout << A << std::endl;
    // [ 0 1 2 ]
    // [ 3 4 5 ]
    // [ 0 1 2 ]

    // Matrix from vector - column assignment
    A <<= move(0,2), traverse_policy::by_column(),
         a;
    std::cout << A << std::endl;
    // [ 0 1 0 ]
    // [ 3 4 1 ]
    // [ 0 1 2 ]

    // Another matrix from vector example (watch the wraping);
    vector<double> c(9); c <<= 1, 2, 3, 4, 5, 6, 7, 8, 9;
    A <<= c;
    std::cout << A << std::endl;
    // [ 1 2 3 ]
    // [ 4 5 6 ]
    // [ 7 8 9 ]

    // If for performance(Benchmarks are not definite about that) or consistency reasons you need to disable wraping:
    static next_row_manip endr; //This can be defined globally
    A <<= traverse_policy::by_row_no_wrap(),
            1, 2, 3, endr,
            4, 5, 6, endr,
            7, 8, 9, endr;
    // [ 1 2 3 ]
    // [ 4 5 6 ]
    // [ 7 8 9 ]
    // If by default you need to disable wraping define
    // BOOST_UBLAS_DEFAULT_NO_WRAP_POLICY, in the compilation options,
    // so that you avoid typing the "traverse_policy::by_row_no_wrap()".

    //  Plus and minus assign:
    A <<= fill_policy::index_plus_assign(),
         3,2,1;
    std::cout << A << std::endl;
    // [ 4 4 4 ]
    // [ 4 5 6 ]
    // [ 7 8 9 ]

    // Matrix from proxy
    A <<= 0, 1, 2,
         project(b, range(3,6)),
         a;
    std::cout << A << std::endl;
    // [ 0 1 2 ]
    // [10 0 1 ]
    // [ 6 7 8 ]

    // Matrix from matrix
    matrix<double> B(6,6);
    B <<= A, A,
         A, A;
    std::cout << B << std::endl;
    // [ A A ]
    // [ A A ]

    // Matrix range (vector is similar)
    B = zero_matrix<double>(6,6);
    matrix_range<matrix<double> > mrB (B, range (1, 4), range (1, 4));
    mrB <<= 1,2,3,4,5,6,7,8,9;
    std::cout << B << std::endl;
    // [ 0 0 0 0 0 0]
    // [ 0 1 2 3 0 0]
    // [ 0 4 5 6 0 0]
    // [ 0 0 0 0 0 0]
    // [ 0 0 0 0 0 0]
    // [ 0 0 0 0 0 0]

    // Horizontal concatenation can be achieved using this trick:
    matrix<double> BH(3,9);
    BH <<= A, A, A;
    std::cout << BH << std::endl;
    // [ A A A]

    // Vertical concatenation can be achieved using this trick:
    matrix<double> BV(9,3);
    BV <<= A,
          A,
          A;
    std::cout << BV << std::endl;
    // [ A ]
    // [ A ]
    // [ A ]

    // Watch the difference when assigning matrices for different traverse policies:
    matrix<double> BR(9,9, 0);
    BR <<= traverse_policy::by_row(), // This is the default, so this might as well be omitted.
          A, A, A;
    std::cout << BR << std::endl;
    // [ A A A]
    // [ 0 0 0]
    // [ 0 0 0]

    matrix<double> BC(9,9, 0);
    BC <<= traverse_policy::by_column(),
          A, A, A;
    std::cout << BC << std::endl;
    // [ A 0 0]
    // [ A 0 0]
    // [ A 0 0]

    // The following will throw a run-time exception in debug mode (matrix mid-assignment wrap is not allowed) :
    // matrix<double> C(7,7);
    // C <<= A, A, A;

    // Matrix from matrix with index manipulators
    matrix<double> C(6,6,0);
    C <<= A, move(3,0), A;
    // [ A 0 ]
    // [ 0 A ]

    // A faster way for to construct this dense matrix.
    matrix<double> D(6,6);
    D <<= A, zero_matrix<double>(3,3),
         zero_matrix<double>(3,3), A;
    // [ A 0 ]
    // [ 0 A ]

    // The next_row and next_column index manipulators:
    // note: next_row and next_column functions return
    // a next_row_manip and and next_column_manip object.
    // This is the manipulator we used earlier when we disabled
    // wrapping.
    matrix<double> E(2,4,0);
    E <<= 1, 2, next_row(),
         3, 4, next_column(),5;
    std::cout << E << std::endl;
    // [ 1 2 0 5 ]
    // [ 3 4 0 0 ]

    // The begin1 (moves to the begining of the column) index manipulator, begin2 does the same for the row:
    matrix<double> F(2,4,0);
    F <<= 1, 2, next_row(),
         3, 4, begin1(),5;
    std::cout << F << std::endl;
    // [ 1 2 5 0 ]
    // [ 3 4 0 0 ]

    // The move (relative) and move_to(absolute) index manipulators (probably the most useful manipulators):
    matrix<double> G(2,4,0);
    G <<= 1, 2, move(0,1), 3,
         move_to(1,3), 4;
    std::cout << G << std::endl;
    // [ 1 2 0 3 ]
    // [ 0 0 0 4 ]

    // Static equivallents (faster) when sizes are known at compile time:
    matrix<double> Gs(2,4,0);
    Gs <<= 1, 2, move<0,1>(), 3,
         move_to<1,3>(), 4;
    std::cout << Gs << std::endl;
    // [ 1 2 0 3 ]
    // [ 0 0 0 4 ]

    // Choice of traverse policy (default is "row by row" traverse):

    matrix<double> H(2,4,0);
    H <<= 1, 2, 3, 4,
         5, 6, 7, 8;
    std::cout << H << std::endl;
    // [ 1 2 3 4 ]
    // [ 5 6 7 8 ]

    H <<= traverse_policy::by_column(),
        1, 2, 3, 4,
        5, 6, 7, 8;
    std::cout << H << std::endl;
    // [ 1 3 5 7 ]
    // [ 2 4 6 8 ]

    // traverse policy can be changed mid assignment if desired.
     matrix<double> H1(4,4,0);
     H1 <<= 1, 2, 3, traverse_policy::by_column(), 1, 2, 3;

    std::cout << H << std::endl;
    // [1 2 3 1]
    // [0 0 0 2]
    // [0 0 0 3]
    // [0 0 0 0]

    // note: fill_policy and traverse_policy are namespaces, so you can use them
    // by a using statement.

    // For compressed and coordinate matrix types a push_back or insert fill policy can be chosen for faster assginment:
    compressed_matrix<double> I(2, 2);
    I <<=    fill_policy::sparse_push_back(),
            0, 1, 2, 3;
    std::cout << I << std::endl;
    // [ 0 1 ]
    // [ 2 3 ]

    coordinate_matrix<double> J(2,2);
    J<<=fill_policy::sparse_insert(),
        1, 2, 3, 4;
    std::cout << J << std::endl;
    // [ 1 2 ]
    // [ 3 4 ]

    // A sparse matrix from another matrix works as with other types.
    coordinate_matrix<double> K(3,3);
    K<<=fill_policy::sparse_insert(),
        J;
    std::cout << K << std::endl;
    // [ 1 2 0 ]
    // [ 3 4 0 ]
    // [ 0 0 0 ]

    // Be careful this will not work:
    //compressed_matrix<double> J2(4,4);
    //J2<<=fill_policy::sparse_push_back(),
     //   J,J;
    // That's because the second J2's elements
    // are attempted to be assigned at positions
    // that come before the elements already pushed.
    // Unfortunatelly that's the only thing you can do in this case
    // (or of course make a custom agorithm):
    compressed_matrix<double> J2(4,4);
    J2<<=fill_policy::sparse_push_back(),
        J, fill_policy::sparse_insert(),
        J;

    std::cout << J2 << std::endl;
    // [  J   J  ]
    // [ 0 0 0 0 ]
    // [ 0 0 0 0 ]

    // A different traverse policy doesn't change the result, only they order it is been assigned.
    coordinate_matrix<double> L(3,3);
    L<<=fill_policy::sparse_insert(), traverse_policy::by_column(),
        J;
    std::cout << L << std::endl;
    // (same as previous)
    // [ 1 2 0 ]
    // [ 3 4 0 ]
    // [ 0 0 0 ]

    typedef coordinate_matrix<double>::size_type cmst;
    const cmst size = 30;
    //typedef fill_policy::sparse_push_back spb;
    // Although the above could have been used the following is may be faster if
    //  you use the policy often and for relatively small containers.
    static fill_policy::sparse_push_back spb;

    // A block diagonal sparse using a loop:
    compressed_matrix<double> M(size, size, 4*15);
    for (cmst i=0; i!=size; i+=J.size1())
        M <<= spb, move_to(i,i), J;


    // If typedef was used above the last expression should start
    // with M <<= spb()...

    // Displaying so that blocks can be easily seen:
    for (unsigned int i=0; i!=M.size1(); i++) {
        std::cout << M(i,0);
        for (unsigned int j=1; j!=M.size2(); j++) std::cout << ", " << M(i,j);
        std::cout << "\n";
    }
    // [ J 0 0 0 ... 0]
    // [ 0 J 0 0 ... 0]
    // [ 0 . . . ... 0]
    // [ 0 0 ... 0 0 J]


    // A "repeat" trasverser may by provided so that this becomes faster and an on-liner like:
    // M <<= spb, repeat(0, size, J.size1(), 0, size, J.size1()), J;
    // An alternate would be to create a :repeater" matrix and vector expression that can be used in other places as well. The latter is probably better,
    return 0;
}