Line data Source code
1 : /* catch_matrix.cpp
2 : * Copyright (c) 2018-2019 Made to Order Software Corp. All Rights Reserved
3 : *
4 : * Project: https://snapwebsites.org/project/snapwebsites
5 : *
6 : * Permission is hereby granted, free of charge, to any
7 : * person obtaining a copy of this software and
8 : * associated documentation files (the "Software"), to
9 : * deal in the Software without restriction, including
10 : * without limitation the rights to use, copy, modify,
11 : * merge, publish, distribute, sublicense, and/or sell
12 : * copies of the Software, and to permit persons to whom
13 : * the Software is furnished to do so, subject to the
14 : * following conditions:
15 : *
16 : * The above copyright notice and this permission notice
17 : * shall be included in all copies or substantial
18 : * portions of the Software.
19 : *
20 : * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
21 : * ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
22 : * LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
23 : * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO
24 : * EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
25 : * LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
26 : * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
27 : * ARISING FROM, OUT OF OR IN CONNECTION WITH THE
28 : * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
29 : * SOFTWARE.
30 : */
31 :
32 : /** \file
33 : * \brief Verify the various matrix implementation.
34 : *
35 : * This file implements tests to verify that the matrix templates
36 : * work as expected.
37 : */
38 :
39 : // self
40 : //
41 : #include "main.h"
42 :
43 :
44 :
45 : // ignore the == and != against float warnings
46 : //
47 : #pragma GCC diagnostic ignored "-Wfloat-equal"
48 :
49 :
50 : // snapdev lib
51 : //
52 : #include "snapdev/matrix.h"
53 :
54 :
55 :
56 : namespace
57 : {
58 700 : auto frand = []()
59 : {
60 700 : return static_cast<double>(rand()) / static_cast<double>(rand());
61 700 : };
62 : }
63 : // no name namespace
64 :
65 :
66 :
67 6 : CATCH_TEST_CASE("matrix_init", "[matrix]")
68 : {
69 : // constructor/copy
70 : // and
71 : // zero/identity
72 : //
73 8 : CATCH_GIVEN("constructor")
74 : {
75 8 : CATCH_START_SECTION("matrix: empty")
76 : {
77 2 : snap::matrix<double> empty;
78 :
79 1 : CATCH_REQUIRE(empty.rows() == 0);
80 1 : CATCH_REQUIRE(empty.columns() == 0);
81 :
82 2 : snap::matrix<double> copy(empty);
83 :
84 1 : CATCH_REQUIRE(empty.rows() == 0);
85 1 : CATCH_REQUIRE(empty.columns() == 0);
86 : }
87 : CATCH_END_SECTION()
88 :
89 8 : CATCH_START_SECTION("matrix: 2x2")
90 : {
91 2 : snap::matrix<double> m(2, 2);
92 :
93 1 : CATCH_REQUIRE(m.rows() == 2);
94 1 : CATCH_REQUIRE(m.columns() == 2);
95 :
96 : // by default we get an identity
97 : //
98 1 : CATCH_REQUIRE(m[0][0] == 1.0);
99 1 : CATCH_REQUIRE(m[0][1] == 0.0);
100 1 : CATCH_REQUIRE(m[1][0] == 0.0);
101 1 : CATCH_REQUIRE(m[1][1] == 1.0);
102 :
103 1 : double const r00(frand());
104 1 : double const r01(frand());
105 1 : double const r10(frand());
106 1 : double const r11(frand());
107 :
108 1 : m[0][0] = r00;
109 1 : m[0][1] = r01;
110 1 : m[1][0] = r10;
111 1 : m[1][1] = r11;
112 :
113 1 : CATCH_REQUIRE(m[0][0] == r00);
114 1 : CATCH_REQUIRE(m[0][1] == r01);
115 1 : CATCH_REQUIRE(m[1][0] == r10);
116 1 : CATCH_REQUIRE(m[1][1] == r11);
117 :
118 2 : snap::matrix<double> copy(m);
119 2 : snap::matrix<double> c2;
120 :
121 1 : CATCH_REQUIRE(copy[0][0] == r00);
122 1 : CATCH_REQUIRE(copy[0][1] == r01);
123 1 : CATCH_REQUIRE(copy[1][0] == r10);
124 1 : CATCH_REQUIRE(copy[1][1] == r11);
125 :
126 1 : m.clear();
127 :
128 1 : CATCH_REQUIRE(m[0][0] == 0.0);
129 1 : CATCH_REQUIRE(m[0][1] == 0.0);
130 1 : CATCH_REQUIRE(m[1][0] == 0.0);
131 1 : CATCH_REQUIRE(m[1][1] == 0.0);
132 :
133 : // copy is still intact
134 : //
135 1 : CATCH_REQUIRE(copy[0][0] == r00);
136 1 : CATCH_REQUIRE(copy[0][1] == r01);
137 1 : CATCH_REQUIRE(copy[1][0] == r10);
138 1 : CATCH_REQUIRE(copy[1][1] == r11);
139 :
140 1 : CATCH_REQUIRE(c2.rows() == 0);
141 1 : CATCH_REQUIRE(c2.columns() == 0);
142 :
143 1 : c2 = copy;
144 :
145 1 : CATCH_REQUIRE(c2[0][0] == r00);
146 1 : CATCH_REQUIRE(c2[0][1] == r01);
147 1 : CATCH_REQUIRE(c2[1][0] == r10);
148 1 : CATCH_REQUIRE(c2[1][1] == r11);
149 :
150 1 : c2.swap(m);
151 :
152 1 : CATCH_REQUIRE(m[0][0] == r00);
153 1 : CATCH_REQUIRE(m[0][1] == r01);
154 1 : CATCH_REQUIRE(m[1][0] == r10);
155 1 : CATCH_REQUIRE(m[1][1] == r11);
156 :
157 1 : CATCH_REQUIRE(c2[0][0] == 0.0);
158 1 : CATCH_REQUIRE(c2[0][1] == 0.0);
159 1 : CATCH_REQUIRE(c2[1][0] == 0.0);
160 1 : CATCH_REQUIRE(c2[1][1] == 0.0);
161 : }
162 : CATCH_END_SECTION()
163 :
164 8 : CATCH_START_SECTION("matrix: 3x3")
165 : {
166 2 : snap::matrix<double> m(3, 3);
167 :
168 1 : CATCH_REQUIRE(m.rows() == 3);
169 1 : CATCH_REQUIRE(m.columns() == 3);
170 :
171 : // by default we get an identity
172 : //
173 1 : CATCH_REQUIRE(m[0][0] == 1.0);
174 1 : CATCH_REQUIRE(m[0][1] == 0.0);
175 1 : CATCH_REQUIRE(m[0][2] == 0.0);
176 1 : CATCH_REQUIRE(m[1][0] == 0.0);
177 1 : CATCH_REQUIRE(m[1][1] == 1.0);
178 1 : CATCH_REQUIRE(m[1][2] == 0.0);
179 1 : CATCH_REQUIRE(m[2][0] == 0.0);
180 1 : CATCH_REQUIRE(m[2][1] == 0.0);
181 1 : CATCH_REQUIRE(m[2][2] == 1.0);
182 :
183 1 : double const r00(frand());
184 1 : double const r01(frand());
185 1 : double const r02(frand());
186 1 : double const r10(frand());
187 1 : double const r11(frand());
188 1 : double const r12(frand());
189 1 : double const r20(frand());
190 1 : double const r21(frand());
191 1 : double const r22(frand());
192 :
193 1 : m[0][0] = r00;
194 1 : m[0][1] = r01;
195 1 : m[0][2] = r02;
196 1 : m[1][0] = r10;
197 1 : m[1][1] = r11;
198 1 : m[1][2] = r12;
199 1 : m[2][0] = r20;
200 1 : m[2][1] = r21;
201 1 : m[2][2] = r22;
202 :
203 1 : CATCH_REQUIRE(m[0][0] == r00);
204 1 : CATCH_REQUIRE(m[0][1] == r01);
205 1 : CATCH_REQUIRE(m[0][2] == r02);
206 1 : CATCH_REQUIRE(m[1][0] == r10);
207 1 : CATCH_REQUIRE(m[1][1] == r11);
208 1 : CATCH_REQUIRE(m[1][2] == r12);
209 1 : CATCH_REQUIRE(m[2][0] == r20);
210 1 : CATCH_REQUIRE(m[2][1] == r21);
211 1 : CATCH_REQUIRE(m[2][2] == r22);
212 :
213 2 : snap::matrix<double> copy(m);
214 2 : snap::matrix<double> c2;
215 :
216 1 : CATCH_REQUIRE(copy[0][0] == r00);
217 1 : CATCH_REQUIRE(copy[0][1] == r01);
218 1 : CATCH_REQUIRE(copy[0][2] == r02);
219 1 : CATCH_REQUIRE(copy[1][0] == r10);
220 1 : CATCH_REQUIRE(copy[1][1] == r11);
221 1 : CATCH_REQUIRE(copy[1][2] == r12);
222 1 : CATCH_REQUIRE(copy[2][0] == r20);
223 1 : CATCH_REQUIRE(copy[2][1] == r21);
224 1 : CATCH_REQUIRE(copy[2][2] == r22);
225 :
226 1 : m.clear();
227 :
228 1 : CATCH_REQUIRE(m[0][0] == 0.0);
229 1 : CATCH_REQUIRE(m[0][1] == 0.0);
230 1 : CATCH_REQUIRE(m[0][2] == 0.0);
231 1 : CATCH_REQUIRE(m[1][0] == 0.0);
232 1 : CATCH_REQUIRE(m[1][1] == 0.0);
233 1 : CATCH_REQUIRE(m[1][2] == 0.0);
234 1 : CATCH_REQUIRE(m[2][0] == 0.0);
235 1 : CATCH_REQUIRE(m[2][1] == 0.0);
236 1 : CATCH_REQUIRE(m[2][2] == 0.0);
237 :
238 : // copy is still intact
239 : //
240 1 : CATCH_REQUIRE(copy[0][0] == r00);
241 1 : CATCH_REQUIRE(copy[0][1] == r01);
242 1 : CATCH_REQUIRE(copy[0][2] == r02);
243 1 : CATCH_REQUIRE(copy[1][0] == r10);
244 1 : CATCH_REQUIRE(copy[1][1] == r11);
245 1 : CATCH_REQUIRE(copy[1][2] == r12);
246 1 : CATCH_REQUIRE(copy[2][0] == r20);
247 1 : CATCH_REQUIRE(copy[2][1] == r21);
248 1 : CATCH_REQUIRE(copy[2][2] == r22);
249 :
250 1 : CATCH_REQUIRE(c2.rows() == 0);
251 1 : CATCH_REQUIRE(c2.columns() == 0);
252 :
253 1 : c2 = copy;
254 :
255 1 : CATCH_REQUIRE(c2[0][0] == r00);
256 1 : CATCH_REQUIRE(c2[0][1] == r01);
257 1 : CATCH_REQUIRE(c2[0][2] == r02);
258 1 : CATCH_REQUIRE(c2[1][0] == r10);
259 1 : CATCH_REQUIRE(c2[1][1] == r11);
260 1 : CATCH_REQUIRE(c2[1][2] == r12);
261 1 : CATCH_REQUIRE(c2[2][0] == r20);
262 1 : CATCH_REQUIRE(c2[2][1] == r21);
263 1 : CATCH_REQUIRE(c2[2][2] == r22);
264 :
265 1 : c2.swap(m);
266 :
267 1 : CATCH_REQUIRE(m[0][0] == r00);
268 1 : CATCH_REQUIRE(m[0][1] == r01);
269 1 : CATCH_REQUIRE(m[0][2] == r02);
270 1 : CATCH_REQUIRE(m[1][0] == r10);
271 1 : CATCH_REQUIRE(m[1][1] == r11);
272 1 : CATCH_REQUIRE(m[1][2] == r12);
273 1 : CATCH_REQUIRE(m[2][0] == r20);
274 1 : CATCH_REQUIRE(m[2][1] == r21);
275 1 : CATCH_REQUIRE(m[2][2] == r22);
276 :
277 1 : CATCH_REQUIRE(c2[0][0] == 0.0);
278 1 : CATCH_REQUIRE(c2[0][1] == 0.0);
279 1 : CATCH_REQUIRE(c2[0][2] == 0.0);
280 1 : CATCH_REQUIRE(c2[1][0] == 0.0);
281 1 : CATCH_REQUIRE(c2[1][1] == 0.0);
282 1 : CATCH_REQUIRE(c2[1][2] == 0.0);
283 1 : CATCH_REQUIRE(c2[2][0] == 0.0);
284 1 : CATCH_REQUIRE(c2[2][1] == 0.0);
285 1 : CATCH_REQUIRE(c2[2][2] == 0.0);
286 : }
287 : CATCH_END_SECTION()
288 :
289 8 : CATCH_START_SECTION("matrix: 4x4")
290 : {
291 2 : snap::matrix<double> m(4, 4);
292 :
293 1 : CATCH_REQUIRE(m.rows() == 4);
294 1 : CATCH_REQUIRE(m.columns() == 4);
295 :
296 : // by default we get an identity
297 : //
298 1 : CATCH_REQUIRE(m[0][0] == 1.0);
299 1 : CATCH_REQUIRE(m[0][1] == 0.0);
300 1 : CATCH_REQUIRE(m[0][2] == 0.0);
301 1 : CATCH_REQUIRE(m[0][3] == 0.0);
302 1 : CATCH_REQUIRE(m[1][0] == 0.0);
303 1 : CATCH_REQUIRE(m[1][1] == 1.0);
304 1 : CATCH_REQUIRE(m[1][2] == 0.0);
305 1 : CATCH_REQUIRE(m[1][3] == 0.0);
306 1 : CATCH_REQUIRE(m[2][0] == 0.0);
307 1 : CATCH_REQUIRE(m[2][1] == 0.0);
308 1 : CATCH_REQUIRE(m[2][2] == 1.0);
309 1 : CATCH_REQUIRE(m[2][3] == 0.0);
310 1 : CATCH_REQUIRE(m[3][0] == 0.0);
311 1 : CATCH_REQUIRE(m[3][1] == 0.0);
312 1 : CATCH_REQUIRE(m[3][2] == 0.0);
313 1 : CATCH_REQUIRE(m[3][3] == 1.0);
314 :
315 1 : double const r00(frand());
316 1 : double const r01(frand());
317 1 : double const r02(frand());
318 1 : double const r03(frand());
319 1 : double const r10(frand());
320 1 : double const r11(frand());
321 1 : double const r12(frand());
322 1 : double const r13(frand());
323 1 : double const r20(frand());
324 1 : double const r21(frand());
325 1 : double const r22(frand());
326 1 : double const r23(frand());
327 1 : double const r30(frand());
328 1 : double const r31(frand());
329 1 : double const r32(frand());
330 1 : double const r33(frand());
331 :
332 1 : m[0][0] = r00;
333 1 : m[0][1] = r01;
334 1 : m[0][2] = r02;
335 1 : m[0][3] = r03;
336 1 : m[1][0] = r10;
337 1 : m[1][1] = r11;
338 1 : m[1][2] = r12;
339 1 : m[1][3] = r13;
340 1 : m[2][0] = r20;
341 1 : m[2][1] = r21;
342 1 : m[2][2] = r22;
343 1 : m[2][3] = r23;
344 1 : m[3][0] = r30;
345 1 : m[3][1] = r31;
346 1 : m[3][2] = r32;
347 1 : m[3][3] = r33;
348 :
349 1 : CATCH_REQUIRE(m[0][0] == r00);
350 1 : CATCH_REQUIRE(m[0][1] == r01);
351 1 : CATCH_REQUIRE(m[0][2] == r02);
352 1 : CATCH_REQUIRE(m[0][3] == r03);
353 1 : CATCH_REQUIRE(m[1][0] == r10);
354 1 : CATCH_REQUIRE(m[1][1] == r11);
355 1 : CATCH_REQUIRE(m[1][2] == r12);
356 1 : CATCH_REQUIRE(m[1][3] == r13);
357 1 : CATCH_REQUIRE(m[2][0] == r20);
358 1 : CATCH_REQUIRE(m[2][1] == r21);
359 1 : CATCH_REQUIRE(m[2][2] == r22);
360 1 : CATCH_REQUIRE(m[2][3] == r23);
361 1 : CATCH_REQUIRE(m[3][0] == r30);
362 1 : CATCH_REQUIRE(m[3][1] == r31);
363 1 : CATCH_REQUIRE(m[3][2] == r32);
364 1 : CATCH_REQUIRE(m[3][3] == r33);
365 :
366 2 : snap::matrix<double> copy(m);
367 2 : snap::matrix<double> c2;
368 :
369 1 : CATCH_REQUIRE(copy[0][0] == r00);
370 1 : CATCH_REQUIRE(copy[0][1] == r01);
371 1 : CATCH_REQUIRE(copy[0][2] == r02);
372 1 : CATCH_REQUIRE(copy[0][3] == r03);
373 1 : CATCH_REQUIRE(copy[1][0] == r10);
374 1 : CATCH_REQUIRE(copy[1][1] == r11);
375 1 : CATCH_REQUIRE(copy[1][2] == r12);
376 1 : CATCH_REQUIRE(copy[1][3] == r13);
377 1 : CATCH_REQUIRE(copy[2][0] == r20);
378 1 : CATCH_REQUIRE(copy[2][1] == r21);
379 1 : CATCH_REQUIRE(copy[2][2] == r22);
380 1 : CATCH_REQUIRE(copy[2][3] == r23);
381 1 : CATCH_REQUIRE(copy[3][0] == r30);
382 1 : CATCH_REQUIRE(copy[3][1] == r31);
383 1 : CATCH_REQUIRE(copy[3][2] == r32);
384 1 : CATCH_REQUIRE(copy[3][3] == r33);
385 :
386 1 : m.clear();
387 :
388 1 : CATCH_REQUIRE(m[0][0] == 0.0);
389 1 : CATCH_REQUIRE(m[0][1] == 0.0);
390 1 : CATCH_REQUIRE(m[0][2] == 0.0);
391 1 : CATCH_REQUIRE(m[0][3] == 0.0);
392 1 : CATCH_REQUIRE(m[1][0] == 0.0);
393 1 : CATCH_REQUIRE(m[1][1] == 0.0);
394 1 : CATCH_REQUIRE(m[1][2] == 0.0);
395 1 : CATCH_REQUIRE(m[1][3] == 0.0);
396 1 : CATCH_REQUIRE(m[2][0] == 0.0);
397 1 : CATCH_REQUIRE(m[2][1] == 0.0);
398 1 : CATCH_REQUIRE(m[2][2] == 0.0);
399 1 : CATCH_REQUIRE(m[2][3] == 0.0);
400 :
401 : // copy is still intact
402 : //
403 1 : CATCH_REQUIRE(copy[0][0] == r00);
404 1 : CATCH_REQUIRE(copy[0][1] == r01);
405 1 : CATCH_REQUIRE(copy[0][2] == r02);
406 1 : CATCH_REQUIRE(copy[0][3] == r03);
407 1 : CATCH_REQUIRE(copy[1][0] == r10);
408 1 : CATCH_REQUIRE(copy[1][1] == r11);
409 1 : CATCH_REQUIRE(copy[1][2] == r12);
410 1 : CATCH_REQUIRE(copy[1][3] == r13);
411 1 : CATCH_REQUIRE(copy[2][0] == r20);
412 1 : CATCH_REQUIRE(copy[2][1] == r21);
413 1 : CATCH_REQUIRE(copy[2][2] == r22);
414 1 : CATCH_REQUIRE(copy[2][3] == r23);
415 1 : CATCH_REQUIRE(copy[3][0] == r30);
416 1 : CATCH_REQUIRE(copy[3][1] == r31);
417 1 : CATCH_REQUIRE(copy[3][2] == r32);
418 1 : CATCH_REQUIRE(copy[3][3] == r33);
419 :
420 1 : CATCH_REQUIRE(c2.rows() == 0);
421 1 : CATCH_REQUIRE(c2.columns() == 0);
422 :
423 1 : c2 = copy;
424 :
425 1 : CATCH_REQUIRE(c2[0][0] == r00);
426 1 : CATCH_REQUIRE(c2[0][1] == r01);
427 1 : CATCH_REQUIRE(c2[0][2] == r02);
428 1 : CATCH_REQUIRE(c2[0][3] == r03);
429 1 : CATCH_REQUIRE(c2[1][0] == r10);
430 1 : CATCH_REQUIRE(c2[1][1] == r11);
431 1 : CATCH_REQUIRE(c2[1][2] == r12);
432 1 : CATCH_REQUIRE(c2[1][3] == r13);
433 1 : CATCH_REQUIRE(c2[2][0] == r20);
434 1 : CATCH_REQUIRE(c2[2][1] == r21);
435 1 : CATCH_REQUIRE(c2[2][2] == r22);
436 1 : CATCH_REQUIRE(c2[2][3] == r23);
437 1 : CATCH_REQUIRE(c2[3][0] == r30);
438 1 : CATCH_REQUIRE(c2[3][1] == r31);
439 1 : CATCH_REQUIRE(c2[3][2] == r32);
440 1 : CATCH_REQUIRE(c2[3][3] == r33);
441 :
442 : //std::cout << c2 << std::endl;
443 :
444 1 : c2.swap(m);
445 :
446 1 : CATCH_REQUIRE(m[0][0] == r00);
447 1 : CATCH_REQUIRE(m[0][1] == r01);
448 1 : CATCH_REQUIRE(m[0][2] == r02);
449 1 : CATCH_REQUIRE(m[0][3] == r03);
450 1 : CATCH_REQUIRE(m[1][0] == r10);
451 1 : CATCH_REQUIRE(m[1][1] == r11);
452 1 : CATCH_REQUIRE(m[1][2] == r12);
453 1 : CATCH_REQUIRE(m[1][3] == r13);
454 1 : CATCH_REQUIRE(m[2][0] == r20);
455 1 : CATCH_REQUIRE(m[2][1] == r21);
456 1 : CATCH_REQUIRE(m[2][2] == r22);
457 1 : CATCH_REQUIRE(m[2][3] == r23);
458 1 : CATCH_REQUIRE(m[3][0] == r30);
459 1 : CATCH_REQUIRE(m[3][1] == r31);
460 1 : CATCH_REQUIRE(m[3][2] == r32);
461 1 : CATCH_REQUIRE(m[3][3] == r33);
462 :
463 1 : CATCH_REQUIRE(c2[0][0] == 0.0);
464 1 : CATCH_REQUIRE(c2[0][1] == 0.0);
465 1 : CATCH_REQUIRE(c2[0][2] == 0.0);
466 1 : CATCH_REQUIRE(c2[0][3] == 0.0);
467 1 : CATCH_REQUIRE(c2[1][0] == 0.0);
468 1 : CATCH_REQUIRE(c2[1][1] == 0.0);
469 1 : CATCH_REQUIRE(c2[1][2] == 0.0);
470 1 : CATCH_REQUIRE(c2[1][3] == 0.0);
471 1 : CATCH_REQUIRE(c2[2][0] == 0.0);
472 1 : CATCH_REQUIRE(c2[2][1] == 0.0);
473 1 : CATCH_REQUIRE(c2[2][2] == 0.0);
474 1 : CATCH_REQUIRE(c2[2][3] == 0.0);
475 : }
476 : CATCH_END_SECTION()
477 : }
478 4 : }
479 :
480 :
481 10 : CATCH_TEST_CASE("matrix_additive", "[matrix]")
482 : {
483 : // create two random 4x4 matrices and make sure the add works
484 : //
485 16 : CATCH_GIVEN("add")
486 : {
487 8 : CATCH_START_SECTION("matrix: a+=<scalar>")
488 : {
489 : // setup A
490 : //
491 2 : snap::matrix<double> a(4, 4);
492 :
493 1 : CATCH_REQUIRE(a.rows() == 4);
494 1 : CATCH_REQUIRE(a.columns() == 4);
495 :
496 1 : double const a00(frand());
497 1 : double const a01(frand());
498 1 : double const a02(frand());
499 1 : double const a03(frand());
500 1 : double const a10(frand());
501 1 : double const a11(frand());
502 1 : double const a12(frand());
503 1 : double const a13(frand());
504 1 : double const a20(frand());
505 1 : double const a21(frand());
506 1 : double const a22(frand());
507 1 : double const a23(frand());
508 1 : double const a30(frand());
509 1 : double const a31(frand());
510 1 : double const a32(frand());
511 1 : double const a33(frand());
512 :
513 1 : a[0][0] = a00;
514 1 : a[0][1] = a01;
515 1 : a[0][2] = a02;
516 1 : a[0][3] = a03;
517 1 : a[1][0] = a10;
518 1 : a[1][1] = a11;
519 1 : a[1][2] = a12;
520 1 : a[1][3] = a13;
521 1 : a[2][0] = a20;
522 1 : a[2][1] = a21;
523 1 : a[2][2] = a22;
524 1 : a[2][3] = a23;
525 1 : a[3][0] = a30;
526 1 : a[3][1] = a31;
527 1 : a[3][2] = a32;
528 1 : a[3][3] = a33;
529 :
530 1 : CATCH_REQUIRE(a[0][0] == a00);
531 1 : CATCH_REQUIRE(a[0][1] == a01);
532 1 : CATCH_REQUIRE(a[0][2] == a02);
533 1 : CATCH_REQUIRE(a[0][3] == a03);
534 1 : CATCH_REQUIRE(a[1][0] == a10);
535 1 : CATCH_REQUIRE(a[1][1] == a11);
536 1 : CATCH_REQUIRE(a[1][2] == a12);
537 1 : CATCH_REQUIRE(a[1][3] == a13);
538 1 : CATCH_REQUIRE(a[2][0] == a20);
539 1 : CATCH_REQUIRE(a[2][1] == a21);
540 1 : CATCH_REQUIRE(a[2][2] == a22);
541 1 : CATCH_REQUIRE(a[2][3] == a23);
542 1 : CATCH_REQUIRE(a[3][0] == a30);
543 1 : CATCH_REQUIRE(a[3][1] == a31);
544 1 : CATCH_REQUIRE(a[3][2] == a32);
545 1 : CATCH_REQUIRE(a[3][3] == a33);
546 :
547 : // create a scalar for our test
548 : //
549 1 : double scalar(frand());
550 1 : while(scalar == 0.0)
551 : {
552 0 : scalar = frand();
553 : }
554 :
555 : // run operation A += <scalar>
556 : //
557 1 : a += scalar;
558 :
559 : // this can't fail because we ensure scalar != 0
560 : //
561 1 : CATCH_REQUIRE_FALSE(a[0][0] == a00);
562 1 : CATCH_REQUIRE_FALSE(a[0][1] == a01);
563 1 : CATCH_REQUIRE_FALSE(a[0][2] == a02);
564 1 : CATCH_REQUIRE_FALSE(a[0][3] == a03);
565 1 : CATCH_REQUIRE_FALSE(a[1][0] == a10);
566 1 : CATCH_REQUIRE_FALSE(a[1][1] == a11);
567 1 : CATCH_REQUIRE_FALSE(a[1][2] == a12);
568 1 : CATCH_REQUIRE_FALSE(a[1][3] == a13);
569 1 : CATCH_REQUIRE_FALSE(a[2][0] == a20);
570 1 : CATCH_REQUIRE_FALSE(a[2][1] == a21);
571 1 : CATCH_REQUIRE_FALSE(a[2][2] == a22);
572 1 : CATCH_REQUIRE_FALSE(a[2][3] == a23);
573 1 : CATCH_REQUIRE_FALSE(a[3][0] == a30);
574 1 : CATCH_REQUIRE_FALSE(a[3][1] == a31);
575 1 : CATCH_REQUIRE_FALSE(a[3][2] == a32);
576 1 : CATCH_REQUIRE_FALSE(a[3][3] == a33);
577 :
578 1 : CATCH_REQUIRE(a[0][0] == a00 + scalar);
579 1 : CATCH_REQUIRE(a[0][1] == a01 + scalar);
580 1 : CATCH_REQUIRE(a[0][2] == a02 + scalar);
581 1 : CATCH_REQUIRE(a[0][3] == a03 + scalar);
582 1 : CATCH_REQUIRE(a[1][0] == a10 + scalar);
583 1 : CATCH_REQUIRE(a[1][1] == a11 + scalar);
584 1 : CATCH_REQUIRE(a[1][2] == a12 + scalar);
585 1 : CATCH_REQUIRE(a[1][3] == a13 + scalar);
586 1 : CATCH_REQUIRE(a[2][0] == a20 + scalar);
587 1 : CATCH_REQUIRE(a[2][1] == a21 + scalar);
588 1 : CATCH_REQUIRE(a[2][2] == a22 + scalar);
589 1 : CATCH_REQUIRE(a[2][3] == a23 + scalar);
590 1 : CATCH_REQUIRE(a[3][0] == a30 + scalar);
591 1 : CATCH_REQUIRE(a[3][1] == a31 + scalar);
592 1 : CATCH_REQUIRE(a[3][2] == a32 + scalar);
593 1 : CATCH_REQUIRE(a[3][3] == a33 + scalar);
594 : }
595 : CATCH_END_SECTION()
596 :
597 8 : CATCH_START_SECTION("matrix: b=a+<scalar>")
598 : {
599 : // setup A
600 : //
601 2 : snap::matrix<double> a(4, 4);
602 :
603 1 : CATCH_REQUIRE(a.rows() == 4);
604 1 : CATCH_REQUIRE(a.columns() == 4);
605 :
606 1 : double const a00(frand());
607 1 : double const a01(frand());
608 1 : double const a02(frand());
609 1 : double const a03(frand());
610 1 : double const a10(frand());
611 1 : double const a11(frand());
612 1 : double const a12(frand());
613 1 : double const a13(frand());
614 1 : double const a20(frand());
615 1 : double const a21(frand());
616 1 : double const a22(frand());
617 1 : double const a23(frand());
618 1 : double const a30(frand());
619 1 : double const a31(frand());
620 1 : double const a32(frand());
621 1 : double const a33(frand());
622 :
623 1 : a[0][0] = a00;
624 1 : a[0][1] = a01;
625 1 : a[0][2] = a02;
626 1 : a[0][3] = a03;
627 1 : a[1][0] = a10;
628 1 : a[1][1] = a11;
629 1 : a[1][2] = a12;
630 1 : a[1][3] = a13;
631 1 : a[2][0] = a20;
632 1 : a[2][1] = a21;
633 1 : a[2][2] = a22;
634 1 : a[2][3] = a23;
635 1 : a[3][0] = a30;
636 1 : a[3][1] = a31;
637 1 : a[3][2] = a32;
638 1 : a[3][3] = a33;
639 :
640 1 : CATCH_REQUIRE(a[0][0] == a00);
641 1 : CATCH_REQUIRE(a[0][1] == a01);
642 1 : CATCH_REQUIRE(a[0][2] == a02);
643 1 : CATCH_REQUIRE(a[0][3] == a03);
644 1 : CATCH_REQUIRE(a[1][0] == a10);
645 1 : CATCH_REQUIRE(a[1][1] == a11);
646 1 : CATCH_REQUIRE(a[1][2] == a12);
647 1 : CATCH_REQUIRE(a[1][3] == a13);
648 1 : CATCH_REQUIRE(a[2][0] == a20);
649 1 : CATCH_REQUIRE(a[2][1] == a21);
650 1 : CATCH_REQUIRE(a[2][2] == a22);
651 1 : CATCH_REQUIRE(a[2][3] == a23);
652 1 : CATCH_REQUIRE(a[3][0] == a30);
653 1 : CATCH_REQUIRE(a[3][1] == a31);
654 1 : CATCH_REQUIRE(a[3][2] == a32);
655 1 : CATCH_REQUIRE(a[3][3] == a33);
656 :
657 : // setup B
658 : //
659 2 : snap::matrix<double> b(4, 4);
660 :
661 1 : CATCH_REQUIRE(b.rows() == 4);
662 1 : CATCH_REQUIRE(b.columns() == 4);
663 :
664 1 : double const b00(frand());
665 1 : double const b01(frand());
666 1 : double const b02(frand());
667 1 : double const b03(frand());
668 1 : double const b10(frand());
669 1 : double const b11(frand());
670 1 : double const b12(frand());
671 1 : double const b13(frand());
672 1 : double const b20(frand());
673 1 : double const b21(frand());
674 1 : double const b22(frand());
675 1 : double const b23(frand());
676 1 : double const b30(frand());
677 1 : double const b31(frand());
678 1 : double const b32(frand());
679 1 : double const b33(frand());
680 :
681 1 : b[0][0] = b00;
682 1 : b[0][1] = b01;
683 1 : b[0][2] = b02;
684 1 : b[0][3] = b03;
685 1 : b[1][0] = b10;
686 1 : b[1][1] = b11;
687 1 : b[1][2] = b12;
688 1 : b[1][3] = b13;
689 1 : b[2][0] = b20;
690 1 : b[2][1] = b21;
691 1 : b[2][2] = b22;
692 1 : b[2][3] = b23;
693 1 : b[3][0] = b30;
694 1 : b[3][1] = b31;
695 1 : b[3][2] = b32;
696 1 : b[3][3] = b33;
697 :
698 1 : CATCH_REQUIRE(b[0][0] == b00);
699 1 : CATCH_REQUIRE(b[0][1] == b01);
700 1 : CATCH_REQUIRE(b[0][2] == b02);
701 1 : CATCH_REQUIRE(b[0][3] == b03);
702 1 : CATCH_REQUIRE(b[1][0] == b10);
703 1 : CATCH_REQUIRE(b[1][1] == b11);
704 1 : CATCH_REQUIRE(b[1][2] == b12);
705 1 : CATCH_REQUIRE(b[1][3] == b13);
706 1 : CATCH_REQUIRE(b[2][0] == b20);
707 1 : CATCH_REQUIRE(b[2][1] == b21);
708 1 : CATCH_REQUIRE(b[2][2] == b22);
709 1 : CATCH_REQUIRE(b[2][3] == b23);
710 1 : CATCH_REQUIRE(b[3][0] == b30);
711 1 : CATCH_REQUIRE(b[3][1] == b31);
712 1 : CATCH_REQUIRE(b[3][2] == b32);
713 1 : CATCH_REQUIRE(b[3][3] == b33);
714 :
715 : // create a scalar for our test
716 : //
717 1 : double scalar(frand());
718 1 : while(scalar == 0.0)
719 : {
720 0 : scalar = frand();
721 : }
722 :
723 : // run operation B = A + <scalar>
724 : //
725 1 : b = a + scalar;
726 :
727 1 : CATCH_REQUIRE(a[0][0] == a00);
728 1 : CATCH_REQUIRE(a[0][1] == a01);
729 1 : CATCH_REQUIRE(a[0][2] == a02);
730 1 : CATCH_REQUIRE(a[0][3] == a03);
731 1 : CATCH_REQUIRE(a[1][0] == a10);
732 1 : CATCH_REQUIRE(a[1][1] == a11);
733 1 : CATCH_REQUIRE(a[1][2] == a12);
734 1 : CATCH_REQUIRE(a[1][3] == a13);
735 1 : CATCH_REQUIRE(a[2][0] == a20);
736 1 : CATCH_REQUIRE(a[2][1] == a21);
737 1 : CATCH_REQUIRE(a[2][2] == a22);
738 1 : CATCH_REQUIRE(a[2][3] == a23);
739 1 : CATCH_REQUIRE(a[3][0] == a30);
740 1 : CATCH_REQUIRE(a[3][1] == a31);
741 1 : CATCH_REQUIRE(a[3][2] == a32);
742 1 : CATCH_REQUIRE(a[3][3] == a33);
743 :
744 : // this can't fail because we ensure scalar != 0
745 : //
746 1 : CATCH_REQUIRE_FALSE(b[0][0] == b00);
747 1 : CATCH_REQUIRE_FALSE(b[0][1] == b01);
748 1 : CATCH_REQUIRE_FALSE(b[0][2] == b02);
749 1 : CATCH_REQUIRE_FALSE(b[0][3] == b03);
750 1 : CATCH_REQUIRE_FALSE(b[1][0] == b10);
751 1 : CATCH_REQUIRE_FALSE(b[1][1] == b11);
752 1 : CATCH_REQUIRE_FALSE(b[1][2] == b12);
753 1 : CATCH_REQUIRE_FALSE(b[1][3] == b13);
754 1 : CATCH_REQUIRE_FALSE(b[2][0] == b20);
755 1 : CATCH_REQUIRE_FALSE(b[2][1] == b21);
756 1 : CATCH_REQUIRE_FALSE(b[2][2] == b22);
757 1 : CATCH_REQUIRE_FALSE(b[2][3] == b23);
758 1 : CATCH_REQUIRE_FALSE(b[3][0] == b30);
759 1 : CATCH_REQUIRE_FALSE(b[3][1] == b31);
760 1 : CATCH_REQUIRE_FALSE(b[3][2] == b32);
761 1 : CATCH_REQUIRE_FALSE(b[3][3] == b33);
762 :
763 1 : CATCH_REQUIRE(b[0][0] == a00 + scalar);
764 1 : CATCH_REQUIRE(b[0][1] == a01 + scalar);
765 1 : CATCH_REQUIRE(b[0][2] == a02 + scalar);
766 1 : CATCH_REQUIRE(b[0][3] == a03 + scalar);
767 1 : CATCH_REQUIRE(b[1][0] == a10 + scalar);
768 1 : CATCH_REQUIRE(b[1][1] == a11 + scalar);
769 1 : CATCH_REQUIRE(b[1][2] == a12 + scalar);
770 1 : CATCH_REQUIRE(b[1][3] == a13 + scalar);
771 1 : CATCH_REQUIRE(b[2][0] == a20 + scalar);
772 1 : CATCH_REQUIRE(b[2][1] == a21 + scalar);
773 1 : CATCH_REQUIRE(b[2][2] == a22 + scalar);
774 1 : CATCH_REQUIRE(b[2][3] == a23 + scalar);
775 1 : CATCH_REQUIRE(b[3][0] == a30 + scalar);
776 1 : CATCH_REQUIRE(b[3][1] == a31 + scalar);
777 1 : CATCH_REQUIRE(b[3][2] == a32 + scalar);
778 1 : CATCH_REQUIRE(b[3][3] == a33 + scalar);
779 : }
780 : CATCH_END_SECTION()
781 :
782 8 : CATCH_START_SECTION("matrix: c=a+b")
783 : {
784 : // setup A
785 : //
786 2 : snap::matrix<double> a(4, 4);
787 :
788 1 : CATCH_REQUIRE(a.rows() == 4);
789 1 : CATCH_REQUIRE(a.columns() == 4);
790 :
791 1 : double const a00(frand());
792 1 : double const a01(frand());
793 1 : double const a02(frand());
794 1 : double const a03(frand());
795 1 : double const a10(frand());
796 1 : double const a11(frand());
797 1 : double const a12(frand());
798 1 : double const a13(frand());
799 1 : double const a20(frand());
800 1 : double const a21(frand());
801 1 : double const a22(frand());
802 1 : double const a23(frand());
803 1 : double const a30(frand());
804 1 : double const a31(frand());
805 1 : double const a32(frand());
806 1 : double const a33(frand());
807 :
808 1 : a[0][0] = a00;
809 1 : a[0][1] = a01;
810 1 : a[0][2] = a02;
811 1 : a[0][3] = a03;
812 1 : a[1][0] = a10;
813 1 : a[1][1] = a11;
814 1 : a[1][2] = a12;
815 1 : a[1][3] = a13;
816 1 : a[2][0] = a20;
817 1 : a[2][1] = a21;
818 1 : a[2][2] = a22;
819 1 : a[2][3] = a23;
820 1 : a[3][0] = a30;
821 1 : a[3][1] = a31;
822 1 : a[3][2] = a32;
823 1 : a[3][3] = a33;
824 :
825 1 : CATCH_REQUIRE(a[0][0] == a00);
826 1 : CATCH_REQUIRE(a[0][1] == a01);
827 1 : CATCH_REQUIRE(a[0][2] == a02);
828 1 : CATCH_REQUIRE(a[0][3] == a03);
829 1 : CATCH_REQUIRE(a[1][0] == a10);
830 1 : CATCH_REQUIRE(a[1][1] == a11);
831 1 : CATCH_REQUIRE(a[1][2] == a12);
832 1 : CATCH_REQUIRE(a[1][3] == a13);
833 1 : CATCH_REQUIRE(a[2][0] == a20);
834 1 : CATCH_REQUIRE(a[2][1] == a21);
835 1 : CATCH_REQUIRE(a[2][2] == a22);
836 1 : CATCH_REQUIRE(a[2][3] == a23);
837 1 : CATCH_REQUIRE(a[3][0] == a30);
838 1 : CATCH_REQUIRE(a[3][1] == a31);
839 1 : CATCH_REQUIRE(a[3][2] == a32);
840 1 : CATCH_REQUIRE(a[3][3] == a33);
841 :
842 : // setup B
843 : //
844 2 : snap::matrix<double> b(4, 4);
845 :
846 1 : CATCH_REQUIRE(b.rows() == 4);
847 1 : CATCH_REQUIRE(b.columns() == 4);
848 :
849 1 : double const b00(frand());
850 1 : double const b01(frand());
851 1 : double const b02(frand());
852 1 : double const b03(frand());
853 1 : double const b10(frand());
854 1 : double const b11(frand());
855 1 : double const b12(frand());
856 1 : double const b13(frand());
857 1 : double const b20(frand());
858 1 : double const b21(frand());
859 1 : double const b22(frand());
860 1 : double const b23(frand());
861 1 : double const b30(frand());
862 1 : double const b31(frand());
863 1 : double const b32(frand());
864 1 : double const b33(frand());
865 :
866 1 : b[0][0] = b00;
867 1 : b[0][1] = b01;
868 1 : b[0][2] = b02;
869 1 : b[0][3] = b03;
870 1 : b[1][0] = b10;
871 1 : b[1][1] = b11;
872 1 : b[1][2] = b12;
873 1 : b[1][3] = b13;
874 1 : b[2][0] = b20;
875 1 : b[2][1] = b21;
876 1 : b[2][2] = b22;
877 1 : b[2][3] = b23;
878 1 : b[3][0] = b30;
879 1 : b[3][1] = b31;
880 1 : b[3][2] = b32;
881 1 : b[3][3] = b33;
882 :
883 1 : CATCH_REQUIRE(b[0][0] == b00);
884 1 : CATCH_REQUIRE(b[0][1] == b01);
885 1 : CATCH_REQUIRE(b[0][2] == b02);
886 1 : CATCH_REQUIRE(b[0][3] == b03);
887 1 : CATCH_REQUIRE(b[1][0] == b10);
888 1 : CATCH_REQUIRE(b[1][1] == b11);
889 1 : CATCH_REQUIRE(b[1][2] == b12);
890 1 : CATCH_REQUIRE(b[1][3] == b13);
891 1 : CATCH_REQUIRE(b[2][0] == b20);
892 1 : CATCH_REQUIRE(b[2][1] == b21);
893 1 : CATCH_REQUIRE(b[2][2] == b22);
894 1 : CATCH_REQUIRE(b[2][3] == b23);
895 1 : CATCH_REQUIRE(b[3][0] == b30);
896 1 : CATCH_REQUIRE(b[3][1] == b31);
897 1 : CATCH_REQUIRE(b[3][2] == b32);
898 1 : CATCH_REQUIRE(b[3][3] == b33);
899 :
900 : // setup C
901 : //
902 2 : snap::matrix<double> c(4, 4);
903 :
904 1 : CATCH_REQUIRE(c.rows() == 4);
905 1 : CATCH_REQUIRE(c.columns() == 4);
906 :
907 1 : double const c00(frand());
908 1 : double const c01(frand());
909 1 : double const c02(frand());
910 1 : double const c03(frand());
911 1 : double const c10(frand());
912 1 : double const c11(frand());
913 1 : double const c12(frand());
914 1 : double const c13(frand());
915 1 : double const c20(frand());
916 1 : double const c21(frand());
917 1 : double const c22(frand());
918 1 : double const c23(frand());
919 1 : double const c30(frand());
920 1 : double const c31(frand());
921 1 : double const c32(frand());
922 1 : double const c33(frand());
923 :
924 1 : c[0][0] = c00;
925 1 : c[0][1] = c01;
926 1 : c[0][2] = c02;
927 1 : c[0][3] = c03;
928 1 : c[1][0] = c10;
929 1 : c[1][1] = c11;
930 1 : c[1][2] = c12;
931 1 : c[1][3] = c13;
932 1 : c[2][0] = c20;
933 1 : c[2][1] = c21;
934 1 : c[2][2] = c22;
935 1 : c[2][3] = c23;
936 1 : c[3][0] = c30;
937 1 : c[3][1] = c31;
938 1 : c[3][2] = c32;
939 1 : c[3][3] = c33;
940 :
941 1 : CATCH_REQUIRE(c[0][0] == c00);
942 1 : CATCH_REQUIRE(c[0][1] == c01);
943 1 : CATCH_REQUIRE(c[0][2] == c02);
944 1 : CATCH_REQUIRE(c[0][3] == c03);
945 1 : CATCH_REQUIRE(c[1][0] == c10);
946 1 : CATCH_REQUIRE(c[1][1] == c11);
947 1 : CATCH_REQUIRE(c[1][2] == c12);
948 1 : CATCH_REQUIRE(c[1][3] == c13);
949 1 : CATCH_REQUIRE(c[2][0] == c20);
950 1 : CATCH_REQUIRE(c[2][1] == c21);
951 1 : CATCH_REQUIRE(c[2][2] == c22);
952 1 : CATCH_REQUIRE(c[2][3] == c23);
953 1 : CATCH_REQUIRE(c[3][0] == c30);
954 1 : CATCH_REQUIRE(c[3][1] == c31);
955 1 : CATCH_REQUIRE(c[3][2] == c32);
956 1 : CATCH_REQUIRE(c[3][3] == c33);
957 :
958 : // run operation C = A + B
959 : //
960 1 : c = a + b;
961 :
962 1 : CATCH_REQUIRE(a[0][0] == a00);
963 1 : CATCH_REQUIRE(a[0][1] == a01);
964 1 : CATCH_REQUIRE(a[0][2] == a02);
965 1 : CATCH_REQUIRE(a[0][3] == a03);
966 1 : CATCH_REQUIRE(a[1][0] == a10);
967 1 : CATCH_REQUIRE(a[1][1] == a11);
968 1 : CATCH_REQUIRE(a[1][2] == a12);
969 1 : CATCH_REQUIRE(a[1][3] == a13);
970 1 : CATCH_REQUIRE(a[2][0] == a20);
971 1 : CATCH_REQUIRE(a[2][1] == a21);
972 1 : CATCH_REQUIRE(a[2][2] == a22);
973 1 : CATCH_REQUIRE(a[2][3] == a23);
974 1 : CATCH_REQUIRE(a[3][0] == a30);
975 1 : CATCH_REQUIRE(a[3][1] == a31);
976 1 : CATCH_REQUIRE(a[3][2] == a32);
977 1 : CATCH_REQUIRE(a[3][3] == a33);
978 :
979 1 : CATCH_REQUIRE(b[0][0] == b00);
980 1 : CATCH_REQUIRE(b[0][1] == b01);
981 1 : CATCH_REQUIRE(b[0][2] == b02);
982 1 : CATCH_REQUIRE(b[0][3] == b03);
983 1 : CATCH_REQUIRE(b[1][0] == b10);
984 1 : CATCH_REQUIRE(b[1][1] == b11);
985 1 : CATCH_REQUIRE(b[1][2] == b12);
986 1 : CATCH_REQUIRE(b[1][3] == b13);
987 1 : CATCH_REQUIRE(b[2][0] == b20);
988 1 : CATCH_REQUIRE(b[2][1] == b21);
989 1 : CATCH_REQUIRE(b[2][2] == b22);
990 1 : CATCH_REQUIRE(b[2][3] == b23);
991 1 : CATCH_REQUIRE(b[3][0] == b30);
992 1 : CATCH_REQUIRE(b[3][1] == b31);
993 1 : CATCH_REQUIRE(b[3][2] == b32);
994 1 : CATCH_REQUIRE(b[3][3] == b33);
995 :
996 : // this could fail
997 : //CATCH_REQUIRE_FALSE(c[0][0] == c00);
998 : //CATCH_REQUIRE_FALSE(c[0][1] == c01);
999 : //CATCH_REQUIRE_FALSE(c[0][2] == c02);
1000 : //CATCH_REQUIRE_FALSE(c[0][3] == c03);
1001 : //CATCH_REQUIRE_FALSE(c[1][0] == c10);
1002 : //CATCH_REQUIRE_FALSE(c[1][1] == c11);
1003 : //CATCH_REQUIRE_FALSE(c[1][2] == c12);
1004 : //CATCH_REQUIRE_FALSE(c[1][3] == c13);
1005 : //CATCH_REQUIRE_FALSE(c[2][0] == c20);
1006 : //CATCH_REQUIRE_FALSE(c[2][1] == c21);
1007 : //CATCH_REQUIRE_FALSE(c[2][2] == c22);
1008 : //CATCH_REQUIRE_FALSE(c[2][3] == c23);
1009 : //CATCH_REQUIRE_FALSE(c[3][0] == c30);
1010 : //CATCH_REQUIRE_FALSE(c[3][1] == c31);
1011 : //CATCH_REQUIRE_FALSE(c[3][2] == c32);
1012 : //CATCH_REQUIRE_FALSE(c[3][3] == c33);
1013 :
1014 1 : CATCH_REQUIRE(c[0][0] == a00 + b00);
1015 1 : CATCH_REQUIRE(c[0][1] == a01 + b01);
1016 1 : CATCH_REQUIRE(c[0][2] == a02 + b02);
1017 1 : CATCH_REQUIRE(c[0][3] == a03 + b03);
1018 1 : CATCH_REQUIRE(c[1][0] == a10 + b10);
1019 1 : CATCH_REQUIRE(c[1][1] == a11 + b11);
1020 1 : CATCH_REQUIRE(c[1][2] == a12 + b12);
1021 1 : CATCH_REQUIRE(c[1][3] == a13 + b13);
1022 1 : CATCH_REQUIRE(c[2][0] == a20 + b20);
1023 1 : CATCH_REQUIRE(c[2][1] == a21 + b21);
1024 1 : CATCH_REQUIRE(c[2][2] == a22 + b22);
1025 1 : CATCH_REQUIRE(c[2][3] == a23 + b23);
1026 1 : CATCH_REQUIRE(c[3][0] == a30 + b30);
1027 1 : CATCH_REQUIRE(c[3][1] == a31 + b31);
1028 1 : CATCH_REQUIRE(c[3][2] == a32 + b32);
1029 1 : CATCH_REQUIRE(c[3][3] == a33 + b33);
1030 : }
1031 : CATCH_END_SECTION()
1032 :
1033 8 : CATCH_START_SECTION("matrix: a+=b")
1034 : {
1035 : // setup A
1036 : //
1037 2 : snap::matrix<double> a(4, 4);
1038 :
1039 1 : CATCH_REQUIRE(a.rows() == 4);
1040 1 : CATCH_REQUIRE(a.columns() == 4);
1041 :
1042 1 : double const a00(frand());
1043 1 : double const a01(frand());
1044 1 : double const a02(frand());
1045 1 : double const a03(frand());
1046 1 : double const a10(frand());
1047 1 : double const a11(frand());
1048 1 : double const a12(frand());
1049 1 : double const a13(frand());
1050 1 : double const a20(frand());
1051 1 : double const a21(frand());
1052 1 : double const a22(frand());
1053 1 : double const a23(frand());
1054 1 : double const a30(frand());
1055 1 : double const a31(frand());
1056 1 : double const a32(frand());
1057 1 : double const a33(frand());
1058 :
1059 1 : a[0][0] = a00;
1060 1 : a[0][1] = a01;
1061 1 : a[0][2] = a02;
1062 1 : a[0][3] = a03;
1063 1 : a[1][0] = a10;
1064 1 : a[1][1] = a11;
1065 1 : a[1][2] = a12;
1066 1 : a[1][3] = a13;
1067 1 : a[2][0] = a20;
1068 1 : a[2][1] = a21;
1069 1 : a[2][2] = a22;
1070 1 : a[2][3] = a23;
1071 1 : a[3][0] = a30;
1072 1 : a[3][1] = a31;
1073 1 : a[3][2] = a32;
1074 1 : a[3][3] = a33;
1075 :
1076 1 : CATCH_REQUIRE(a[0][0] == a00);
1077 1 : CATCH_REQUIRE(a[0][1] == a01);
1078 1 : CATCH_REQUIRE(a[0][2] == a02);
1079 1 : CATCH_REQUIRE(a[0][3] == a03);
1080 1 : CATCH_REQUIRE(a[1][0] == a10);
1081 1 : CATCH_REQUIRE(a[1][1] == a11);
1082 1 : CATCH_REQUIRE(a[1][2] == a12);
1083 1 : CATCH_REQUIRE(a[1][3] == a13);
1084 1 : CATCH_REQUIRE(a[2][0] == a20);
1085 1 : CATCH_REQUIRE(a[2][1] == a21);
1086 1 : CATCH_REQUIRE(a[2][2] == a22);
1087 1 : CATCH_REQUIRE(a[2][3] == a23);
1088 1 : CATCH_REQUIRE(a[3][0] == a30);
1089 1 : CATCH_REQUIRE(a[3][1] == a31);
1090 1 : CATCH_REQUIRE(a[3][2] == a32);
1091 1 : CATCH_REQUIRE(a[3][3] == a33);
1092 :
1093 : // setup B
1094 : //
1095 2 : snap::matrix<double> b(4, 4);
1096 :
1097 1 : CATCH_REQUIRE(b.rows() == 4);
1098 1 : CATCH_REQUIRE(b.columns() == 4);
1099 :
1100 1 : double const b00(frand());
1101 1 : double const b01(frand());
1102 1 : double const b02(frand());
1103 1 : double const b03(frand());
1104 1 : double const b10(frand());
1105 1 : double const b11(frand());
1106 1 : double const b12(frand());
1107 1 : double const b13(frand());
1108 1 : double const b20(frand());
1109 1 : double const b21(frand());
1110 1 : double const b22(frand());
1111 1 : double const b23(frand());
1112 1 : double const b30(frand());
1113 1 : double const b31(frand());
1114 1 : double const b32(frand());
1115 1 : double const b33(frand());
1116 :
1117 1 : b[0][0] = b00;
1118 1 : b[0][1] = b01;
1119 1 : b[0][2] = b02;
1120 1 : b[0][3] = b03;
1121 1 : b[1][0] = b10;
1122 1 : b[1][1] = b11;
1123 1 : b[1][2] = b12;
1124 1 : b[1][3] = b13;
1125 1 : b[2][0] = b20;
1126 1 : b[2][1] = b21;
1127 1 : b[2][2] = b22;
1128 1 : b[2][3] = b23;
1129 1 : b[3][0] = b30;
1130 1 : b[3][1] = b31;
1131 1 : b[3][2] = b32;
1132 1 : b[3][3] = b33;
1133 :
1134 1 : CATCH_REQUIRE(b[0][0] == b00);
1135 1 : CATCH_REQUIRE(b[0][1] == b01);
1136 1 : CATCH_REQUIRE(b[0][2] == b02);
1137 1 : CATCH_REQUIRE(b[0][3] == b03);
1138 1 : CATCH_REQUIRE(b[1][0] == b10);
1139 1 : CATCH_REQUIRE(b[1][1] == b11);
1140 1 : CATCH_REQUIRE(b[1][2] == b12);
1141 1 : CATCH_REQUIRE(b[1][3] == b13);
1142 1 : CATCH_REQUIRE(b[2][0] == b20);
1143 1 : CATCH_REQUIRE(b[2][1] == b21);
1144 1 : CATCH_REQUIRE(b[2][2] == b22);
1145 1 : CATCH_REQUIRE(b[2][3] == b23);
1146 1 : CATCH_REQUIRE(b[3][0] == b30);
1147 1 : CATCH_REQUIRE(b[3][1] == b31);
1148 1 : CATCH_REQUIRE(b[3][2] == b32);
1149 1 : CATCH_REQUIRE(b[3][3] == b33);
1150 :
1151 : // run operation A += B
1152 : //
1153 1 : a += b;
1154 :
1155 : // this could fail if any bXX is 0.0
1156 : //
1157 : //CATCH_REQUIRE_FALSE(a[0][0] == a00);
1158 : //CATCH_REQUIRE_FALSE(a[0][1] == a01);
1159 : //CATCH_REQUIRE_FALSE(a[0][2] == a02);
1160 : //CATCH_REQUIRE_FALSE(a[0][3] == a03);
1161 : //CATCH_REQUIRE_FALSE(a[1][0] == a10);
1162 : //CATCH_REQUIRE_FALSE(a[1][1] == a11);
1163 : //CATCH_REQUIRE_FALSE(a[1][2] == a12);
1164 : //CATCH_REQUIRE_FALSE(a[1][3] == a13);
1165 : //CATCH_REQUIRE_FALSE(a[2][0] == a20);
1166 : //CATCH_REQUIRE_FALSE(a[2][1] == a21);
1167 : //CATCH_REQUIRE_FALSE(a[2][2] == a22);
1168 : //CATCH_REQUIRE_FALSE(a[2][3] == a23);
1169 : //CATCH_REQUIRE_FALSE(a[3][0] == a30);
1170 : //CATCH_REQUIRE_FALSE(a[3][1] == a31);
1171 : //CATCH_REQUIRE_FALSE(a[3][2] == a32);
1172 : //CATCH_REQUIRE_FALSE(a[3][3] == a33);
1173 :
1174 1 : CATCH_REQUIRE(b[0][0] == b00);
1175 1 : CATCH_REQUIRE(b[0][1] == b01);
1176 1 : CATCH_REQUIRE(b[0][2] == b02);
1177 1 : CATCH_REQUIRE(b[0][3] == b03);
1178 1 : CATCH_REQUIRE(b[1][0] == b10);
1179 1 : CATCH_REQUIRE(b[1][1] == b11);
1180 1 : CATCH_REQUIRE(b[1][2] == b12);
1181 1 : CATCH_REQUIRE(b[1][3] == b13);
1182 1 : CATCH_REQUIRE(b[2][0] == b20);
1183 1 : CATCH_REQUIRE(b[2][1] == b21);
1184 1 : CATCH_REQUIRE(b[2][2] == b22);
1185 1 : CATCH_REQUIRE(b[2][3] == b23);
1186 1 : CATCH_REQUIRE(b[3][0] == b30);
1187 1 : CATCH_REQUIRE(b[3][1] == b31);
1188 1 : CATCH_REQUIRE(b[3][2] == b32);
1189 1 : CATCH_REQUIRE(b[3][3] == b33);
1190 :
1191 1 : CATCH_REQUIRE(a[0][0] == a00 + b00);
1192 1 : CATCH_REQUIRE(a[0][1] == a01 + b01);
1193 1 : CATCH_REQUIRE(a[0][2] == a02 + b02);
1194 1 : CATCH_REQUIRE(a[0][3] == a03 + b03);
1195 1 : CATCH_REQUIRE(a[1][0] == a10 + b10);
1196 1 : CATCH_REQUIRE(a[1][1] == a11 + b11);
1197 1 : CATCH_REQUIRE(a[1][2] == a12 + b12);
1198 1 : CATCH_REQUIRE(a[1][3] == a13 + b13);
1199 1 : CATCH_REQUIRE(a[2][0] == a20 + b20);
1200 1 : CATCH_REQUIRE(a[2][1] == a21 + b21);
1201 1 : CATCH_REQUIRE(a[2][2] == a22 + b22);
1202 1 : CATCH_REQUIRE(a[2][3] == a23 + b23);
1203 1 : CATCH_REQUIRE(a[3][0] == a30 + b30);
1204 1 : CATCH_REQUIRE(a[3][1] == a31 + b31);
1205 1 : CATCH_REQUIRE(a[3][2] == a32 + b32);
1206 1 : CATCH_REQUIRE(a[3][3] == a33 + b33);
1207 : }
1208 : CATCH_END_SECTION()
1209 : }
1210 :
1211 : // create two random 4x4 matrices and make sure the add works
1212 : //
1213 16 : CATCH_GIVEN("sub")
1214 : {
1215 8 : CATCH_START_SECTION("matrix: b=a-<scalar>")
1216 : {
1217 : // setup A
1218 : //
1219 2 : snap::matrix<double> a(4, 4);
1220 :
1221 1 : CATCH_REQUIRE(a.rows() == 4);
1222 1 : CATCH_REQUIRE(a.columns() == 4);
1223 :
1224 1 : double const a00(frand());
1225 1 : double const a01(frand());
1226 1 : double const a02(frand());
1227 1 : double const a03(frand());
1228 1 : double const a10(frand());
1229 1 : double const a11(frand());
1230 1 : double const a12(frand());
1231 1 : double const a13(frand());
1232 1 : double const a20(frand());
1233 1 : double const a21(frand());
1234 1 : double const a22(frand());
1235 1 : double const a23(frand());
1236 1 : double const a30(frand());
1237 1 : double const a31(frand());
1238 1 : double const a32(frand());
1239 1 : double const a33(frand());
1240 :
1241 1 : a[0][0] = a00;
1242 1 : a[0][1] = a01;
1243 1 : a[0][2] = a02;
1244 1 : a[0][3] = a03;
1245 1 : a[1][0] = a10;
1246 1 : a[1][1] = a11;
1247 1 : a[1][2] = a12;
1248 1 : a[1][3] = a13;
1249 1 : a[2][0] = a20;
1250 1 : a[2][1] = a21;
1251 1 : a[2][2] = a22;
1252 1 : a[2][3] = a23;
1253 1 : a[3][0] = a30;
1254 1 : a[3][1] = a31;
1255 1 : a[3][2] = a32;
1256 1 : a[3][3] = a33;
1257 :
1258 1 : CATCH_REQUIRE(a[0][0] == a00);
1259 1 : CATCH_REQUIRE(a[0][1] == a01);
1260 1 : CATCH_REQUIRE(a[0][2] == a02);
1261 1 : CATCH_REQUIRE(a[0][3] == a03);
1262 1 : CATCH_REQUIRE(a[1][0] == a10);
1263 1 : CATCH_REQUIRE(a[1][1] == a11);
1264 1 : CATCH_REQUIRE(a[1][2] == a12);
1265 1 : CATCH_REQUIRE(a[1][3] == a13);
1266 1 : CATCH_REQUIRE(a[2][0] == a20);
1267 1 : CATCH_REQUIRE(a[2][1] == a21);
1268 1 : CATCH_REQUIRE(a[2][2] == a22);
1269 1 : CATCH_REQUIRE(a[2][3] == a23);
1270 1 : CATCH_REQUIRE(a[3][0] == a30);
1271 1 : CATCH_REQUIRE(a[3][1] == a31);
1272 1 : CATCH_REQUIRE(a[3][2] == a32);
1273 1 : CATCH_REQUIRE(a[3][3] == a33);
1274 :
1275 : // setup B
1276 : //
1277 2 : snap::matrix<double> b(4, 4);
1278 :
1279 1 : CATCH_REQUIRE(b.rows() == 4);
1280 1 : CATCH_REQUIRE(b.columns() == 4);
1281 :
1282 1 : double const b00(frand());
1283 1 : double const b01(frand());
1284 1 : double const b02(frand());
1285 1 : double const b03(frand());
1286 1 : double const b10(frand());
1287 1 : double const b11(frand());
1288 1 : double const b12(frand());
1289 1 : double const b13(frand());
1290 1 : double const b20(frand());
1291 1 : double const b21(frand());
1292 1 : double const b22(frand());
1293 1 : double const b23(frand());
1294 1 : double const b30(frand());
1295 1 : double const b31(frand());
1296 1 : double const b32(frand());
1297 1 : double const b33(frand());
1298 :
1299 1 : b[0][0] = b00;
1300 1 : b[0][1] = b01;
1301 1 : b[0][2] = b02;
1302 1 : b[0][3] = b03;
1303 1 : b[1][0] = b10;
1304 1 : b[1][1] = b11;
1305 1 : b[1][2] = b12;
1306 1 : b[1][3] = b13;
1307 1 : b[2][0] = b20;
1308 1 : b[2][1] = b21;
1309 1 : b[2][2] = b22;
1310 1 : b[2][3] = b23;
1311 1 : b[3][0] = b30;
1312 1 : b[3][1] = b31;
1313 1 : b[3][2] = b32;
1314 1 : b[3][3] = b33;
1315 :
1316 1 : CATCH_REQUIRE(b[0][0] == b00);
1317 1 : CATCH_REQUIRE(b[0][1] == b01);
1318 1 : CATCH_REQUIRE(b[0][2] == b02);
1319 1 : CATCH_REQUIRE(b[0][3] == b03);
1320 1 : CATCH_REQUIRE(b[1][0] == b10);
1321 1 : CATCH_REQUIRE(b[1][1] == b11);
1322 1 : CATCH_REQUIRE(b[1][2] == b12);
1323 1 : CATCH_REQUIRE(b[1][3] == b13);
1324 1 : CATCH_REQUIRE(b[2][0] == b20);
1325 1 : CATCH_REQUIRE(b[2][1] == b21);
1326 1 : CATCH_REQUIRE(b[2][2] == b22);
1327 1 : CATCH_REQUIRE(b[2][3] == b23);
1328 1 : CATCH_REQUIRE(b[3][0] == b30);
1329 1 : CATCH_REQUIRE(b[3][1] == b31);
1330 1 : CATCH_REQUIRE(b[3][2] == b32);
1331 1 : CATCH_REQUIRE(b[3][3] == b33);
1332 :
1333 : // create a scalar for our test
1334 : //
1335 1 : double scalar(frand());
1336 1 : while(scalar == 0.0)
1337 : {
1338 0 : scalar = frand();
1339 : }
1340 :
1341 : // run operation B = A - <scalar>
1342 : //
1343 1 : b = a - scalar;
1344 :
1345 1 : CATCH_REQUIRE(a[0][0] == a00);
1346 1 : CATCH_REQUIRE(a[0][1] == a01);
1347 1 : CATCH_REQUIRE(a[0][2] == a02);
1348 1 : CATCH_REQUIRE(a[0][3] == a03);
1349 1 : CATCH_REQUIRE(a[1][0] == a10);
1350 1 : CATCH_REQUIRE(a[1][1] == a11);
1351 1 : CATCH_REQUIRE(a[1][2] == a12);
1352 1 : CATCH_REQUIRE(a[1][3] == a13);
1353 1 : CATCH_REQUIRE(a[2][0] == a20);
1354 1 : CATCH_REQUIRE(a[2][1] == a21);
1355 1 : CATCH_REQUIRE(a[2][2] == a22);
1356 1 : CATCH_REQUIRE(a[2][3] == a23);
1357 1 : CATCH_REQUIRE(a[3][0] == a30);
1358 1 : CATCH_REQUIRE(a[3][1] == a31);
1359 1 : CATCH_REQUIRE(a[3][2] == a32);
1360 1 : CATCH_REQUIRE(a[3][3] == a33);
1361 :
1362 : // this can't fail because we ensure scalar != 0
1363 : //
1364 1 : CATCH_REQUIRE_FALSE(b[0][0] == b00);
1365 1 : CATCH_REQUIRE_FALSE(b[0][1] == b01);
1366 1 : CATCH_REQUIRE_FALSE(b[0][2] == b02);
1367 1 : CATCH_REQUIRE_FALSE(b[0][3] == b03);
1368 1 : CATCH_REQUIRE_FALSE(b[1][0] == b10);
1369 1 : CATCH_REQUIRE_FALSE(b[1][1] == b11);
1370 1 : CATCH_REQUIRE_FALSE(b[1][2] == b12);
1371 1 : CATCH_REQUIRE_FALSE(b[1][3] == b13);
1372 1 : CATCH_REQUIRE_FALSE(b[2][0] == b20);
1373 1 : CATCH_REQUIRE_FALSE(b[2][1] == b21);
1374 1 : CATCH_REQUIRE_FALSE(b[2][2] == b22);
1375 1 : CATCH_REQUIRE_FALSE(b[2][3] == b23);
1376 1 : CATCH_REQUIRE_FALSE(b[3][0] == b30);
1377 1 : CATCH_REQUIRE_FALSE(b[3][1] == b31);
1378 1 : CATCH_REQUIRE_FALSE(b[3][2] == b32);
1379 1 : CATCH_REQUIRE_FALSE(b[3][3] == b33);
1380 :
1381 1 : CATCH_REQUIRE(b[0][0] == a00 - scalar);
1382 1 : CATCH_REQUIRE(b[0][1] == a01 - scalar);
1383 1 : CATCH_REQUIRE(b[0][2] == a02 - scalar);
1384 1 : CATCH_REQUIRE(b[0][3] == a03 - scalar);
1385 1 : CATCH_REQUIRE(b[1][0] == a10 - scalar);
1386 1 : CATCH_REQUIRE(b[1][1] == a11 - scalar);
1387 1 : CATCH_REQUIRE(b[1][2] == a12 - scalar);
1388 1 : CATCH_REQUIRE(b[1][3] == a13 - scalar);
1389 1 : CATCH_REQUIRE(b[2][0] == a20 - scalar);
1390 1 : CATCH_REQUIRE(b[2][1] == a21 - scalar);
1391 1 : CATCH_REQUIRE(b[2][2] == a22 - scalar);
1392 1 : CATCH_REQUIRE(b[2][3] == a23 - scalar);
1393 1 : CATCH_REQUIRE(b[3][0] == a30 - scalar);
1394 1 : CATCH_REQUIRE(b[3][1] == a31 - scalar);
1395 1 : CATCH_REQUIRE(b[3][2] == a32 - scalar);
1396 1 : CATCH_REQUIRE(b[3][3] == a33 - scalar);
1397 : }
1398 : CATCH_END_SECTION()
1399 :
1400 8 : CATCH_START_SECTION("matrix: a-=<scalar>")
1401 : {
1402 : // setup A
1403 : //
1404 2 : snap::matrix<double> a(4, 4);
1405 :
1406 1 : CATCH_REQUIRE(a.rows() == 4);
1407 1 : CATCH_REQUIRE(a.columns() == 4);
1408 :
1409 1 : double const a00(frand());
1410 1 : double const a01(frand());
1411 1 : double const a02(frand());
1412 1 : double const a03(frand());
1413 1 : double const a10(frand());
1414 1 : double const a11(frand());
1415 1 : double const a12(frand());
1416 1 : double const a13(frand());
1417 1 : double const a20(frand());
1418 1 : double const a21(frand());
1419 1 : double const a22(frand());
1420 1 : double const a23(frand());
1421 1 : double const a30(frand());
1422 1 : double const a31(frand());
1423 1 : double const a32(frand());
1424 1 : double const a33(frand());
1425 :
1426 1 : a[0][0] = a00;
1427 1 : a[0][1] = a01;
1428 1 : a[0][2] = a02;
1429 1 : a[0][3] = a03;
1430 1 : a[1][0] = a10;
1431 1 : a[1][1] = a11;
1432 1 : a[1][2] = a12;
1433 1 : a[1][3] = a13;
1434 1 : a[2][0] = a20;
1435 1 : a[2][1] = a21;
1436 1 : a[2][2] = a22;
1437 1 : a[2][3] = a23;
1438 1 : a[3][0] = a30;
1439 1 : a[3][1] = a31;
1440 1 : a[3][2] = a32;
1441 1 : a[3][3] = a33;
1442 :
1443 1 : CATCH_REQUIRE(a[0][0] == a00);
1444 1 : CATCH_REQUIRE(a[0][1] == a01);
1445 1 : CATCH_REQUIRE(a[0][2] == a02);
1446 1 : CATCH_REQUIRE(a[0][3] == a03);
1447 1 : CATCH_REQUIRE(a[1][0] == a10);
1448 1 : CATCH_REQUIRE(a[1][1] == a11);
1449 1 : CATCH_REQUIRE(a[1][2] == a12);
1450 1 : CATCH_REQUIRE(a[1][3] == a13);
1451 1 : CATCH_REQUIRE(a[2][0] == a20);
1452 1 : CATCH_REQUIRE(a[2][1] == a21);
1453 1 : CATCH_REQUIRE(a[2][2] == a22);
1454 1 : CATCH_REQUIRE(a[2][3] == a23);
1455 1 : CATCH_REQUIRE(a[3][0] == a30);
1456 1 : CATCH_REQUIRE(a[3][1] == a31);
1457 1 : CATCH_REQUIRE(a[3][2] == a32);
1458 1 : CATCH_REQUIRE(a[3][3] == a33);
1459 :
1460 : // create a scalar for our test
1461 : //
1462 1 : double scalar(frand());
1463 1 : while(scalar == 0.0)
1464 : {
1465 0 : scalar = frand();
1466 : }
1467 :
1468 : // run operation A -= <scalar>
1469 : //
1470 1 : a -= scalar;
1471 :
1472 : // this can't fail because we ensure scalar != 0
1473 : //
1474 1 : CATCH_REQUIRE_FALSE(a[0][0] == a00);
1475 1 : CATCH_REQUIRE_FALSE(a[0][1] == a01);
1476 1 : CATCH_REQUIRE_FALSE(a[0][2] == a02);
1477 1 : CATCH_REQUIRE_FALSE(a[0][3] == a03);
1478 1 : CATCH_REQUIRE_FALSE(a[1][0] == a10);
1479 1 : CATCH_REQUIRE_FALSE(a[1][1] == a11);
1480 1 : CATCH_REQUIRE_FALSE(a[1][2] == a12);
1481 1 : CATCH_REQUIRE_FALSE(a[1][3] == a13);
1482 1 : CATCH_REQUIRE_FALSE(a[2][0] == a20);
1483 1 : CATCH_REQUIRE_FALSE(a[2][1] == a21);
1484 1 : CATCH_REQUIRE_FALSE(a[2][2] == a22);
1485 1 : CATCH_REQUIRE_FALSE(a[2][3] == a23);
1486 1 : CATCH_REQUIRE_FALSE(a[3][0] == a30);
1487 1 : CATCH_REQUIRE_FALSE(a[3][1] == a31);
1488 1 : CATCH_REQUIRE_FALSE(a[3][2] == a32);
1489 1 : CATCH_REQUIRE_FALSE(a[3][3] == a33);
1490 :
1491 1 : CATCH_REQUIRE(a[0][0] == a00 - scalar);
1492 1 : CATCH_REQUIRE(a[0][1] == a01 - scalar);
1493 1 : CATCH_REQUIRE(a[0][2] == a02 - scalar);
1494 1 : CATCH_REQUIRE(a[0][3] == a03 - scalar);
1495 1 : CATCH_REQUIRE(a[1][0] == a10 - scalar);
1496 1 : CATCH_REQUIRE(a[1][1] == a11 - scalar);
1497 1 : CATCH_REQUIRE(a[1][2] == a12 - scalar);
1498 1 : CATCH_REQUIRE(a[1][3] == a13 - scalar);
1499 1 : CATCH_REQUIRE(a[2][0] == a20 - scalar);
1500 1 : CATCH_REQUIRE(a[2][1] == a21 - scalar);
1501 1 : CATCH_REQUIRE(a[2][2] == a22 - scalar);
1502 1 : CATCH_REQUIRE(a[2][3] == a23 - scalar);
1503 1 : CATCH_REQUIRE(a[3][0] == a30 - scalar);
1504 1 : CATCH_REQUIRE(a[3][1] == a31 - scalar);
1505 1 : CATCH_REQUIRE(a[3][2] == a32 - scalar);
1506 1 : CATCH_REQUIRE(a[3][3] == a33 - scalar);
1507 : }
1508 : CATCH_END_SECTION()
1509 :
1510 8 : CATCH_START_SECTION("matrix: c=a-b")
1511 : {
1512 : // setup A
1513 : //
1514 2 : snap::matrix<double> a(4, 4);
1515 :
1516 1 : CATCH_REQUIRE(a.rows() == 4);
1517 1 : CATCH_REQUIRE(a.columns() == 4);
1518 :
1519 1 : double const a00(frand());
1520 1 : double const a01(frand());
1521 1 : double const a02(frand());
1522 1 : double const a03(frand());
1523 1 : double const a10(frand());
1524 1 : double const a11(frand());
1525 1 : double const a12(frand());
1526 1 : double const a13(frand());
1527 1 : double const a20(frand());
1528 1 : double const a21(frand());
1529 1 : double const a22(frand());
1530 1 : double const a23(frand());
1531 1 : double const a30(frand());
1532 1 : double const a31(frand());
1533 1 : double const a32(frand());
1534 1 : double const a33(frand());
1535 :
1536 1 : a[0][0] = a00;
1537 1 : a[0][1] = a01;
1538 1 : a[0][2] = a02;
1539 1 : a[0][3] = a03;
1540 1 : a[1][0] = a10;
1541 1 : a[1][1] = a11;
1542 1 : a[1][2] = a12;
1543 1 : a[1][3] = a13;
1544 1 : a[2][0] = a20;
1545 1 : a[2][1] = a21;
1546 1 : a[2][2] = a22;
1547 1 : a[2][3] = a23;
1548 1 : a[3][0] = a30;
1549 1 : a[3][1] = a31;
1550 1 : a[3][2] = a32;
1551 1 : a[3][3] = a33;
1552 :
1553 1 : CATCH_REQUIRE(a[0][0] == a00);
1554 1 : CATCH_REQUIRE(a[0][1] == a01);
1555 1 : CATCH_REQUIRE(a[0][2] == a02);
1556 1 : CATCH_REQUIRE(a[0][3] == a03);
1557 1 : CATCH_REQUIRE(a[1][0] == a10);
1558 1 : CATCH_REQUIRE(a[1][1] == a11);
1559 1 : CATCH_REQUIRE(a[1][2] == a12);
1560 1 : CATCH_REQUIRE(a[1][3] == a13);
1561 1 : CATCH_REQUIRE(a[2][0] == a20);
1562 1 : CATCH_REQUIRE(a[2][1] == a21);
1563 1 : CATCH_REQUIRE(a[2][2] == a22);
1564 1 : CATCH_REQUIRE(a[2][3] == a23);
1565 1 : CATCH_REQUIRE(a[3][0] == a30);
1566 1 : CATCH_REQUIRE(a[3][1] == a31);
1567 1 : CATCH_REQUIRE(a[3][2] == a32);
1568 1 : CATCH_REQUIRE(a[3][3] == a33);
1569 :
1570 : // setup B
1571 : //
1572 2 : snap::matrix<double> b(4, 4);
1573 :
1574 1 : CATCH_REQUIRE(b.rows() == 4);
1575 1 : CATCH_REQUIRE(b.columns() == 4);
1576 :
1577 1 : double const b00(frand());
1578 1 : double const b01(frand());
1579 1 : double const b02(frand());
1580 1 : double const b03(frand());
1581 1 : double const b10(frand());
1582 1 : double const b11(frand());
1583 1 : double const b12(frand());
1584 1 : double const b13(frand());
1585 1 : double const b20(frand());
1586 1 : double const b21(frand());
1587 1 : double const b22(frand());
1588 1 : double const b23(frand());
1589 1 : double const b30(frand());
1590 1 : double const b31(frand());
1591 1 : double const b32(frand());
1592 1 : double const b33(frand());
1593 :
1594 1 : b[0][0] = b00;
1595 1 : b[0][1] = b01;
1596 1 : b[0][2] = b02;
1597 1 : b[0][3] = b03;
1598 1 : b[1][0] = b10;
1599 1 : b[1][1] = b11;
1600 1 : b[1][2] = b12;
1601 1 : b[1][3] = b13;
1602 1 : b[2][0] = b20;
1603 1 : b[2][1] = b21;
1604 1 : b[2][2] = b22;
1605 1 : b[2][3] = b23;
1606 1 : b[3][0] = b30;
1607 1 : b[3][1] = b31;
1608 1 : b[3][2] = b32;
1609 1 : b[3][3] = b33;
1610 :
1611 1 : CATCH_REQUIRE(b[0][0] == b00);
1612 1 : CATCH_REQUIRE(b[0][1] == b01);
1613 1 : CATCH_REQUIRE(b[0][2] == b02);
1614 1 : CATCH_REQUIRE(b[0][3] == b03);
1615 1 : CATCH_REQUIRE(b[1][0] == b10);
1616 1 : CATCH_REQUIRE(b[1][1] == b11);
1617 1 : CATCH_REQUIRE(b[1][2] == b12);
1618 1 : CATCH_REQUIRE(b[1][3] == b13);
1619 1 : CATCH_REQUIRE(b[2][0] == b20);
1620 1 : CATCH_REQUIRE(b[2][1] == b21);
1621 1 : CATCH_REQUIRE(b[2][2] == b22);
1622 1 : CATCH_REQUIRE(b[2][3] == b23);
1623 1 : CATCH_REQUIRE(b[3][0] == b30);
1624 1 : CATCH_REQUIRE(b[3][1] == b31);
1625 1 : CATCH_REQUIRE(b[3][2] == b32);
1626 1 : CATCH_REQUIRE(b[3][3] == b33);
1627 :
1628 : // setup C
1629 : //
1630 2 : snap::matrix<double> c(4, 4);
1631 :
1632 1 : CATCH_REQUIRE(c.rows() == 4);
1633 1 : CATCH_REQUIRE(c.columns() == 4);
1634 :
1635 1 : double const c00(frand());
1636 1 : double const c01(frand());
1637 1 : double const c02(frand());
1638 1 : double const c03(frand());
1639 1 : double const c10(frand());
1640 1 : double const c11(frand());
1641 1 : double const c12(frand());
1642 1 : double const c13(frand());
1643 1 : double const c20(frand());
1644 1 : double const c21(frand());
1645 1 : double const c22(frand());
1646 1 : double const c23(frand());
1647 1 : double const c30(frand());
1648 1 : double const c31(frand());
1649 1 : double const c32(frand());
1650 1 : double const c33(frand());
1651 :
1652 1 : c[0][0] = c00;
1653 1 : c[0][1] = c01;
1654 1 : c[0][2] = c02;
1655 1 : c[0][3] = c03;
1656 1 : c[1][0] = c10;
1657 1 : c[1][1] = c11;
1658 1 : c[1][2] = c12;
1659 1 : c[1][3] = c13;
1660 1 : c[2][0] = c20;
1661 1 : c[2][1] = c21;
1662 1 : c[2][2] = c22;
1663 1 : c[2][3] = c23;
1664 1 : c[3][0] = c30;
1665 1 : c[3][1] = c31;
1666 1 : c[3][2] = c32;
1667 1 : c[3][3] = c33;
1668 :
1669 1 : CATCH_REQUIRE(c[0][0] == c00);
1670 1 : CATCH_REQUIRE(c[0][1] == c01);
1671 1 : CATCH_REQUIRE(c[0][2] == c02);
1672 1 : CATCH_REQUIRE(c[0][3] == c03);
1673 1 : CATCH_REQUIRE(c[1][0] == c10);
1674 1 : CATCH_REQUIRE(c[1][1] == c11);
1675 1 : CATCH_REQUIRE(c[1][2] == c12);
1676 1 : CATCH_REQUIRE(c[1][3] == c13);
1677 1 : CATCH_REQUIRE(c[2][0] == c20);
1678 1 : CATCH_REQUIRE(c[2][1] == c21);
1679 1 : CATCH_REQUIRE(c[2][2] == c22);
1680 1 : CATCH_REQUIRE(c[2][3] == c23);
1681 1 : CATCH_REQUIRE(c[3][0] == c30);
1682 1 : CATCH_REQUIRE(c[3][1] == c31);
1683 1 : CATCH_REQUIRE(c[3][2] == c32);
1684 1 : CATCH_REQUIRE(c[3][3] == c33);
1685 :
1686 : // run operation C = A - B
1687 : //
1688 1 : c = a - b;
1689 :
1690 1 : CATCH_REQUIRE(a[0][0] == a00);
1691 1 : CATCH_REQUIRE(a[0][1] == a01);
1692 1 : CATCH_REQUIRE(a[0][2] == a02);
1693 1 : CATCH_REQUIRE(a[0][3] == a03);
1694 1 : CATCH_REQUIRE(a[1][0] == a10);
1695 1 : CATCH_REQUIRE(a[1][1] == a11);
1696 1 : CATCH_REQUIRE(a[1][2] == a12);
1697 1 : CATCH_REQUIRE(a[1][3] == a13);
1698 1 : CATCH_REQUIRE(a[2][0] == a20);
1699 1 : CATCH_REQUIRE(a[2][1] == a21);
1700 1 : CATCH_REQUIRE(a[2][2] == a22);
1701 1 : CATCH_REQUIRE(a[2][3] == a23);
1702 1 : CATCH_REQUIRE(a[3][0] == a30);
1703 1 : CATCH_REQUIRE(a[3][1] == a31);
1704 1 : CATCH_REQUIRE(a[3][2] == a32);
1705 1 : CATCH_REQUIRE(a[3][3] == a33);
1706 :
1707 1 : CATCH_REQUIRE(b[0][0] == b00);
1708 1 : CATCH_REQUIRE(b[0][1] == b01);
1709 1 : CATCH_REQUIRE(b[0][2] == b02);
1710 1 : CATCH_REQUIRE(b[0][3] == b03);
1711 1 : CATCH_REQUIRE(b[1][0] == b10);
1712 1 : CATCH_REQUIRE(b[1][1] == b11);
1713 1 : CATCH_REQUIRE(b[1][2] == b12);
1714 1 : CATCH_REQUIRE(b[1][3] == b13);
1715 1 : CATCH_REQUIRE(b[2][0] == b20);
1716 1 : CATCH_REQUIRE(b[2][1] == b21);
1717 1 : CATCH_REQUIRE(b[2][2] == b22);
1718 1 : CATCH_REQUIRE(b[2][3] == b23);
1719 1 : CATCH_REQUIRE(b[3][0] == b30);
1720 1 : CATCH_REQUIRE(b[3][1] == b31);
1721 1 : CATCH_REQUIRE(b[3][2] == b32);
1722 1 : CATCH_REQUIRE(b[3][3] == b33);
1723 :
1724 : // this could fail
1725 : //CATCH_REQUIRE_FALSE(c[0][0] == c00);
1726 : //CATCH_REQUIRE_FALSE(c[0][1] == c01);
1727 : //CATCH_REQUIRE_FALSE(c[0][2] == c02);
1728 : //CATCH_REQUIRE_FALSE(c[0][3] == c03);
1729 : //CATCH_REQUIRE_FALSE(c[1][0] == c10);
1730 : //CATCH_REQUIRE_FALSE(c[1][1] == c11);
1731 : //CATCH_REQUIRE_FALSE(c[1][2] == c12);
1732 : //CATCH_REQUIRE_FALSE(c[1][3] == c13);
1733 : //CATCH_REQUIRE_FALSE(c[2][0] == c20);
1734 : //CATCH_REQUIRE_FALSE(c[2][1] == c21);
1735 : //CATCH_REQUIRE_FALSE(c[2][2] == c22);
1736 : //CATCH_REQUIRE_FALSE(c[2][3] == c23);
1737 : //CATCH_REQUIRE_FALSE(c[3][0] == c30);
1738 : //CATCH_REQUIRE_FALSE(c[3][1] == c31);
1739 : //CATCH_REQUIRE_FALSE(c[3][2] == c32);
1740 : //CATCH_REQUIRE_FALSE(c[3][3] == c33);
1741 :
1742 1 : CATCH_REQUIRE(c[0][0] == a00 - b00);
1743 1 : CATCH_REQUIRE(c[0][1] == a01 - b01);
1744 1 : CATCH_REQUIRE(c[0][2] == a02 - b02);
1745 1 : CATCH_REQUIRE(c[0][3] == a03 - b03);
1746 1 : CATCH_REQUIRE(c[1][0] == a10 - b10);
1747 1 : CATCH_REQUIRE(c[1][1] == a11 - b11);
1748 1 : CATCH_REQUIRE(c[1][2] == a12 - b12);
1749 1 : CATCH_REQUIRE(c[1][3] == a13 - b13);
1750 1 : CATCH_REQUIRE(c[2][0] == a20 - b20);
1751 1 : CATCH_REQUIRE(c[2][1] == a21 - b21);
1752 1 : CATCH_REQUIRE(c[2][2] == a22 - b22);
1753 1 : CATCH_REQUIRE(c[2][3] == a23 - b23);
1754 1 : CATCH_REQUIRE(c[3][0] == a30 - b30);
1755 1 : CATCH_REQUIRE(c[3][1] == a31 - b31);
1756 1 : CATCH_REQUIRE(c[3][2] == a32 - b32);
1757 1 : CATCH_REQUIRE(c[3][3] == a33 - b33);
1758 : }
1759 : CATCH_END_SECTION()
1760 :
1761 8 : CATCH_START_SECTION("matrix: a-=b")
1762 : {
1763 : // setup A
1764 : //
1765 2 : snap::matrix<double> a(4, 4);
1766 :
1767 1 : CATCH_REQUIRE(a.rows() == 4);
1768 1 : CATCH_REQUIRE(a.columns() == 4);
1769 :
1770 1 : double const a00(frand());
1771 1 : double const a01(frand());
1772 1 : double const a02(frand());
1773 1 : double const a03(frand());
1774 1 : double const a10(frand());
1775 1 : double const a11(frand());
1776 1 : double const a12(frand());
1777 1 : double const a13(frand());
1778 1 : double const a20(frand());
1779 1 : double const a21(frand());
1780 1 : double const a22(frand());
1781 1 : double const a23(frand());
1782 1 : double const a30(frand());
1783 1 : double const a31(frand());
1784 1 : double const a32(frand());
1785 1 : double const a33(frand());
1786 :
1787 1 : a[0][0] = a00;
1788 1 : a[0][1] = a01;
1789 1 : a[0][2] = a02;
1790 1 : a[0][3] = a03;
1791 1 : a[1][0] = a10;
1792 1 : a[1][1] = a11;
1793 1 : a[1][2] = a12;
1794 1 : a[1][3] = a13;
1795 1 : a[2][0] = a20;
1796 1 : a[2][1] = a21;
1797 1 : a[2][2] = a22;
1798 1 : a[2][3] = a23;
1799 1 : a[3][0] = a30;
1800 1 : a[3][1] = a31;
1801 1 : a[3][2] = a32;
1802 1 : a[3][3] = a33;
1803 :
1804 1 : CATCH_REQUIRE(a[0][0] == a00);
1805 1 : CATCH_REQUIRE(a[0][1] == a01);
1806 1 : CATCH_REQUIRE(a[0][2] == a02);
1807 1 : CATCH_REQUIRE(a[0][3] == a03);
1808 1 : CATCH_REQUIRE(a[1][0] == a10);
1809 1 : CATCH_REQUIRE(a[1][1] == a11);
1810 1 : CATCH_REQUIRE(a[1][2] == a12);
1811 1 : CATCH_REQUIRE(a[1][3] == a13);
1812 1 : CATCH_REQUIRE(a[2][0] == a20);
1813 1 : CATCH_REQUIRE(a[2][1] == a21);
1814 1 : CATCH_REQUIRE(a[2][2] == a22);
1815 1 : CATCH_REQUIRE(a[2][3] == a23);
1816 1 : CATCH_REQUIRE(a[3][0] == a30);
1817 1 : CATCH_REQUIRE(a[3][1] == a31);
1818 1 : CATCH_REQUIRE(a[3][2] == a32);
1819 1 : CATCH_REQUIRE(a[3][3] == a33);
1820 :
1821 : // setup B
1822 : //
1823 2 : snap::matrix<double> b(4, 4);
1824 :
1825 1 : CATCH_REQUIRE(b.rows() == 4);
1826 1 : CATCH_REQUIRE(b.columns() == 4);
1827 :
1828 1 : double const b00(frand());
1829 1 : double const b01(frand());
1830 1 : double const b02(frand());
1831 1 : double const b03(frand());
1832 1 : double const b10(frand());
1833 1 : double const b11(frand());
1834 1 : double const b12(frand());
1835 1 : double const b13(frand());
1836 1 : double const b20(frand());
1837 1 : double const b21(frand());
1838 1 : double const b22(frand());
1839 1 : double const b23(frand());
1840 1 : double const b30(frand());
1841 1 : double const b31(frand());
1842 1 : double const b32(frand());
1843 1 : double const b33(frand());
1844 :
1845 1 : b[0][0] = b00;
1846 1 : b[0][1] = b01;
1847 1 : b[0][2] = b02;
1848 1 : b[0][3] = b03;
1849 1 : b[1][0] = b10;
1850 1 : b[1][1] = b11;
1851 1 : b[1][2] = b12;
1852 1 : b[1][3] = b13;
1853 1 : b[2][0] = b20;
1854 1 : b[2][1] = b21;
1855 1 : b[2][2] = b22;
1856 1 : b[2][3] = b23;
1857 1 : b[3][0] = b30;
1858 1 : b[3][1] = b31;
1859 1 : b[3][2] = b32;
1860 1 : b[3][3] = b33;
1861 :
1862 1 : CATCH_REQUIRE(b[0][0] == b00);
1863 1 : CATCH_REQUIRE(b[0][1] == b01);
1864 1 : CATCH_REQUIRE(b[0][2] == b02);
1865 1 : CATCH_REQUIRE(b[0][3] == b03);
1866 1 : CATCH_REQUIRE(b[1][0] == b10);
1867 1 : CATCH_REQUIRE(b[1][1] == b11);
1868 1 : CATCH_REQUIRE(b[1][2] == b12);
1869 1 : CATCH_REQUIRE(b[1][3] == b13);
1870 1 : CATCH_REQUIRE(b[2][0] == b20);
1871 1 : CATCH_REQUIRE(b[2][1] == b21);
1872 1 : CATCH_REQUIRE(b[2][2] == b22);
1873 1 : CATCH_REQUIRE(b[2][3] == b23);
1874 1 : CATCH_REQUIRE(b[3][0] == b30);
1875 1 : CATCH_REQUIRE(b[3][1] == b31);
1876 1 : CATCH_REQUIRE(b[3][2] == b32);
1877 1 : CATCH_REQUIRE(b[3][3] == b33);
1878 :
1879 : // run operation A -= B
1880 : //
1881 1 : a -= b;
1882 :
1883 : // this could fail if one of bXX is 0.0
1884 : //
1885 : //CATCH_REQUIRE(a[0][0] == a00);
1886 : //CATCH_REQUIRE(a[0][1] == a01);
1887 : //CATCH_REQUIRE(a[0][2] == a02);
1888 : //CATCH_REQUIRE(a[0][3] == a03);
1889 : //CATCH_REQUIRE(a[1][0] == a10);
1890 : //CATCH_REQUIRE(a[1][1] == a11);
1891 : //CATCH_REQUIRE(a[1][2] == a12);
1892 : //CATCH_REQUIRE(a[1][3] == a13);
1893 : //CATCH_REQUIRE(a[2][0] == a20);
1894 : //CATCH_REQUIRE(a[2][1] == a21);
1895 : //CATCH_REQUIRE(a[2][2] == a22);
1896 : //CATCH_REQUIRE(a[2][3] == a23);
1897 : //CATCH_REQUIRE(a[3][0] == a30);
1898 : //CATCH_REQUIRE(a[3][1] == a31);
1899 : //CATCH_REQUIRE(a[3][2] == a32);
1900 : //CATCH_REQUIRE(a[3][3] == a33);
1901 :
1902 1 : CATCH_REQUIRE(b[0][0] == b00);
1903 1 : CATCH_REQUIRE(b[0][1] == b01);
1904 1 : CATCH_REQUIRE(b[0][2] == b02);
1905 1 : CATCH_REQUIRE(b[0][3] == b03);
1906 1 : CATCH_REQUIRE(b[1][0] == b10);
1907 1 : CATCH_REQUIRE(b[1][1] == b11);
1908 1 : CATCH_REQUIRE(b[1][2] == b12);
1909 1 : CATCH_REQUIRE(b[1][3] == b13);
1910 1 : CATCH_REQUIRE(b[2][0] == b20);
1911 1 : CATCH_REQUIRE(b[2][1] == b21);
1912 1 : CATCH_REQUIRE(b[2][2] == b22);
1913 1 : CATCH_REQUIRE(b[2][3] == b23);
1914 1 : CATCH_REQUIRE(b[3][0] == b30);
1915 1 : CATCH_REQUIRE(b[3][1] == b31);
1916 1 : CATCH_REQUIRE(b[3][2] == b32);
1917 1 : CATCH_REQUIRE(b[3][3] == b33);
1918 :
1919 1 : CATCH_REQUIRE(a[0][0] == a00 - b00);
1920 1 : CATCH_REQUIRE(a[0][1] == a01 - b01);
1921 1 : CATCH_REQUIRE(a[0][2] == a02 - b02);
1922 1 : CATCH_REQUIRE(a[0][3] == a03 - b03);
1923 1 : CATCH_REQUIRE(a[1][0] == a10 - b10);
1924 1 : CATCH_REQUIRE(a[1][1] == a11 - b11);
1925 1 : CATCH_REQUIRE(a[1][2] == a12 - b12);
1926 1 : CATCH_REQUIRE(a[1][3] == a13 - b13);
1927 1 : CATCH_REQUIRE(a[2][0] == a20 - b20);
1928 1 : CATCH_REQUIRE(a[2][1] == a21 - b21);
1929 1 : CATCH_REQUIRE(a[2][2] == a22 - b22);
1930 1 : CATCH_REQUIRE(a[2][3] == a23 - b23);
1931 1 : CATCH_REQUIRE(a[3][0] == a30 - b30);
1932 1 : CATCH_REQUIRE(a[3][1] == a31 - b31);
1933 1 : CATCH_REQUIRE(a[3][2] == a32 - b32);
1934 1 : CATCH_REQUIRE(a[3][3] == a33 - b33);
1935 : }
1936 : CATCH_END_SECTION()
1937 : }
1938 8 : }
1939 :
1940 :
1941 10 : CATCH_TEST_CASE("matrix_util", "[matrix]")
1942 : {
1943 : // various ways to change the data order, minor, enlarge
1944 : //
1945 16 : CATCH_GIVEN("move data")
1946 : {
1947 10 : CATCH_START_SECTION("matrix: minor")
1948 : {
1949 : // setup A
1950 : //
1951 2 : snap::matrix<double> a(4, 4);
1952 :
1953 1 : CATCH_REQUIRE(a.rows() == 4);
1954 1 : CATCH_REQUIRE(a.columns() == 4);
1955 :
1956 1 : double const a00(frand());
1957 1 : double const a01(frand());
1958 1 : double const a02(frand());
1959 1 : double const a03(frand());
1960 1 : double const a10(frand());
1961 1 : double const a11(frand());
1962 1 : double const a12(frand());
1963 1 : double const a13(frand());
1964 1 : double const a20(frand());
1965 1 : double const a21(frand());
1966 1 : double const a22(frand());
1967 1 : double const a23(frand());
1968 1 : double const a30(frand());
1969 1 : double const a31(frand());
1970 1 : double const a32(frand());
1971 1 : double const a33(frand());
1972 :
1973 1 : a[0][0] = a00;
1974 1 : a[0][1] = a01;
1975 1 : a[0][2] = a02;
1976 1 : a[0][3] = a03;
1977 1 : a[1][0] = a10;
1978 1 : a[1][1] = a11;
1979 1 : a[1][2] = a12;
1980 1 : a[1][3] = a13;
1981 1 : a[2][0] = a20;
1982 1 : a[2][1] = a21;
1983 1 : a[2][2] = a22;
1984 1 : a[2][3] = a23;
1985 1 : a[3][0] = a30;
1986 1 : a[3][1] = a31;
1987 1 : a[3][2] = a32;
1988 1 : a[3][3] = a33;
1989 :
1990 1 : CATCH_REQUIRE(a[0][0] == a00);
1991 1 : CATCH_REQUIRE(a[0][1] == a01);
1992 1 : CATCH_REQUIRE(a[0][2] == a02);
1993 1 : CATCH_REQUIRE(a[0][3] == a03);
1994 1 : CATCH_REQUIRE(a[1][0] == a10);
1995 1 : CATCH_REQUIRE(a[1][1] == a11);
1996 1 : CATCH_REQUIRE(a[1][2] == a12);
1997 1 : CATCH_REQUIRE(a[1][3] == a13);
1998 1 : CATCH_REQUIRE(a[2][0] == a20);
1999 1 : CATCH_REQUIRE(a[2][1] == a21);
2000 1 : CATCH_REQUIRE(a[2][2] == a22);
2001 1 : CATCH_REQUIRE(a[2][3] == a23);
2002 1 : CATCH_REQUIRE(a[3][0] == a30);
2003 1 : CATCH_REQUIRE(a[3][1] == a31);
2004 1 : CATCH_REQUIRE(a[3][2] == a32);
2005 1 : CATCH_REQUIRE(a[3][3] == a33);
2006 :
2007 : {
2008 2 : snap::matrix<double> p = a.minor_matrix(0, 0);
2009 :
2010 1 : CATCH_REQUIRE(p.rows() == 3);
2011 1 : CATCH_REQUIRE(p.columns() == 3);
2012 :
2013 1 : CATCH_REQUIRE(p[0][0] == a11);
2014 1 : CATCH_REQUIRE(p[0][1] == a12);
2015 1 : CATCH_REQUIRE(p[0][2] == a13);
2016 1 : CATCH_REQUIRE(p[1][0] == a21);
2017 1 : CATCH_REQUIRE(p[1][1] == a22);
2018 1 : CATCH_REQUIRE(p[1][2] == a23);
2019 1 : CATCH_REQUIRE(p[2][0] == a31);
2020 1 : CATCH_REQUIRE(p[2][1] == a32);
2021 1 : CATCH_REQUIRE(p[2][2] == a33);
2022 : }
2023 :
2024 : {
2025 2 : snap::matrix<double> p = a.minor_matrix(0, 1);
2026 :
2027 1 : CATCH_REQUIRE(p.rows() == 3);
2028 1 : CATCH_REQUIRE(p.columns() == 3);
2029 :
2030 1 : CATCH_REQUIRE(p[0][0] == a10);
2031 1 : CATCH_REQUIRE(p[0][1] == a12);
2032 1 : CATCH_REQUIRE(p[0][2] == a13);
2033 1 : CATCH_REQUIRE(p[1][0] == a20);
2034 1 : CATCH_REQUIRE(p[1][1] == a22);
2035 1 : CATCH_REQUIRE(p[1][2] == a23);
2036 1 : CATCH_REQUIRE(p[2][0] == a30);
2037 1 : CATCH_REQUIRE(p[2][1] == a32);
2038 1 : CATCH_REQUIRE(p[2][2] == a33);
2039 : }
2040 :
2041 : {
2042 2 : snap::matrix<double> p = a.minor_matrix(0, 2);
2043 :
2044 1 : CATCH_REQUIRE(p.rows() == 3);
2045 1 : CATCH_REQUIRE(p.columns() == 3);
2046 :
2047 1 : CATCH_REQUIRE(p[0][0] == a10);
2048 1 : CATCH_REQUIRE(p[0][1] == a11);
2049 1 : CATCH_REQUIRE(p[0][2] == a13);
2050 1 : CATCH_REQUIRE(p[1][0] == a20);
2051 1 : CATCH_REQUIRE(p[1][1] == a21);
2052 1 : CATCH_REQUIRE(p[1][2] == a23);
2053 1 : CATCH_REQUIRE(p[2][0] == a30);
2054 1 : CATCH_REQUIRE(p[2][1] == a31);
2055 1 : CATCH_REQUIRE(p[2][2] == a33);
2056 : }
2057 :
2058 : {
2059 2 : snap::matrix<double> p = a.minor_matrix(0, 3);
2060 :
2061 1 : CATCH_REQUIRE(p.rows() == 3);
2062 1 : CATCH_REQUIRE(p.columns() == 3);
2063 :
2064 1 : CATCH_REQUIRE(p[0][0] == a10);
2065 1 : CATCH_REQUIRE(p[0][1] == a11);
2066 1 : CATCH_REQUIRE(p[0][2] == a12);
2067 1 : CATCH_REQUIRE(p[1][0] == a20);
2068 1 : CATCH_REQUIRE(p[1][1] == a21);
2069 1 : CATCH_REQUIRE(p[1][2] == a22);
2070 1 : CATCH_REQUIRE(p[2][0] == a30);
2071 1 : CATCH_REQUIRE(p[2][1] == a31);
2072 1 : CATCH_REQUIRE(p[2][2] == a32);
2073 : }
2074 :
2075 : {
2076 2 : snap::matrix<double> p = a.minor_matrix(2, 1);
2077 :
2078 1 : CATCH_REQUIRE(p.rows() == 3);
2079 1 : CATCH_REQUIRE(p.columns() == 3);
2080 :
2081 1 : CATCH_REQUIRE(p[0][0] == a00);
2082 1 : CATCH_REQUIRE(p[0][1] == a02);
2083 1 : CATCH_REQUIRE(p[0][2] == a03);
2084 1 : CATCH_REQUIRE(p[1][0] == a10);
2085 1 : CATCH_REQUIRE(p[1][1] == a12);
2086 1 : CATCH_REQUIRE(p[1][2] == a13);
2087 1 : CATCH_REQUIRE(p[2][0] == a30);
2088 1 : CATCH_REQUIRE(p[2][1] == a32);
2089 1 : CATCH_REQUIRE(p[2][2] == a33);
2090 : }
2091 : }
2092 : CATCH_END_SECTION()
2093 :
2094 10 : CATCH_START_SECTION("matrix: transpose 4x4")
2095 : {
2096 : // setup A
2097 : //
2098 2 : snap::matrix<double> a(4, 4);
2099 :
2100 1 : CATCH_REQUIRE(a.rows() == 4);
2101 1 : CATCH_REQUIRE(a.columns() == 4);
2102 :
2103 1 : double const a00(frand());
2104 1 : double const a01(frand());
2105 1 : double const a02(frand());
2106 1 : double const a03(frand());
2107 1 : double const a10(frand());
2108 1 : double const a11(frand());
2109 1 : double const a12(frand());
2110 1 : double const a13(frand());
2111 1 : double const a20(frand());
2112 1 : double const a21(frand());
2113 1 : double const a22(frand());
2114 1 : double const a23(frand());
2115 1 : double const a30(frand());
2116 1 : double const a31(frand());
2117 1 : double const a32(frand());
2118 1 : double const a33(frand());
2119 :
2120 1 : a[0][0] = a00;
2121 1 : a[0][1] = a01;
2122 1 : a[0][2] = a02;
2123 1 : a[0][3] = a03;
2124 1 : a[1][0] = a10;
2125 1 : a[1][1] = a11;
2126 1 : a[1][2] = a12;
2127 1 : a[1][3] = a13;
2128 1 : a[2][0] = a20;
2129 1 : a[2][1] = a21;
2130 1 : a[2][2] = a22;
2131 1 : a[2][3] = a23;
2132 1 : a[3][0] = a30;
2133 1 : a[3][1] = a31;
2134 1 : a[3][2] = a32;
2135 1 : a[3][3] = a33;
2136 :
2137 1 : CATCH_REQUIRE(a[0][0] == a00);
2138 1 : CATCH_REQUIRE(a[0][1] == a01);
2139 1 : CATCH_REQUIRE(a[0][2] == a02);
2140 1 : CATCH_REQUIRE(a[0][3] == a03);
2141 1 : CATCH_REQUIRE(a[1][0] == a10);
2142 1 : CATCH_REQUIRE(a[1][1] == a11);
2143 1 : CATCH_REQUIRE(a[1][2] == a12);
2144 1 : CATCH_REQUIRE(a[1][3] == a13);
2145 1 : CATCH_REQUIRE(a[2][0] == a20);
2146 1 : CATCH_REQUIRE(a[2][1] == a21);
2147 1 : CATCH_REQUIRE(a[2][2] == a22);
2148 1 : CATCH_REQUIRE(a[2][3] == a23);
2149 1 : CATCH_REQUIRE(a[3][0] == a30);
2150 1 : CATCH_REQUIRE(a[3][1] == a31);
2151 1 : CATCH_REQUIRE(a[3][2] == a32);
2152 1 : CATCH_REQUIRE(a[3][3] == a33);
2153 :
2154 2 : snap::matrix<double> t = a.transpose();
2155 :
2156 1 : CATCH_REQUIRE(t.rows() == 4);
2157 1 : CATCH_REQUIRE(t.columns() == 4);
2158 :
2159 1 : CATCH_REQUIRE(t[0][0] == a00);
2160 1 : CATCH_REQUIRE(t[0][1] == a10);
2161 1 : CATCH_REQUIRE(t[0][2] == a20);
2162 1 : CATCH_REQUIRE(t[0][3] == a30);
2163 1 : CATCH_REQUIRE(t[1][0] == a01);
2164 1 : CATCH_REQUIRE(t[1][1] == a11);
2165 1 : CATCH_REQUIRE(t[1][2] == a21);
2166 1 : CATCH_REQUIRE(t[1][3] == a31);
2167 1 : CATCH_REQUIRE(t[2][0] == a02);
2168 1 : CATCH_REQUIRE(t[2][1] == a12);
2169 1 : CATCH_REQUIRE(t[2][2] == a22);
2170 1 : CATCH_REQUIRE(t[2][3] == a32);
2171 1 : CATCH_REQUIRE(t[3][0] == a03);
2172 1 : CATCH_REQUIRE(t[3][1] == a13);
2173 1 : CATCH_REQUIRE(t[3][2] == a23);
2174 1 : CATCH_REQUIRE(t[3][3] == a33);
2175 : }
2176 : CATCH_END_SECTION()
2177 :
2178 10 : CATCH_START_SECTION("matrix: transpose 6x2")
2179 : {
2180 : // setup A
2181 : //
2182 2 : snap::matrix<double> a(6, 2);
2183 :
2184 1 : CATCH_REQUIRE(a.rows() == 6);
2185 1 : CATCH_REQUIRE(a.columns() == 2);
2186 :
2187 1 : double const a00(frand());
2188 1 : double const a01(frand());
2189 1 : double const a10(frand());
2190 1 : double const a11(frand());
2191 1 : double const a20(frand());
2192 1 : double const a21(frand());
2193 1 : double const a30(frand());
2194 1 : double const a31(frand());
2195 1 : double const a40(frand());
2196 1 : double const a41(frand());
2197 1 : double const a50(frand());
2198 1 : double const a51(frand());
2199 :
2200 1 : a[0][0] = a00;
2201 1 : a[0][1] = a01;
2202 1 : a[1][0] = a10;
2203 1 : a[1][1] = a11;
2204 1 : a[2][0] = a20;
2205 1 : a[2][1] = a21;
2206 1 : a[3][0] = a30;
2207 1 : a[3][1] = a31;
2208 1 : a[4][0] = a40;
2209 1 : a[4][1] = a41;
2210 1 : a[5][0] = a50;
2211 1 : a[5][1] = a51;
2212 :
2213 1 : CATCH_REQUIRE(a[0][0] == a00);
2214 1 : CATCH_REQUIRE(a[0][1] == a01);
2215 1 : CATCH_REQUIRE(a[1][0] == a10);
2216 1 : CATCH_REQUIRE(a[1][1] == a11);
2217 1 : CATCH_REQUIRE(a[2][0] == a20);
2218 1 : CATCH_REQUIRE(a[2][1] == a21);
2219 1 : CATCH_REQUIRE(a[3][0] == a30);
2220 1 : CATCH_REQUIRE(a[3][1] == a31);
2221 1 : CATCH_REQUIRE(a[4][0] == a40);
2222 1 : CATCH_REQUIRE(a[4][1] == a41);
2223 1 : CATCH_REQUIRE(a[5][0] == a50);
2224 1 : CATCH_REQUIRE(a[5][1] == a51);
2225 :
2226 2 : snap::matrix<double> t = a.transpose();
2227 :
2228 1 : CATCH_REQUIRE(t.rows() == 2);
2229 1 : CATCH_REQUIRE(t.columns() == 6);
2230 :
2231 : // original
2232 : // a00 a01
2233 : // a10 a11
2234 : // a20 a21
2235 : // a30 a31
2236 : // a40 a41
2237 : // a50 a51
2238 : //
2239 : // transposed
2240 : // a00 a10 a20 a30 a40 a50
2241 : // a01 a11 a21 a31 a41 a51
2242 : //
2243 :
2244 1 : CATCH_REQUIRE(t[0][0] == a00);
2245 1 : CATCH_REQUIRE(t[0][1] == a10);
2246 1 : CATCH_REQUIRE(t[0][2] == a20);
2247 1 : CATCH_REQUIRE(t[0][3] == a30);
2248 1 : CATCH_REQUIRE(t[0][4] == a40);
2249 1 : CATCH_REQUIRE(t[0][5] == a50);
2250 1 : CATCH_REQUIRE(t[1][0] == a01);
2251 1 : CATCH_REQUIRE(t[1][1] == a11);
2252 1 : CATCH_REQUIRE(t[1][2] == a21);
2253 1 : CATCH_REQUIRE(t[1][3] == a31);
2254 1 : CATCH_REQUIRE(t[1][4] == a41);
2255 1 : CATCH_REQUIRE(t[1][5] == a51);
2256 : }
2257 : CATCH_END_SECTION()
2258 :
2259 10 : CATCH_START_SECTION("matrix: adjugate 2x2")
2260 : {
2261 : // setup A
2262 : //
2263 2 : snap::matrix<double> a(2, 2);
2264 :
2265 1 : CATCH_REQUIRE(a.rows() == 2);
2266 1 : CATCH_REQUIRE(a.columns() == 2);
2267 :
2268 1 : double const a00(frand());
2269 1 : double const a01(frand());
2270 1 : double const a10(frand());
2271 1 : double const a11(frand());
2272 :
2273 1 : a[0][0] = a00;
2274 1 : a[0][1] = a01;
2275 1 : a[1][0] = a10;
2276 1 : a[1][1] = a11;
2277 :
2278 1 : CATCH_REQUIRE(a[0][0] == a00);
2279 1 : CATCH_REQUIRE(a[0][1] == a01);
2280 1 : CATCH_REQUIRE(a[1][0] == a10);
2281 1 : CATCH_REQUIRE(a[1][1] == a11);
2282 :
2283 2 : snap::matrix<double> m = a.adjugate();
2284 :
2285 1 : CATCH_REQUIRE(m.rows() == 2);
2286 1 : CATCH_REQUIRE(m.columns() == 2);
2287 :
2288 1 : CATCH_REQUIRE(m[0][0] == a11);
2289 1 : CATCH_REQUIRE(m[0][1] == -a01);
2290 1 : CATCH_REQUIRE(m[1][0] == -a10);
2291 1 : CATCH_REQUIRE(m[1][1] == a00);
2292 : }
2293 : CATCH_END_SECTION()
2294 :
2295 10 : CATCH_START_SECTION("matrix: adjugate 3x3")
2296 : {
2297 : // setup A
2298 : //
2299 2 : snap::matrix<double> a(3, 3);
2300 :
2301 1 : CATCH_REQUIRE(a.rows() == 3);
2302 1 : CATCH_REQUIRE(a.columns() == 3);
2303 :
2304 1 : double const a00(frand());
2305 1 : double const a01(frand());
2306 1 : double const a02(frand());
2307 1 : double const a10(frand());
2308 1 : double const a11(frand());
2309 1 : double const a12(frand());
2310 1 : double const a20(frand());
2311 1 : double const a21(frand());
2312 1 : double const a22(frand());
2313 :
2314 1 : a[0][0] = a00;
2315 1 : a[0][1] = a01;
2316 1 : a[0][2] = a02;
2317 1 : a[1][0] = a10;
2318 1 : a[1][1] = a11;
2319 1 : a[1][2] = a12;
2320 1 : a[2][0] = a20;
2321 1 : a[2][1] = a21;
2322 1 : a[2][2] = a22;
2323 :
2324 1 : CATCH_REQUIRE(a[0][0] == a00);
2325 1 : CATCH_REQUIRE(a[0][1] == a01);
2326 1 : CATCH_REQUIRE(a[0][2] == a02);
2327 1 : CATCH_REQUIRE(a[1][0] == a10);
2328 1 : CATCH_REQUIRE(a[1][1] == a11);
2329 1 : CATCH_REQUIRE(a[1][2] == a12);
2330 1 : CATCH_REQUIRE(a[2][0] == a20);
2331 1 : CATCH_REQUIRE(a[2][1] == a21);
2332 1 : CATCH_REQUIRE(a[2][2] == a22);
2333 :
2334 2 : snap::matrix<double> m = a.adjugate();
2335 :
2336 1 : CATCH_REQUIRE(m.rows() == 3);
2337 1 : CATCH_REQUIRE(m.columns() == 3);
2338 :
2339 : {
2340 2 : snap::matrix<double> p(a.minor_matrix(0, 0));
2341 1 : double const e(m[0][0] - p.determinant());
2342 1 : CATCH_REQUIRE(fabs(e) < 0.0001);
2343 : }
2344 :
2345 : {
2346 2 : snap::matrix<double> p(a.minor_matrix(0, 1));
2347 1 : double const e(m[1][0] + p.determinant());
2348 1 : CATCH_REQUIRE(fabs(e) < 0.0001);
2349 : }
2350 :
2351 : {
2352 2 : snap::matrix<double> p(a.minor_matrix(0, 2));
2353 1 : double const e(m[2][0] - p.determinant());
2354 1 : CATCH_REQUIRE(fabs(e) < 0.0001);
2355 : }
2356 :
2357 : {
2358 2 : snap::matrix<double> p(a.minor_matrix(1, 0));
2359 1 : double const e(m[0][1] + p.determinant());
2360 1 : CATCH_REQUIRE(fabs(e) < 0.0001);
2361 : }
2362 :
2363 : {
2364 2 : snap::matrix<double> p(a.minor_matrix(1, 1));
2365 1 : double const e(m[1][1] - p.determinant());
2366 1 : CATCH_REQUIRE(fabs(e) < 0.0001);
2367 : }
2368 :
2369 : {
2370 2 : snap::matrix<double> p(a.minor_matrix(1, 2));
2371 1 : double const e(m[2][1] + p.determinant());
2372 1 : CATCH_REQUIRE(fabs(e) < 0.0001);
2373 : }
2374 :
2375 : {
2376 2 : snap::matrix<double> p(a.minor_matrix(2, 0));
2377 1 : double const e(m[0][2] - p.determinant());
2378 1 : CATCH_REQUIRE(fabs(e) < 0.0001);
2379 : }
2380 :
2381 : {
2382 2 : snap::matrix<double> p(a.minor_matrix(2, 1));
2383 1 : double const e(m[1][2] + p.determinant());
2384 1 : CATCH_REQUIRE(fabs(e) < 0.0001);
2385 : }
2386 :
2387 : {
2388 2 : snap::matrix<double> p(a.minor_matrix(2, 2));
2389 1 : double const e(m[2][2] - p.determinant());
2390 1 : CATCH_REQUIRE(fabs(e) < 0.0001);
2391 : }
2392 : }
2393 : CATCH_END_SECTION()
2394 : }
2395 :
2396 : // calculations such as the determinant
2397 : //
2398 16 : CATCH_GIVEN("calculations")
2399 : {
2400 6 : CATCH_START_SECTION("matrix: 2x2 determinant")
2401 : {
2402 : // setup A
2403 : //
2404 2 : snap::matrix<double> a(2, 2);
2405 :
2406 1 : CATCH_REQUIRE(a.rows() == 2);
2407 1 : CATCH_REQUIRE(a.columns() == 2);
2408 :
2409 1 : double const a00(frand());
2410 1 : double const a01(frand());
2411 1 : double const a10(frand());
2412 1 : double const a11(frand());
2413 :
2414 1 : a[0][0] = a00;
2415 1 : a[0][1] = a01;
2416 1 : a[1][0] = a10;
2417 1 : a[1][1] = a11;
2418 :
2419 1 : CATCH_REQUIRE(a[0][0] == a00);
2420 1 : CATCH_REQUIRE(a[0][1] == a01);
2421 1 : CATCH_REQUIRE(a[1][0] == a10);
2422 1 : CATCH_REQUIRE(a[1][1] == a11);
2423 :
2424 1 : double d(a.determinant());
2425 :
2426 : //return f_vector[0 + 0 * 2] * f_vector[1 + 1 * 2]
2427 : // - f_vector[1 + 0 * 2] * f_vector[0 + 1 * 2];
2428 1 : double e = a00 * a11 - a10 * a01;
2429 :
2430 1 : CATCH_REQUIRE(fabs(d - e) < 0.0001);
2431 : }
2432 : CATCH_END_SECTION()
2433 :
2434 6 : CATCH_START_SECTION("matrix: 3x3 determinant with specific data")
2435 : {
2436 : // setup A
2437 : //
2438 2 : snap::matrix<double> a(3, 3);
2439 :
2440 1 : CATCH_REQUIRE(a.rows() == 3);
2441 1 : CATCH_REQUIRE(a.columns() == 3);
2442 :
2443 1 : a[0][0] = 5.0;
2444 1 : a[0][1] = -2.0;
2445 1 : a[0][2] = 1.0;
2446 1 : a[1][0] = 0.0;
2447 1 : a[1][1] = 3.0;
2448 1 : a[1][2] = -1.0;
2449 1 : a[2][0] = 2.0;
2450 1 : a[2][1] = 0.0;
2451 1 : a[2][2] = 7.0;
2452 :
2453 1 : double d(a.determinant());
2454 :
2455 : // we know that the exact answer for this one is 103
2456 : //
2457 1 : CATCH_REQUIRE(fabs(d - 103.0) < 0.0001);
2458 : }
2459 : CATCH_END_SECTION()
2460 :
2461 6 : CATCH_START_SECTION("matrix: 3x3 determinant with random data")
2462 : {
2463 : // verify 10 times (with different values)
2464 : //
2465 11 : for(int repeat(0); repeat < 10; ++repeat)
2466 : {
2467 : // setup A
2468 : //
2469 20 : snap::matrix<double> a(3, 3);
2470 :
2471 10 : CATCH_REQUIRE(a.rows() == 3);
2472 10 : CATCH_REQUIRE(a.columns() == 3);
2473 :
2474 10 : double const a00(frand());
2475 10 : double const a01(frand());
2476 10 : double const a02(frand());
2477 10 : double const a10(frand());
2478 10 : double const a11(frand());
2479 10 : double const a12(frand());
2480 10 : double const a20(frand());
2481 10 : double const a21(frand());
2482 10 : double const a22(frand());
2483 :
2484 10 : a[0][0] = a00;
2485 10 : a[0][1] = a01;
2486 10 : a[0][2] = a02;
2487 10 : a[1][0] = a10;
2488 10 : a[1][1] = a11;
2489 10 : a[1][2] = a12;
2490 10 : a[2][0] = a20;
2491 10 : a[2][1] = a21;
2492 10 : a[2][2] = a22;
2493 :
2494 10 : CATCH_REQUIRE(a[0][0] == a00);
2495 10 : CATCH_REQUIRE(a[0][1] == a01);
2496 10 : CATCH_REQUIRE(a[0][2] == a02);
2497 10 : CATCH_REQUIRE(a[1][0] == a10);
2498 10 : CATCH_REQUIRE(a[1][1] == a11);
2499 10 : CATCH_REQUIRE(a[1][2] == a12);
2500 10 : CATCH_REQUIRE(a[2][0] == a20);
2501 10 : CATCH_REQUIRE(a[2][1] == a21);
2502 10 : CATCH_REQUIRE(a[2][2] == a22);
2503 :
2504 10 : double d(a.determinant());
2505 :
2506 : //return f_vector[0 + 0 * 2] * f_vector[1 + 1 * 2]
2507 : // - f_vector[1 + 0 * 2] * f_vector[0 + 1 * 2];
2508 10 : double e = a00 * a11 * a22 + a01 * a12 * a20 + a02 * a10 * a21
2509 10 : - a00 * a12 * a21 - a01 * a10 * a22 - a02 * a11 * a20;
2510 :
2511 10 : CATCH_REQUIRE(fabs(d - e) < 0.0001);
2512 : }
2513 : }
2514 : CATCH_END_SECTION()
2515 : }
2516 8 : }
2517 :
2518 :
2519 10 : CATCH_TEST_CASE("matrix_multiplicative", "[matrix]")
2520 : {
2521 : // create two random 4x4 matrices and make sure the add works
2522 : //
2523 16 : CATCH_GIVEN("mul")
2524 : {
2525 8 : CATCH_START_SECTION("matrix: b=a*<scalar>")
2526 : {
2527 : // setup A
2528 : //
2529 2 : snap::matrix<double> a(4, 4);
2530 :
2531 1 : CATCH_REQUIRE(a.rows() == 4);
2532 1 : CATCH_REQUIRE(a.columns() == 4);
2533 :
2534 1 : double const a00(frand());
2535 1 : double const a01(frand());
2536 1 : double const a02(frand());
2537 1 : double const a03(frand());
2538 1 : double const a10(frand());
2539 1 : double const a11(frand());
2540 1 : double const a12(frand());
2541 1 : double const a13(frand());
2542 1 : double const a20(frand());
2543 1 : double const a21(frand());
2544 1 : double const a22(frand());
2545 1 : double const a23(frand());
2546 1 : double const a30(frand());
2547 1 : double const a31(frand());
2548 1 : double const a32(frand());
2549 1 : double const a33(frand());
2550 :
2551 1 : a[0][0] = a00;
2552 1 : a[0][1] = a01;
2553 1 : a[0][2] = a02;
2554 1 : a[0][3] = a03;
2555 1 : a[1][0] = a10;
2556 1 : a[1][1] = a11;
2557 1 : a[1][2] = a12;
2558 1 : a[1][3] = a13;
2559 1 : a[2][0] = a20;
2560 1 : a[2][1] = a21;
2561 1 : a[2][2] = a22;
2562 1 : a[2][3] = a23;
2563 1 : a[3][0] = a30;
2564 1 : a[3][1] = a31;
2565 1 : a[3][2] = a32;
2566 1 : a[3][3] = a33;
2567 :
2568 1 : CATCH_REQUIRE(a[0][0] == a00);
2569 1 : CATCH_REQUIRE(a[0][1] == a01);
2570 1 : CATCH_REQUIRE(a[0][2] == a02);
2571 1 : CATCH_REQUIRE(a[0][3] == a03);
2572 1 : CATCH_REQUIRE(a[1][0] == a10);
2573 1 : CATCH_REQUIRE(a[1][1] == a11);
2574 1 : CATCH_REQUIRE(a[1][2] == a12);
2575 1 : CATCH_REQUIRE(a[1][3] == a13);
2576 1 : CATCH_REQUIRE(a[2][0] == a20);
2577 1 : CATCH_REQUIRE(a[2][1] == a21);
2578 1 : CATCH_REQUIRE(a[2][2] == a22);
2579 1 : CATCH_REQUIRE(a[2][3] == a23);
2580 1 : CATCH_REQUIRE(a[3][0] == a30);
2581 1 : CATCH_REQUIRE(a[3][1] == a31);
2582 1 : CATCH_REQUIRE(a[3][2] == a32);
2583 1 : CATCH_REQUIRE(a[3][3] == a33);
2584 :
2585 : // setup B
2586 : //
2587 2 : snap::matrix<double> b(4, 4);
2588 :
2589 1 : CATCH_REQUIRE(b.rows() == 4);
2590 1 : CATCH_REQUIRE(b.columns() == 4);
2591 :
2592 1 : double const b00(frand());
2593 1 : double const b01(frand());
2594 1 : double const b02(frand());
2595 1 : double const b03(frand());
2596 1 : double const b10(frand());
2597 1 : double const b11(frand());
2598 1 : double const b12(frand());
2599 1 : double const b13(frand());
2600 1 : double const b20(frand());
2601 1 : double const b21(frand());
2602 1 : double const b22(frand());
2603 1 : double const b23(frand());
2604 1 : double const b30(frand());
2605 1 : double const b31(frand());
2606 1 : double const b32(frand());
2607 1 : double const b33(frand());
2608 :
2609 1 : b[0][0] = b00;
2610 1 : b[0][1] = b01;
2611 1 : b[0][2] = b02;
2612 1 : b[0][3] = b03;
2613 1 : b[1][0] = b10;
2614 1 : b[1][1] = b11;
2615 1 : b[1][2] = b12;
2616 1 : b[1][3] = b13;
2617 1 : b[2][0] = b20;
2618 1 : b[2][1] = b21;
2619 1 : b[2][2] = b22;
2620 1 : b[2][3] = b23;
2621 1 : b[3][0] = b30;
2622 1 : b[3][1] = b31;
2623 1 : b[3][2] = b32;
2624 1 : b[3][3] = b33;
2625 :
2626 1 : CATCH_REQUIRE(b[0][0] == b00);
2627 1 : CATCH_REQUIRE(b[0][1] == b01);
2628 1 : CATCH_REQUIRE(b[0][2] == b02);
2629 1 : CATCH_REQUIRE(b[0][3] == b03);
2630 1 : CATCH_REQUIRE(b[1][0] == b10);
2631 1 : CATCH_REQUIRE(b[1][1] == b11);
2632 1 : CATCH_REQUIRE(b[1][2] == b12);
2633 1 : CATCH_REQUIRE(b[1][3] == b13);
2634 1 : CATCH_REQUIRE(b[2][0] == b20);
2635 1 : CATCH_REQUIRE(b[2][1] == b21);
2636 1 : CATCH_REQUIRE(b[2][2] == b22);
2637 1 : CATCH_REQUIRE(b[2][3] == b23);
2638 1 : CATCH_REQUIRE(b[3][0] == b30);
2639 1 : CATCH_REQUIRE(b[3][1] == b31);
2640 1 : CATCH_REQUIRE(b[3][2] == b32);
2641 1 : CATCH_REQUIRE(b[3][3] == b33);
2642 :
2643 : // create a scalar for our test
2644 : //
2645 1 : double scalar(frand());
2646 1 : while(scalar == 0.0 || scalar == 1.0)
2647 : {
2648 0 : scalar = frand();
2649 : }
2650 :
2651 : // run operation B = A + <scalar>
2652 : //
2653 1 : b = a * scalar;
2654 :
2655 1 : CATCH_REQUIRE(a[0][0] == a00);
2656 1 : CATCH_REQUIRE(a[0][1] == a01);
2657 1 : CATCH_REQUIRE(a[0][2] == a02);
2658 1 : CATCH_REQUIRE(a[0][3] == a03);
2659 1 : CATCH_REQUIRE(a[1][0] == a10);
2660 1 : CATCH_REQUIRE(a[1][1] == a11);
2661 1 : CATCH_REQUIRE(a[1][2] == a12);
2662 1 : CATCH_REQUIRE(a[1][3] == a13);
2663 1 : CATCH_REQUIRE(a[2][0] == a20);
2664 1 : CATCH_REQUIRE(a[2][1] == a21);
2665 1 : CATCH_REQUIRE(a[2][2] == a22);
2666 1 : CATCH_REQUIRE(a[2][3] == a23);
2667 1 : CATCH_REQUIRE(a[3][0] == a30);
2668 1 : CATCH_REQUIRE(a[3][1] == a31);
2669 1 : CATCH_REQUIRE(a[3][2] == a32);
2670 1 : CATCH_REQUIRE(a[3][3] == a33);
2671 :
2672 : // this can't fail because we ensure scalar != 0 or 1
2673 : //
2674 1 : CATCH_REQUIRE_FALSE(b[0][0] == b00);
2675 1 : CATCH_REQUIRE_FALSE(b[0][1] == b01);
2676 1 : CATCH_REQUIRE_FALSE(b[0][2] == b02);
2677 1 : CATCH_REQUIRE_FALSE(b[0][3] == b03);
2678 1 : CATCH_REQUIRE_FALSE(b[1][0] == b10);
2679 1 : CATCH_REQUIRE_FALSE(b[1][1] == b11);
2680 1 : CATCH_REQUIRE_FALSE(b[1][2] == b12);
2681 1 : CATCH_REQUIRE_FALSE(b[1][3] == b13);
2682 1 : CATCH_REQUIRE_FALSE(b[2][0] == b20);
2683 1 : CATCH_REQUIRE_FALSE(b[2][1] == b21);
2684 1 : CATCH_REQUIRE_FALSE(b[2][2] == b22);
2685 1 : CATCH_REQUIRE_FALSE(b[2][3] == b23);
2686 1 : CATCH_REQUIRE_FALSE(b[3][0] == b30);
2687 1 : CATCH_REQUIRE_FALSE(b[3][1] == b31);
2688 1 : CATCH_REQUIRE_FALSE(b[3][2] == b32);
2689 1 : CATCH_REQUIRE_FALSE(b[3][3] == b33);
2690 :
2691 1 : CATCH_REQUIRE(b[0][0] == a00 * scalar);
2692 1 : CATCH_REQUIRE(b[0][1] == a01 * scalar);
2693 1 : CATCH_REQUIRE(b[0][2] == a02 * scalar);
2694 1 : CATCH_REQUIRE(b[0][3] == a03 * scalar);
2695 1 : CATCH_REQUIRE(b[1][0] == a10 * scalar);
2696 1 : CATCH_REQUIRE(b[1][1] == a11 * scalar);
2697 1 : CATCH_REQUIRE(b[1][2] == a12 * scalar);
2698 1 : CATCH_REQUIRE(b[1][3] == a13 * scalar);
2699 1 : CATCH_REQUIRE(b[2][0] == a20 * scalar);
2700 1 : CATCH_REQUIRE(b[2][1] == a21 * scalar);
2701 1 : CATCH_REQUIRE(b[2][2] == a22 * scalar);
2702 1 : CATCH_REQUIRE(b[2][3] == a23 * scalar);
2703 1 : CATCH_REQUIRE(b[3][0] == a30 * scalar);
2704 1 : CATCH_REQUIRE(b[3][1] == a31 * scalar);
2705 1 : CATCH_REQUIRE(b[3][2] == a32 * scalar);
2706 1 : CATCH_REQUIRE(b[3][3] == a33 * scalar);
2707 : }
2708 : CATCH_END_SECTION()
2709 :
2710 8 : CATCH_START_SECTION("matrix: a*=<scalar>")
2711 : {
2712 : // setup A
2713 : //
2714 2 : snap::matrix<double> a(4, 4);
2715 :
2716 1 : CATCH_REQUIRE(a.rows() == 4);
2717 1 : CATCH_REQUIRE(a.columns() == 4);
2718 :
2719 1 : double const a00(frand());
2720 1 : double const a01(frand());
2721 1 : double const a02(frand());
2722 1 : double const a03(frand());
2723 1 : double const a10(frand());
2724 1 : double const a11(frand());
2725 1 : double const a12(frand());
2726 1 : double const a13(frand());
2727 1 : double const a20(frand());
2728 1 : double const a21(frand());
2729 1 : double const a22(frand());
2730 1 : double const a23(frand());
2731 1 : double const a30(frand());
2732 1 : double const a31(frand());
2733 1 : double const a32(frand());
2734 1 : double const a33(frand());
2735 :
2736 1 : a[0][0] = a00;
2737 1 : a[0][1] = a01;
2738 1 : a[0][2] = a02;
2739 1 : a[0][3] = a03;
2740 1 : a[1][0] = a10;
2741 1 : a[1][1] = a11;
2742 1 : a[1][2] = a12;
2743 1 : a[1][3] = a13;
2744 1 : a[2][0] = a20;
2745 1 : a[2][1] = a21;
2746 1 : a[2][2] = a22;
2747 1 : a[2][3] = a23;
2748 1 : a[3][0] = a30;
2749 1 : a[3][1] = a31;
2750 1 : a[3][2] = a32;
2751 1 : a[3][3] = a33;
2752 :
2753 1 : CATCH_REQUIRE(a[0][0] == a00);
2754 1 : CATCH_REQUIRE(a[0][1] == a01);
2755 1 : CATCH_REQUIRE(a[0][2] == a02);
2756 1 : CATCH_REQUIRE(a[0][3] == a03);
2757 1 : CATCH_REQUIRE(a[1][0] == a10);
2758 1 : CATCH_REQUIRE(a[1][1] == a11);
2759 1 : CATCH_REQUIRE(a[1][2] == a12);
2760 1 : CATCH_REQUIRE(a[1][3] == a13);
2761 1 : CATCH_REQUIRE(a[2][0] == a20);
2762 1 : CATCH_REQUIRE(a[2][1] == a21);
2763 1 : CATCH_REQUIRE(a[2][2] == a22);
2764 1 : CATCH_REQUIRE(a[2][3] == a23);
2765 1 : CATCH_REQUIRE(a[3][0] == a30);
2766 1 : CATCH_REQUIRE(a[3][1] == a31);
2767 1 : CATCH_REQUIRE(a[3][2] == a32);
2768 1 : CATCH_REQUIRE(a[3][3] == a33);
2769 :
2770 : // create a scalar for our test
2771 : //
2772 1 : double scalar(frand());
2773 1 : while(scalar == 0.0 || scalar == 1.0)
2774 : {
2775 0 : scalar = frand();
2776 : }
2777 :
2778 : // run operation A *= <scalar>
2779 : //
2780 1 : a *= scalar;
2781 :
2782 : // this can't fail because we ensure scalar != 0 or 1
2783 : //
2784 1 : CATCH_REQUIRE_FALSE(a[0][0] == a00);
2785 1 : CATCH_REQUIRE_FALSE(a[0][1] == a01);
2786 1 : CATCH_REQUIRE_FALSE(a[0][2] == a02);
2787 1 : CATCH_REQUIRE_FALSE(a[0][3] == a03);
2788 1 : CATCH_REQUIRE_FALSE(a[1][0] == a10);
2789 1 : CATCH_REQUIRE_FALSE(a[1][1] == a11);
2790 1 : CATCH_REQUIRE_FALSE(a[1][2] == a12);
2791 1 : CATCH_REQUIRE_FALSE(a[1][3] == a13);
2792 1 : CATCH_REQUIRE_FALSE(a[2][0] == a20);
2793 1 : CATCH_REQUIRE_FALSE(a[2][1] == a21);
2794 1 : CATCH_REQUIRE_FALSE(a[2][2] == a22);
2795 1 : CATCH_REQUIRE_FALSE(a[2][3] == a23);
2796 1 : CATCH_REQUIRE_FALSE(a[3][0] == a30);
2797 1 : CATCH_REQUIRE_FALSE(a[3][1] == a31);
2798 1 : CATCH_REQUIRE_FALSE(a[3][2] == a32);
2799 1 : CATCH_REQUIRE_FALSE(a[3][3] == a33);
2800 :
2801 1 : CATCH_REQUIRE(a[0][0] == a00 * scalar);
2802 1 : CATCH_REQUIRE(a[0][1] == a01 * scalar);
2803 1 : CATCH_REQUIRE(a[0][2] == a02 * scalar);
2804 1 : CATCH_REQUIRE(a[0][3] == a03 * scalar);
2805 1 : CATCH_REQUIRE(a[1][0] == a10 * scalar);
2806 1 : CATCH_REQUIRE(a[1][1] == a11 * scalar);
2807 1 : CATCH_REQUIRE(a[1][2] == a12 * scalar);
2808 1 : CATCH_REQUIRE(a[1][3] == a13 * scalar);
2809 1 : CATCH_REQUIRE(a[2][0] == a20 * scalar);
2810 1 : CATCH_REQUIRE(a[2][1] == a21 * scalar);
2811 1 : CATCH_REQUIRE(a[2][2] == a22 * scalar);
2812 1 : CATCH_REQUIRE(a[2][3] == a23 * scalar);
2813 1 : CATCH_REQUIRE(a[3][0] == a30 * scalar);
2814 1 : CATCH_REQUIRE(a[3][1] == a31 * scalar);
2815 1 : CATCH_REQUIRE(a[3][2] == a32 * scalar);
2816 1 : CATCH_REQUIRE(a[3][3] == a33 * scalar);
2817 : }
2818 : CATCH_END_SECTION()
2819 :
2820 8 : CATCH_START_SECTION("matrix: c=a*b")
2821 : {
2822 : // setup A
2823 : //
2824 2 : snap::matrix<double> a(4, 4);
2825 :
2826 1 : CATCH_REQUIRE(a.rows() == 4);
2827 1 : CATCH_REQUIRE(a.columns() == 4);
2828 :
2829 1 : double const a00(frand());
2830 1 : double const a01(frand());
2831 1 : double const a02(frand());
2832 1 : double const a03(frand());
2833 1 : double const a10(frand());
2834 1 : double const a11(frand());
2835 1 : double const a12(frand());
2836 1 : double const a13(frand());
2837 1 : double const a20(frand());
2838 1 : double const a21(frand());
2839 1 : double const a22(frand());
2840 1 : double const a23(frand());
2841 1 : double const a30(frand());
2842 1 : double const a31(frand());
2843 1 : double const a32(frand());
2844 1 : double const a33(frand());
2845 :
2846 1 : a[0][0] = a00;
2847 1 : a[0][1] = a01;
2848 1 : a[0][2] = a02;
2849 1 : a[0][3] = a03;
2850 1 : a[1][0] = a10;
2851 1 : a[1][1] = a11;
2852 1 : a[1][2] = a12;
2853 1 : a[1][3] = a13;
2854 1 : a[2][0] = a20;
2855 1 : a[2][1] = a21;
2856 1 : a[2][2] = a22;
2857 1 : a[2][3] = a23;
2858 1 : a[3][0] = a30;
2859 1 : a[3][1] = a31;
2860 1 : a[3][2] = a32;
2861 1 : a[3][3] = a33;
2862 :
2863 1 : CATCH_REQUIRE(a[0][0] == a00);
2864 1 : CATCH_REQUIRE(a[0][1] == a01);
2865 1 : CATCH_REQUIRE(a[0][2] == a02);
2866 1 : CATCH_REQUIRE(a[0][3] == a03);
2867 1 : CATCH_REQUIRE(a[1][0] == a10);
2868 1 : CATCH_REQUIRE(a[1][1] == a11);
2869 1 : CATCH_REQUIRE(a[1][2] == a12);
2870 1 : CATCH_REQUIRE(a[1][3] == a13);
2871 1 : CATCH_REQUIRE(a[2][0] == a20);
2872 1 : CATCH_REQUIRE(a[2][1] == a21);
2873 1 : CATCH_REQUIRE(a[2][2] == a22);
2874 1 : CATCH_REQUIRE(a[2][3] == a23);
2875 1 : CATCH_REQUIRE(a[3][0] == a30);
2876 1 : CATCH_REQUIRE(a[3][1] == a31);
2877 1 : CATCH_REQUIRE(a[3][2] == a32);
2878 1 : CATCH_REQUIRE(a[3][3] == a33);
2879 :
2880 : // setup B
2881 : //
2882 2 : snap::matrix<double> b(4, 4);
2883 :
2884 1 : CATCH_REQUIRE(b.rows() == 4);
2885 1 : CATCH_REQUIRE(b.columns() == 4);
2886 :
2887 1 : double const b00(frand());
2888 1 : double const b01(frand());
2889 1 : double const b02(frand());
2890 1 : double const b03(frand());
2891 1 : double const b10(frand());
2892 1 : double const b11(frand());
2893 1 : double const b12(frand());
2894 1 : double const b13(frand());
2895 1 : double const b20(frand());
2896 1 : double const b21(frand());
2897 1 : double const b22(frand());
2898 1 : double const b23(frand());
2899 1 : double const b30(frand());
2900 1 : double const b31(frand());
2901 1 : double const b32(frand());
2902 1 : double const b33(frand());
2903 :
2904 1 : b[0][0] = b00;
2905 1 : b[0][1] = b01;
2906 1 : b[0][2] = b02;
2907 1 : b[0][3] = b03;
2908 1 : b[1][0] = b10;
2909 1 : b[1][1] = b11;
2910 1 : b[1][2] = b12;
2911 1 : b[1][3] = b13;
2912 1 : b[2][0] = b20;
2913 1 : b[2][1] = b21;
2914 1 : b[2][2] = b22;
2915 1 : b[2][3] = b23;
2916 1 : b[3][0] = b30;
2917 1 : b[3][1] = b31;
2918 1 : b[3][2] = b32;
2919 1 : b[3][3] = b33;
2920 :
2921 1 : CATCH_REQUIRE(b[0][0] == b00);
2922 1 : CATCH_REQUIRE(b[0][1] == b01);
2923 1 : CATCH_REQUIRE(b[0][2] == b02);
2924 1 : CATCH_REQUIRE(b[0][3] == b03);
2925 1 : CATCH_REQUIRE(b[1][0] == b10);
2926 1 : CATCH_REQUIRE(b[1][1] == b11);
2927 1 : CATCH_REQUIRE(b[1][2] == b12);
2928 1 : CATCH_REQUIRE(b[1][3] == b13);
2929 1 : CATCH_REQUIRE(b[2][0] == b20);
2930 1 : CATCH_REQUIRE(b[2][1] == b21);
2931 1 : CATCH_REQUIRE(b[2][2] == b22);
2932 1 : CATCH_REQUIRE(b[2][3] == b23);
2933 1 : CATCH_REQUIRE(b[3][0] == b30);
2934 1 : CATCH_REQUIRE(b[3][1] == b31);
2935 1 : CATCH_REQUIRE(b[3][2] == b32);
2936 1 : CATCH_REQUIRE(b[3][3] == b33);
2937 :
2938 : // setup C
2939 : //
2940 2 : snap::matrix<double> c(4, 4);
2941 :
2942 1 : CATCH_REQUIRE(c.rows() == 4);
2943 1 : CATCH_REQUIRE(c.columns() == 4);
2944 :
2945 1 : double const c00(frand());
2946 1 : double const c01(frand());
2947 1 : double const c02(frand());
2948 1 : double const c03(frand());
2949 1 : double const c10(frand());
2950 1 : double const c11(frand());
2951 1 : double const c12(frand());
2952 1 : double const c13(frand());
2953 1 : double const c20(frand());
2954 1 : double const c21(frand());
2955 1 : double const c22(frand());
2956 1 : double const c23(frand());
2957 1 : double const c30(frand());
2958 1 : double const c31(frand());
2959 1 : double const c32(frand());
2960 1 : double const c33(frand());
2961 :
2962 1 : c[0][0] = c00;
2963 1 : c[0][1] = c01;
2964 1 : c[0][2] = c02;
2965 1 : c[0][3] = c03;
2966 1 : c[1][0] = c10;
2967 1 : c[1][1] = c11;
2968 1 : c[1][2] = c12;
2969 1 : c[1][3] = c13;
2970 1 : c[2][0] = c20;
2971 1 : c[2][1] = c21;
2972 1 : c[2][2] = c22;
2973 1 : c[2][3] = c23;
2974 1 : c[3][0] = c30;
2975 1 : c[3][1] = c31;
2976 1 : c[3][2] = c32;
2977 1 : c[3][3] = c33;
2978 :
2979 1 : CATCH_REQUIRE(c[0][0] == c00);
2980 1 : CATCH_REQUIRE(c[0][1] == c01);
2981 1 : CATCH_REQUIRE(c[0][2] == c02);
2982 1 : CATCH_REQUIRE(c[0][3] == c03);
2983 1 : CATCH_REQUIRE(c[1][0] == c10);
2984 1 : CATCH_REQUIRE(c[1][1] == c11);
2985 1 : CATCH_REQUIRE(c[1][2] == c12);
2986 1 : CATCH_REQUIRE(c[1][3] == c13);
2987 1 : CATCH_REQUIRE(c[2][0] == c20);
2988 1 : CATCH_REQUIRE(c[2][1] == c21);
2989 1 : CATCH_REQUIRE(c[2][2] == c22);
2990 1 : CATCH_REQUIRE(c[2][3] == c23);
2991 1 : CATCH_REQUIRE(c[3][0] == c30);
2992 1 : CATCH_REQUIRE(c[3][1] == c31);
2993 1 : CATCH_REQUIRE(c[3][2] == c32);
2994 1 : CATCH_REQUIRE(c[3][3] == c33);
2995 :
2996 : // run operation C = A * B
2997 : //
2998 1 : c = a * b;
2999 :
3000 1 : CATCH_REQUIRE(a[0][0] == a00);
3001 1 : CATCH_REQUIRE(a[0][1] == a01);
3002 1 : CATCH_REQUIRE(a[0][2] == a02);
3003 1 : CATCH_REQUIRE(a[0][3] == a03);
3004 1 : CATCH_REQUIRE(a[1][0] == a10);
3005 1 : CATCH_REQUIRE(a[1][1] == a11);
3006 1 : CATCH_REQUIRE(a[1][2] == a12);
3007 1 : CATCH_REQUIRE(a[1][3] == a13);
3008 1 : CATCH_REQUIRE(a[2][0] == a20);
3009 1 : CATCH_REQUIRE(a[2][1] == a21);
3010 1 : CATCH_REQUIRE(a[2][2] == a22);
3011 1 : CATCH_REQUIRE(a[2][3] == a23);
3012 1 : CATCH_REQUIRE(a[3][0] == a30);
3013 1 : CATCH_REQUIRE(a[3][1] == a31);
3014 1 : CATCH_REQUIRE(a[3][2] == a32);
3015 1 : CATCH_REQUIRE(a[3][3] == a33);
3016 :
3017 1 : CATCH_REQUIRE(b[0][0] == b00);
3018 1 : CATCH_REQUIRE(b[0][1] == b01);
3019 1 : CATCH_REQUIRE(b[0][2] == b02);
3020 1 : CATCH_REQUIRE(b[0][3] == b03);
3021 1 : CATCH_REQUIRE(b[1][0] == b10);
3022 1 : CATCH_REQUIRE(b[1][1] == b11);
3023 1 : CATCH_REQUIRE(b[1][2] == b12);
3024 1 : CATCH_REQUIRE(b[1][3] == b13);
3025 1 : CATCH_REQUIRE(b[2][0] == b20);
3026 1 : CATCH_REQUIRE(b[2][1] == b21);
3027 1 : CATCH_REQUIRE(b[2][2] == b22);
3028 1 : CATCH_REQUIRE(b[2][3] == b23);
3029 1 : CATCH_REQUIRE(b[3][0] == b30);
3030 1 : CATCH_REQUIRE(b[3][1] == b31);
3031 1 : CATCH_REQUIRE(b[3][2] == b32);
3032 1 : CATCH_REQUIRE(b[3][3] == b33);
3033 :
3034 : // this could fail (albeit rather unlikely)
3035 : //CATCH_REQUIRE_FALSE(c[0][0] == c00);
3036 : //CATCH_REQUIRE_FALSE(c[0][1] == c01);
3037 : //CATCH_REQUIRE_FALSE(c[0][2] == c02);
3038 : //CATCH_REQUIRE_FALSE(c[0][3] == c03);
3039 : //CATCH_REQUIRE_FALSE(c[1][0] == c10);
3040 : //CATCH_REQUIRE_FALSE(c[1][1] == c11);
3041 : //CATCH_REQUIRE_FALSE(c[1][2] == c12);
3042 : //CATCH_REQUIRE_FALSE(c[1][3] == c13);
3043 : //CATCH_REQUIRE_FALSE(c[2][0] == c20);
3044 : //CATCH_REQUIRE_FALSE(c[2][1] == c21);
3045 : //CATCH_REQUIRE_FALSE(c[2][2] == c22);
3046 : //CATCH_REQUIRE_FALSE(c[2][3] == c23);
3047 : //CATCH_REQUIRE_FALSE(c[3][0] == c30);
3048 : //CATCH_REQUIRE_FALSE(c[3][1] == c31);
3049 : //CATCH_REQUIRE_FALSE(c[3][2] == c32);
3050 : //CATCH_REQUIRE_FALSE(c[3][3] == c33);
3051 :
3052 : //std::cout << "A = " << a << std::endl;
3053 : //std::cout << "B = " << b << std::endl;
3054 : //std::cout << "C = " << c << std::endl;
3055 :
3056 1 : CATCH_REQUIRE(c[0][0] == a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30);
3057 1 : CATCH_REQUIRE(c[0][1] == a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31);
3058 1 : CATCH_REQUIRE(c[0][2] == a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32);
3059 1 : CATCH_REQUIRE(c[0][3] == a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33);
3060 :
3061 1 : CATCH_REQUIRE(c[1][0] == a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30);
3062 1 : CATCH_REQUIRE(c[1][1] == a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31);
3063 1 : CATCH_REQUIRE(c[1][2] == a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32);
3064 1 : CATCH_REQUIRE(c[1][3] == a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33);
3065 :
3066 1 : CATCH_REQUIRE(c[2][0] == a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30);
3067 1 : CATCH_REQUIRE(c[2][1] == a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31);
3068 1 : CATCH_REQUIRE(c[2][2] == a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32);
3069 1 : CATCH_REQUIRE(c[2][3] == a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33);
3070 :
3071 1 : CATCH_REQUIRE(c[3][0] == a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30);
3072 1 : CATCH_REQUIRE(c[3][1] == a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31);
3073 1 : CATCH_REQUIRE(c[3][2] == a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32);
3074 1 : CATCH_REQUIRE(c[3][3] == a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33);
3075 :
3076 : // if swapped it would equal this instead
3077 : //CATCH_REQUIRE(c[0][0] == a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03);
3078 : //CATCH_REQUIRE(c[0][1] == a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03);
3079 : //CATCH_REQUIRE(c[0][2] == a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03);
3080 : //CATCH_REQUIRE(c[0][3] == a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03);
3081 :
3082 : //CATCH_REQUIRE(c[1][0] == a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13);
3083 : //CATCH_REQUIRE(c[1][1] == a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13);
3084 : //CATCH_REQUIRE(c[1][2] == a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13);
3085 : //CATCH_REQUIRE(c[1][3] == a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13);
3086 :
3087 : //CATCH_REQUIRE(c[2][0] == a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23);
3088 : //CATCH_REQUIRE(c[2][1] == a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23);
3089 : //CATCH_REQUIRE(c[2][2] == a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23);
3090 : //CATCH_REQUIRE(c[2][3] == a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23);
3091 :
3092 : //CATCH_REQUIRE(c[3][0] == a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33);
3093 : //CATCH_REQUIRE(c[3][1] == a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33);
3094 : //CATCH_REQUIRE(c[3][2] == a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33);
3095 : //CATCH_REQUIRE(c[3][3] == a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33);
3096 : }
3097 : CATCH_END_SECTION()
3098 :
3099 8 : CATCH_START_SECTION("matrix: a*=b")
3100 : {
3101 : // setup A
3102 : //
3103 2 : snap::matrix<double> a(4, 4);
3104 :
3105 1 : CATCH_REQUIRE(a.rows() == 4);
3106 1 : CATCH_REQUIRE(a.columns() == 4);
3107 :
3108 1 : double const a00(frand());
3109 1 : double const a01(frand());
3110 1 : double const a02(frand());
3111 1 : double const a03(frand());
3112 1 : double const a10(frand());
3113 1 : double const a11(frand());
3114 1 : double const a12(frand());
3115 1 : double const a13(frand());
3116 1 : double const a20(frand());
3117 1 : double const a21(frand());
3118 1 : double const a22(frand());
3119 1 : double const a23(frand());
3120 1 : double const a30(frand());
3121 1 : double const a31(frand());
3122 1 : double const a32(frand());
3123 1 : double const a33(frand());
3124 :
3125 1 : a[0][0] = a00;
3126 1 : a[0][1] = a01;
3127 1 : a[0][2] = a02;
3128 1 : a[0][3] = a03;
3129 1 : a[1][0] = a10;
3130 1 : a[1][1] = a11;
3131 1 : a[1][2] = a12;
3132 1 : a[1][3] = a13;
3133 1 : a[2][0] = a20;
3134 1 : a[2][1] = a21;
3135 1 : a[2][2] = a22;
3136 1 : a[2][3] = a23;
3137 1 : a[3][0] = a30;
3138 1 : a[3][1] = a31;
3139 1 : a[3][2] = a32;
3140 1 : a[3][3] = a33;
3141 :
3142 1 : CATCH_REQUIRE(a[0][0] == a00);
3143 1 : CATCH_REQUIRE(a[0][1] == a01);
3144 1 : CATCH_REQUIRE(a[0][2] == a02);
3145 1 : CATCH_REQUIRE(a[0][3] == a03);
3146 1 : CATCH_REQUIRE(a[1][0] == a10);
3147 1 : CATCH_REQUIRE(a[1][1] == a11);
3148 1 : CATCH_REQUIRE(a[1][2] == a12);
3149 1 : CATCH_REQUIRE(a[1][3] == a13);
3150 1 : CATCH_REQUIRE(a[2][0] == a20);
3151 1 : CATCH_REQUIRE(a[2][1] == a21);
3152 1 : CATCH_REQUIRE(a[2][2] == a22);
3153 1 : CATCH_REQUIRE(a[2][3] == a23);
3154 1 : CATCH_REQUIRE(a[3][0] == a30);
3155 1 : CATCH_REQUIRE(a[3][1] == a31);
3156 1 : CATCH_REQUIRE(a[3][2] == a32);
3157 1 : CATCH_REQUIRE(a[3][3] == a33);
3158 :
3159 : // setup B
3160 : //
3161 2 : snap::matrix<double> b(4, 4);
3162 :
3163 1 : CATCH_REQUIRE(b.rows() == 4);
3164 1 : CATCH_REQUIRE(b.columns() == 4);
3165 :
3166 1 : double const b00(frand());
3167 1 : double const b01(frand());
3168 1 : double const b02(frand());
3169 1 : double const b03(frand());
3170 1 : double const b10(frand());
3171 1 : double const b11(frand());
3172 1 : double const b12(frand());
3173 1 : double const b13(frand());
3174 1 : double const b20(frand());
3175 1 : double const b21(frand());
3176 1 : double const b22(frand());
3177 1 : double const b23(frand());
3178 1 : double const b30(frand());
3179 1 : double const b31(frand());
3180 1 : double const b32(frand());
3181 1 : double const b33(frand());
3182 :
3183 1 : b[0][0] = b00;
3184 1 : b[0][1] = b01;
3185 1 : b[0][2] = b02;
3186 1 : b[0][3] = b03;
3187 1 : b[1][0] = b10;
3188 1 : b[1][1] = b11;
3189 1 : b[1][2] = b12;
3190 1 : b[1][3] = b13;
3191 1 : b[2][0] = b20;
3192 1 : b[2][1] = b21;
3193 1 : b[2][2] = b22;
3194 1 : b[2][3] = b23;
3195 1 : b[3][0] = b30;
3196 1 : b[3][1] = b31;
3197 1 : b[3][2] = b32;
3198 1 : b[3][3] = b33;
3199 :
3200 1 : CATCH_REQUIRE(b[0][0] == b00);
3201 1 : CATCH_REQUIRE(b[0][1] == b01);
3202 1 : CATCH_REQUIRE(b[0][2] == b02);
3203 1 : CATCH_REQUIRE(b[0][3] == b03);
3204 1 : CATCH_REQUIRE(b[1][0] == b10);
3205 1 : CATCH_REQUIRE(b[1][1] == b11);
3206 1 : CATCH_REQUIRE(b[1][2] == b12);
3207 1 : CATCH_REQUIRE(b[1][3] == b13);
3208 1 : CATCH_REQUIRE(b[2][0] == b20);
3209 1 : CATCH_REQUIRE(b[2][1] == b21);
3210 1 : CATCH_REQUIRE(b[2][2] == b22);
3211 1 : CATCH_REQUIRE(b[2][3] == b23);
3212 1 : CATCH_REQUIRE(b[3][0] == b30);
3213 1 : CATCH_REQUIRE(b[3][1] == b31);
3214 1 : CATCH_REQUIRE(b[3][2] == b32);
3215 1 : CATCH_REQUIRE(b[3][3] == b33);
3216 :
3217 : // run operation A *= B
3218 : //
3219 1 : a *= b;
3220 :
3221 : // this could fail
3222 : //
3223 : //CATCH_REQUIRE_FALSE(a[0][0] == a00);
3224 : //CATCH_REQUIRE_FALSE(a[0][1] == a01);
3225 : //CATCH_REQUIRE_FALSE(a[0][2] == a02);
3226 : //CATCH_REQUIRE_FALSE(a[0][3] == a03);
3227 : //CATCH_REQUIRE_FALSE(a[1][0] == a10);
3228 : //CATCH_REQUIRE_FALSE(a[1][1] == a11);
3229 : //CATCH_REQUIRE_FALSE(a[1][2] == a12);
3230 : //CATCH_REQUIRE_FALSE(a[1][3] == a13);
3231 : //CATCH_REQUIRE_FALSE(a[2][0] == a20);
3232 : //CATCH_REQUIRE_FALSE(a[2][1] == a21);
3233 : //CATCH_REQUIRE_FALSE(a[2][2] == a22);
3234 : //CATCH_REQUIRE_FALSE(a[2][3] == a23);
3235 : //CATCH_REQUIRE_FALSE(a[3][0] == a30);
3236 : //CATCH_REQUIRE_FALSE(a[3][1] == a31);
3237 : //CATCH_REQUIRE_FALSE(a[3][2] == a32);
3238 : //CATCH_REQUIRE_FALSE(a[3][3] == a33);
3239 :
3240 1 : CATCH_REQUIRE(b[0][0] == b00);
3241 1 : CATCH_REQUIRE(b[0][1] == b01);
3242 1 : CATCH_REQUIRE(b[0][2] == b02);
3243 1 : CATCH_REQUIRE(b[0][3] == b03);
3244 1 : CATCH_REQUIRE(b[1][0] == b10);
3245 1 : CATCH_REQUIRE(b[1][1] == b11);
3246 1 : CATCH_REQUIRE(b[1][2] == b12);
3247 1 : CATCH_REQUIRE(b[1][3] == b13);
3248 1 : CATCH_REQUIRE(b[2][0] == b20);
3249 1 : CATCH_REQUIRE(b[2][1] == b21);
3250 1 : CATCH_REQUIRE(b[2][2] == b22);
3251 1 : CATCH_REQUIRE(b[2][3] == b23);
3252 1 : CATCH_REQUIRE(b[3][0] == b30);
3253 1 : CATCH_REQUIRE(b[3][1] == b31);
3254 1 : CATCH_REQUIRE(b[3][2] == b32);
3255 1 : CATCH_REQUIRE(b[3][3] == b33);
3256 :
3257 1 : CATCH_REQUIRE(a[0][0] == a00 * b00 + a01 * b10 + a02 * b20 + a03 * b30);
3258 1 : CATCH_REQUIRE(a[0][1] == a00 * b01 + a01 * b11 + a02 * b21 + a03 * b31);
3259 1 : CATCH_REQUIRE(a[0][2] == a00 * b02 + a01 * b12 + a02 * b22 + a03 * b32);
3260 1 : CATCH_REQUIRE(a[0][3] == a00 * b03 + a01 * b13 + a02 * b23 + a03 * b33);
3261 :
3262 1 : CATCH_REQUIRE(a[1][0] == a10 * b00 + a11 * b10 + a12 * b20 + a13 * b30);
3263 1 : CATCH_REQUIRE(a[1][1] == a10 * b01 + a11 * b11 + a12 * b21 + a13 * b31);
3264 1 : CATCH_REQUIRE(a[1][2] == a10 * b02 + a11 * b12 + a12 * b22 + a13 * b32);
3265 1 : CATCH_REQUIRE(a[1][3] == a10 * b03 + a11 * b13 + a12 * b23 + a13 * b33);
3266 :
3267 1 : CATCH_REQUIRE(a[2][0] == a20 * b00 + a21 * b10 + a22 * b20 + a23 * b30);
3268 1 : CATCH_REQUIRE(a[2][1] == a20 * b01 + a21 * b11 + a22 * b21 + a23 * b31);
3269 1 : CATCH_REQUIRE(a[2][2] == a20 * b02 + a21 * b12 + a22 * b22 + a23 * b32);
3270 1 : CATCH_REQUIRE(a[2][3] == a20 * b03 + a21 * b13 + a22 * b23 + a23 * b33);
3271 :
3272 1 : CATCH_REQUIRE(a[3][0] == a30 * b00 + a31 * b10 + a32 * b20 + a33 * b30);
3273 1 : CATCH_REQUIRE(a[3][1] == a30 * b01 + a31 * b11 + a32 * b21 + a33 * b31);
3274 1 : CATCH_REQUIRE(a[3][2] == a30 * b02 + a31 * b12 + a32 * b22 + a33 * b32);
3275 1 : CATCH_REQUIRE(a[3][3] == a30 * b03 + a31 * b13 + a32 * b23 + a33 * b33);
3276 :
3277 : //CATCH_REQUIRE(a[0][0] == a00 * b00 + a10 * b01 + a20 * b02 + a30 * b03);
3278 : //CATCH_REQUIRE(a[0][1] == a01 * b00 + a11 * b01 + a21 * b02 + a31 * b03);
3279 : //CATCH_REQUIRE(a[0][2] == a02 * b00 + a12 * b01 + a22 * b02 + a32 * b03);
3280 : //CATCH_REQUIRE(a[0][3] == a03 * b00 + a13 * b01 + a23 * b02 + a33 * b03);
3281 :
3282 : //CATCH_REQUIRE(a[1][0] == a00 * b10 + a10 * b11 + a20 * b12 + a30 * b13);
3283 : //CATCH_REQUIRE(a[1][1] == a01 * b10 + a11 * b11 + a21 * b12 + a31 * b13);
3284 : //CATCH_REQUIRE(a[1][2] == a02 * b10 + a12 * b11 + a22 * b12 + a32 * b13);
3285 : //CATCH_REQUIRE(a[1][3] == a03 * b10 + a13 * b11 + a23 * b12 + a33 * b13);
3286 :
3287 : //CATCH_REQUIRE(a[2][0] == a00 * b20 + a10 * b21 + a20 * b22 + a30 * b23);
3288 : //CATCH_REQUIRE(a[2][1] == a01 * b20 + a11 * b21 + a21 * b22 + a31 * b23);
3289 : //CATCH_REQUIRE(a[2][2] == a02 * b20 + a12 * b21 + a22 * b22 + a32 * b23);
3290 : //CATCH_REQUIRE(a[2][3] == a03 * b20 + a13 * b21 + a23 * b22 + a33 * b23);
3291 :
3292 : //CATCH_REQUIRE(a[3][0] == a00 * b30 + a10 * b31 + a20 * b32 + a30 * b33);
3293 : //CATCH_REQUIRE(a[3][1] == a01 * b30 + a11 * b31 + a21 * b32 + a31 * b33);
3294 : //CATCH_REQUIRE(a[3][2] == a02 * b30 + a12 * b31 + a22 * b32 + a32 * b33);
3295 : //CATCH_REQUIRE(a[3][3] == a03 * b30 + a13 * b31 + a23 * b32 + a33 * b33);
3296 : }
3297 : CATCH_END_SECTION()
3298 : }
3299 :
3300 : // create two random 4x4 matrices and make sure the add works
3301 : //
3302 16 : CATCH_GIVEN("div")
3303 : {
3304 8 : CATCH_START_SECTION("matrix: b=a/<scalar>")
3305 : {
3306 : // setup A
3307 : //
3308 2 : snap::matrix<double> a(4, 4);
3309 :
3310 1 : CATCH_REQUIRE(a.rows() == 4);
3311 1 : CATCH_REQUIRE(a.columns() == 4);
3312 :
3313 1 : double const a00(frand());
3314 1 : double const a01(frand());
3315 1 : double const a02(frand());
3316 1 : double const a03(frand());
3317 1 : double const a10(frand());
3318 1 : double const a11(frand());
3319 1 : double const a12(frand());
3320 1 : double const a13(frand());
3321 1 : double const a20(frand());
3322 1 : double const a21(frand());
3323 1 : double const a22(frand());
3324 1 : double const a23(frand());
3325 1 : double const a30(frand());
3326 1 : double const a31(frand());
3327 1 : double const a32(frand());
3328 1 : double const a33(frand());
3329 :
3330 1 : a[0][0] = a00;
3331 1 : a[0][1] = a01;
3332 1 : a[0][2] = a02;
3333 1 : a[0][3] = a03;
3334 1 : a[1][0] = a10;
3335 1 : a[1][1] = a11;
3336 1 : a[1][2] = a12;
3337 1 : a[1][3] = a13;
3338 1 : a[2][0] = a20;
3339 1 : a[2][1] = a21;
3340 1 : a[2][2] = a22;
3341 1 : a[2][3] = a23;
3342 1 : a[3][0] = a30;
3343 1 : a[3][1] = a31;
3344 1 : a[3][2] = a32;
3345 1 : a[3][3] = a33;
3346 :
3347 1 : CATCH_REQUIRE(a[0][0] == a00);
3348 1 : CATCH_REQUIRE(a[0][1] == a01);
3349 1 : CATCH_REQUIRE(a[0][2] == a02);
3350 1 : CATCH_REQUIRE(a[0][3] == a03);
3351 1 : CATCH_REQUIRE(a[1][0] == a10);
3352 1 : CATCH_REQUIRE(a[1][1] == a11);
3353 1 : CATCH_REQUIRE(a[1][2] == a12);
3354 1 : CATCH_REQUIRE(a[1][3] == a13);
3355 1 : CATCH_REQUIRE(a[2][0] == a20);
3356 1 : CATCH_REQUIRE(a[2][1] == a21);
3357 1 : CATCH_REQUIRE(a[2][2] == a22);
3358 1 : CATCH_REQUIRE(a[2][3] == a23);
3359 1 : CATCH_REQUIRE(a[3][0] == a30);
3360 1 : CATCH_REQUIRE(a[3][1] == a31);
3361 1 : CATCH_REQUIRE(a[3][2] == a32);
3362 1 : CATCH_REQUIRE(a[3][3] == a33);
3363 :
3364 : // setup B
3365 : //
3366 2 : snap::matrix<double> b(4, 4);
3367 :
3368 1 : CATCH_REQUIRE(b.rows() == 4);
3369 1 : CATCH_REQUIRE(b.columns() == 4);
3370 :
3371 1 : double const b00(frand());
3372 1 : double const b01(frand());
3373 1 : double const b02(frand());
3374 1 : double const b03(frand());
3375 1 : double const b10(frand());
3376 1 : double const b11(frand());
3377 1 : double const b12(frand());
3378 1 : double const b13(frand());
3379 1 : double const b20(frand());
3380 1 : double const b21(frand());
3381 1 : double const b22(frand());
3382 1 : double const b23(frand());
3383 1 : double const b30(frand());
3384 1 : double const b31(frand());
3385 1 : double const b32(frand());
3386 1 : double const b33(frand());
3387 :
3388 1 : b[0][0] = b00;
3389 1 : b[0][1] = b01;
3390 1 : b[0][2] = b02;
3391 1 : b[0][3] = b03;
3392 1 : b[1][0] = b10;
3393 1 : b[1][1] = b11;
3394 1 : b[1][2] = b12;
3395 1 : b[1][3] = b13;
3396 1 : b[2][0] = b20;
3397 1 : b[2][1] = b21;
3398 1 : b[2][2] = b22;
3399 1 : b[2][3] = b23;
3400 1 : b[3][0] = b30;
3401 1 : b[3][1] = b31;
3402 1 : b[3][2] = b32;
3403 1 : b[3][3] = b33;
3404 :
3405 1 : CATCH_REQUIRE(b[0][0] == b00);
3406 1 : CATCH_REQUIRE(b[0][1] == b01);
3407 1 : CATCH_REQUIRE(b[0][2] == b02);
3408 1 : CATCH_REQUIRE(b[0][3] == b03);
3409 1 : CATCH_REQUIRE(b[1][0] == b10);
3410 1 : CATCH_REQUIRE(b[1][1] == b11);
3411 1 : CATCH_REQUIRE(b[1][2] == b12);
3412 1 : CATCH_REQUIRE(b[1][3] == b13);
3413 1 : CATCH_REQUIRE(b[2][0] == b20);
3414 1 : CATCH_REQUIRE(b[2][1] == b21);
3415 1 : CATCH_REQUIRE(b[2][2] == b22);
3416 1 : CATCH_REQUIRE(b[2][3] == b23);
3417 1 : CATCH_REQUIRE(b[3][0] == b30);
3418 1 : CATCH_REQUIRE(b[3][1] == b31);
3419 1 : CATCH_REQUIRE(b[3][2] == b32);
3420 1 : CATCH_REQUIRE(b[3][3] == b33);
3421 :
3422 : // create a scalar for our test
3423 : //
3424 1 : double scalar(frand());
3425 1 : while(scalar == 0.0 || scalar == 1.0)
3426 : {
3427 0 : scalar = frand();
3428 : }
3429 :
3430 : // run operation B = A / <scalar>
3431 : //
3432 1 : b = a / scalar;
3433 :
3434 1 : CATCH_REQUIRE(a[0][0] == a00);
3435 1 : CATCH_REQUIRE(a[0][1] == a01);
3436 1 : CATCH_REQUIRE(a[0][2] == a02);
3437 1 : CATCH_REQUIRE(a[0][3] == a03);
3438 1 : CATCH_REQUIRE(a[1][0] == a10);
3439 1 : CATCH_REQUIRE(a[1][1] == a11);
3440 1 : CATCH_REQUIRE(a[1][2] == a12);
3441 1 : CATCH_REQUIRE(a[1][3] == a13);
3442 1 : CATCH_REQUIRE(a[2][0] == a20);
3443 1 : CATCH_REQUIRE(a[2][1] == a21);
3444 1 : CATCH_REQUIRE(a[2][2] == a22);
3445 1 : CATCH_REQUIRE(a[2][3] == a23);
3446 1 : CATCH_REQUIRE(a[3][0] == a30);
3447 1 : CATCH_REQUIRE(a[3][1] == a31);
3448 1 : CATCH_REQUIRE(a[3][2] == a32);
3449 1 : CATCH_REQUIRE(a[3][3] == a33);
3450 :
3451 : // this can't fail because we ensure scalar != 0 or 1
3452 : //
3453 1 : CATCH_REQUIRE_FALSE(b[0][0] == b00);
3454 1 : CATCH_REQUIRE_FALSE(b[0][1] == b01);
3455 1 : CATCH_REQUIRE_FALSE(b[0][2] == b02);
3456 1 : CATCH_REQUIRE_FALSE(b[0][3] == b03);
3457 1 : CATCH_REQUIRE_FALSE(b[1][0] == b10);
3458 1 : CATCH_REQUIRE_FALSE(b[1][1] == b11);
3459 1 : CATCH_REQUIRE_FALSE(b[1][2] == b12);
3460 1 : CATCH_REQUIRE_FALSE(b[1][3] == b13);
3461 1 : CATCH_REQUIRE_FALSE(b[2][0] == b20);
3462 1 : CATCH_REQUIRE_FALSE(b[2][1] == b21);
3463 1 : CATCH_REQUIRE_FALSE(b[2][2] == b22);
3464 1 : CATCH_REQUIRE_FALSE(b[2][3] == b23);
3465 1 : CATCH_REQUIRE_FALSE(b[3][0] == b30);
3466 1 : CATCH_REQUIRE_FALSE(b[3][1] == b31);
3467 1 : CATCH_REQUIRE_FALSE(b[3][2] == b32);
3468 1 : CATCH_REQUIRE_FALSE(b[3][3] == b33);
3469 :
3470 1 : CATCH_REQUIRE(b[0][0] == a00 / scalar);
3471 1 : CATCH_REQUIRE(b[0][1] == a01 / scalar);
3472 1 : CATCH_REQUIRE(b[0][2] == a02 / scalar);
3473 1 : CATCH_REQUIRE(b[0][3] == a03 / scalar);
3474 1 : CATCH_REQUIRE(b[1][0] == a10 / scalar);
3475 1 : CATCH_REQUIRE(b[1][1] == a11 / scalar);
3476 1 : CATCH_REQUIRE(b[1][2] == a12 / scalar);
3477 1 : CATCH_REQUIRE(b[1][3] == a13 / scalar);
3478 1 : CATCH_REQUIRE(b[2][0] == a20 / scalar);
3479 1 : CATCH_REQUIRE(b[2][1] == a21 / scalar);
3480 1 : CATCH_REQUIRE(b[2][2] == a22 / scalar);
3481 1 : CATCH_REQUIRE(b[2][3] == a23 / scalar);
3482 1 : CATCH_REQUIRE(b[3][0] == a30 / scalar);
3483 1 : CATCH_REQUIRE(b[3][1] == a31 / scalar);
3484 1 : CATCH_REQUIRE(b[3][2] == a32 / scalar);
3485 1 : CATCH_REQUIRE(b[3][3] == a33 / scalar);
3486 : }
3487 : CATCH_END_SECTION()
3488 :
3489 8 : CATCH_START_SECTION("matrix: a/=<scalar>")
3490 : {
3491 : // setup A
3492 : //
3493 2 : snap::matrix<double> a(4, 4);
3494 :
3495 1 : CATCH_REQUIRE(a.rows() == 4);
3496 1 : CATCH_REQUIRE(a.columns() == 4);
3497 :
3498 1 : double const a00(frand());
3499 1 : double const a01(frand());
3500 1 : double const a02(frand());
3501 1 : double const a03(frand());
3502 1 : double const a10(frand());
3503 1 : double const a11(frand());
3504 1 : double const a12(frand());
3505 1 : double const a13(frand());
3506 1 : double const a20(frand());
3507 1 : double const a21(frand());
3508 1 : double const a22(frand());
3509 1 : double const a23(frand());
3510 1 : double const a30(frand());
3511 1 : double const a31(frand());
3512 1 : double const a32(frand());
3513 1 : double const a33(frand());
3514 :
3515 1 : a[0][0] = a00;
3516 1 : a[0][1] = a01;
3517 1 : a[0][2] = a02;
3518 1 : a[0][3] = a03;
3519 1 : a[1][0] = a10;
3520 1 : a[1][1] = a11;
3521 1 : a[1][2] = a12;
3522 1 : a[1][3] = a13;
3523 1 : a[2][0] = a20;
3524 1 : a[2][1] = a21;
3525 1 : a[2][2] = a22;
3526 1 : a[2][3] = a23;
3527 1 : a[3][0] = a30;
3528 1 : a[3][1] = a31;
3529 1 : a[3][2] = a32;
3530 1 : a[3][3] = a33;
3531 :
3532 1 : CATCH_REQUIRE(a[0][0] == a00);
3533 1 : CATCH_REQUIRE(a[0][1] == a01);
3534 1 : CATCH_REQUIRE(a[0][2] == a02);
3535 1 : CATCH_REQUIRE(a[0][3] == a03);
3536 1 : CATCH_REQUIRE(a[1][0] == a10);
3537 1 : CATCH_REQUIRE(a[1][1] == a11);
3538 1 : CATCH_REQUIRE(a[1][2] == a12);
3539 1 : CATCH_REQUIRE(a[1][3] == a13);
3540 1 : CATCH_REQUIRE(a[2][0] == a20);
3541 1 : CATCH_REQUIRE(a[2][1] == a21);
3542 1 : CATCH_REQUIRE(a[2][2] == a22);
3543 1 : CATCH_REQUIRE(a[2][3] == a23);
3544 1 : CATCH_REQUIRE(a[3][0] == a30);
3545 1 : CATCH_REQUIRE(a[3][1] == a31);
3546 1 : CATCH_REQUIRE(a[3][2] == a32);
3547 1 : CATCH_REQUIRE(a[3][3] == a33);
3548 :
3549 : // create a scalar for our test
3550 : //
3551 1 : double scalar(frand());
3552 1 : while(scalar == 0.0)
3553 : {
3554 0 : scalar = frand();
3555 : }
3556 :
3557 : // run operation A /= <scalar>
3558 : //
3559 1 : a /= scalar;
3560 :
3561 : // this can't fail because we ensure scalar != 0 or 1
3562 : //
3563 1 : CATCH_REQUIRE_FALSE(a[0][0] == a00);
3564 1 : CATCH_REQUIRE_FALSE(a[0][1] == a01);
3565 1 : CATCH_REQUIRE_FALSE(a[0][2] == a02);
3566 1 : CATCH_REQUIRE_FALSE(a[0][3] == a03);
3567 1 : CATCH_REQUIRE_FALSE(a[1][0] == a10);
3568 1 : CATCH_REQUIRE_FALSE(a[1][1] == a11);
3569 1 : CATCH_REQUIRE_FALSE(a[1][2] == a12);
3570 1 : CATCH_REQUIRE_FALSE(a[1][3] == a13);
3571 1 : CATCH_REQUIRE_FALSE(a[2][0] == a20);
3572 1 : CATCH_REQUIRE_FALSE(a[2][1] == a21);
3573 1 : CATCH_REQUIRE_FALSE(a[2][2] == a22);
3574 1 : CATCH_REQUIRE_FALSE(a[2][3] == a23);
3575 1 : CATCH_REQUIRE_FALSE(a[3][0] == a30);
3576 1 : CATCH_REQUIRE_FALSE(a[3][1] == a31);
3577 1 : CATCH_REQUIRE_FALSE(a[3][2] == a32);
3578 1 : CATCH_REQUIRE_FALSE(a[3][3] == a33);
3579 :
3580 1 : CATCH_REQUIRE(a[0][0] == a00 / scalar);
3581 1 : CATCH_REQUIRE(a[0][1] == a01 / scalar);
3582 1 : CATCH_REQUIRE(a[0][2] == a02 / scalar);
3583 1 : CATCH_REQUIRE(a[0][3] == a03 / scalar);
3584 1 : CATCH_REQUIRE(a[1][0] == a10 / scalar);
3585 1 : CATCH_REQUIRE(a[1][1] == a11 / scalar);
3586 1 : CATCH_REQUIRE(a[1][2] == a12 / scalar);
3587 1 : CATCH_REQUIRE(a[1][3] == a13 / scalar);
3588 1 : CATCH_REQUIRE(a[2][0] == a20 / scalar);
3589 1 : CATCH_REQUIRE(a[2][1] == a21 / scalar);
3590 1 : CATCH_REQUIRE(a[2][2] == a22 / scalar);
3591 1 : CATCH_REQUIRE(a[2][3] == a23 / scalar);
3592 1 : CATCH_REQUIRE(a[3][0] == a30 / scalar);
3593 1 : CATCH_REQUIRE(a[3][1] == a31 / scalar);
3594 1 : CATCH_REQUIRE(a[3][2] == a32 / scalar);
3595 1 : CATCH_REQUIRE(a[3][3] == a33 / scalar);
3596 : }
3597 : CATCH_END_SECTION()
3598 :
3599 8 : CATCH_START_SECTION("matrix: c=a/b")
3600 : {
3601 : // setup A
3602 : //
3603 2 : snap::matrix<double> a(4, 4);
3604 :
3605 1 : CATCH_REQUIRE(a.rows() == 4);
3606 1 : CATCH_REQUIRE(a.columns() == 4);
3607 :
3608 1 : double const a00(frand());
3609 1 : double const a01(frand());
3610 1 : double const a02(frand());
3611 1 : double const a03(frand());
3612 1 : double const a10(frand());
3613 1 : double const a11(frand());
3614 1 : double const a12(frand());
3615 1 : double const a13(frand());
3616 1 : double const a20(frand());
3617 1 : double const a21(frand());
3618 1 : double const a22(frand());
3619 1 : double const a23(frand());
3620 1 : double const a30(frand());
3621 1 : double const a31(frand());
3622 1 : double const a32(frand());
3623 1 : double const a33(frand());
3624 :
3625 1 : a[0][0] = a00;
3626 1 : a[0][1] = a01;
3627 1 : a[0][2] = a02;
3628 1 : a[0][3] = a03;
3629 1 : a[1][0] = a10;
3630 1 : a[1][1] = a11;
3631 1 : a[1][2] = a12;
3632 1 : a[1][3] = a13;
3633 1 : a[2][0] = a20;
3634 1 : a[2][1] = a21;
3635 1 : a[2][2] = a22;
3636 1 : a[2][3] = a23;
3637 1 : a[3][0] = a30;
3638 1 : a[3][1] = a31;
3639 1 : a[3][2] = a32;
3640 1 : a[3][3] = a33;
3641 :
3642 1 : CATCH_REQUIRE(a[0][0] == a00);
3643 1 : CATCH_REQUIRE(a[0][1] == a01);
3644 1 : CATCH_REQUIRE(a[0][2] == a02);
3645 1 : CATCH_REQUIRE(a[0][3] == a03);
3646 1 : CATCH_REQUIRE(a[1][0] == a10);
3647 1 : CATCH_REQUIRE(a[1][1] == a11);
3648 1 : CATCH_REQUIRE(a[1][2] == a12);
3649 1 : CATCH_REQUIRE(a[1][3] == a13);
3650 1 : CATCH_REQUIRE(a[2][0] == a20);
3651 1 : CATCH_REQUIRE(a[2][1] == a21);
3652 1 : CATCH_REQUIRE(a[2][2] == a22);
3653 1 : CATCH_REQUIRE(a[2][3] == a23);
3654 1 : CATCH_REQUIRE(a[3][0] == a30);
3655 1 : CATCH_REQUIRE(a[3][1] == a31);
3656 1 : CATCH_REQUIRE(a[3][2] == a32);
3657 1 : CATCH_REQUIRE(a[3][3] == a33);
3658 :
3659 : // setup B
3660 : //
3661 2 : snap::matrix<double> b(4, 4);
3662 :
3663 1 : CATCH_REQUIRE(b.rows() == 4);
3664 1 : CATCH_REQUIRE(b.columns() == 4);
3665 :
3666 : double b00;
3667 : double b01;
3668 : double b02;
3669 : double b03;
3670 : double b10;
3671 : double b11;
3672 : double b12;
3673 : double b13;
3674 : double b20;
3675 : double b21;
3676 : double b22;
3677 : double b23;
3678 : double b30;
3679 : double b31;
3680 : double b32;
3681 : double b33;
3682 :
3683 : // create an inversible matrix (most are with random numbers)
3684 2 : snap::matrix<double> t(4, 4);
3685 1 : do
3686 : {
3687 1 : b00 = frand();
3688 1 : b01 = frand();
3689 1 : b02 = frand();
3690 1 : b03 = frand();
3691 1 : b10 = frand();
3692 1 : b11 = frand();
3693 1 : b12 = frand();
3694 1 : b13 = frand();
3695 1 : b20 = frand();
3696 1 : b21 = frand();
3697 1 : b22 = frand();
3698 1 : b23 = frand();
3699 1 : b30 = frand();
3700 1 : b31 = frand();
3701 1 : b32 = frand();
3702 1 : b33 = frand();
3703 :
3704 1 : b[0][0] = b00;
3705 1 : b[0][1] = b01;
3706 1 : b[0][2] = b02;
3707 1 : b[0][3] = b03;
3708 1 : b[1][0] = b10;
3709 1 : b[1][1] = b11;
3710 1 : b[1][2] = b12;
3711 1 : b[1][3] = b13;
3712 1 : b[2][0] = b20;
3713 1 : b[2][1] = b21;
3714 1 : b[2][2] = b22;
3715 1 : b[2][3] = b23;
3716 1 : b[3][0] = b30;
3717 1 : b[3][1] = b31;
3718 1 : b[3][2] = b32;
3719 1 : b[3][3] = b33;
3720 :
3721 1 : CATCH_REQUIRE(b[0][0] == b00);
3722 1 : CATCH_REQUIRE(b[0][1] == b01);
3723 1 : CATCH_REQUIRE(b[0][2] == b02);
3724 1 : CATCH_REQUIRE(b[0][3] == b03);
3725 1 : CATCH_REQUIRE(b[1][0] == b10);
3726 1 : CATCH_REQUIRE(b[1][1] == b11);
3727 1 : CATCH_REQUIRE(b[1][2] == b12);
3728 1 : CATCH_REQUIRE(b[1][3] == b13);
3729 1 : CATCH_REQUIRE(b[2][0] == b20);
3730 1 : CATCH_REQUIRE(b[2][1] == b21);
3731 1 : CATCH_REQUIRE(b[2][2] == b22);
3732 1 : CATCH_REQUIRE(b[2][3] == b23);
3733 1 : CATCH_REQUIRE(b[3][0] == b30);
3734 1 : CATCH_REQUIRE(b[3][1] == b31);
3735 1 : CATCH_REQUIRE(b[3][2] == b32);
3736 1 : CATCH_REQUIRE(b[3][3] == b33);
3737 :
3738 1 : t = b;
3739 : }
3740 1 : while(!t.inverse());
3741 :
3742 : // setup C
3743 : //
3744 2 : snap::matrix<double> c(4, 4);
3745 :
3746 1 : CATCH_REQUIRE(c.rows() == 4);
3747 1 : CATCH_REQUIRE(c.columns() == 4);
3748 :
3749 1 : double const c00(frand());
3750 1 : double const c01(frand());
3751 1 : double const c02(frand());
3752 1 : double const c03(frand());
3753 1 : double const c10(frand());
3754 1 : double const c11(frand());
3755 1 : double const c12(frand());
3756 1 : double const c13(frand());
3757 1 : double const c20(frand());
3758 1 : double const c21(frand());
3759 1 : double const c22(frand());
3760 1 : double const c23(frand());
3761 1 : double const c30(frand());
3762 1 : double const c31(frand());
3763 1 : double const c32(frand());
3764 1 : double const c33(frand());
3765 :
3766 1 : c[0][0] = c00;
3767 1 : c[0][1] = c01;
3768 1 : c[0][2] = c02;
3769 1 : c[0][3] = c03;
3770 1 : c[1][0] = c10;
3771 1 : c[1][1] = c11;
3772 1 : c[1][2] = c12;
3773 1 : c[1][3] = c13;
3774 1 : c[2][0] = c20;
3775 1 : c[2][1] = c21;
3776 1 : c[2][2] = c22;
3777 1 : c[2][3] = c23;
3778 1 : c[3][0] = c30;
3779 1 : c[3][1] = c31;
3780 1 : c[3][2] = c32;
3781 1 : c[3][3] = c33;
3782 :
3783 1 : CATCH_REQUIRE(c[0][0] == c00);
3784 1 : CATCH_REQUIRE(c[0][1] == c01);
3785 1 : CATCH_REQUIRE(c[0][2] == c02);
3786 1 : CATCH_REQUIRE(c[0][3] == c03);
3787 1 : CATCH_REQUIRE(c[1][0] == c10);
3788 1 : CATCH_REQUIRE(c[1][1] == c11);
3789 1 : CATCH_REQUIRE(c[1][2] == c12);
3790 1 : CATCH_REQUIRE(c[1][3] == c13);
3791 1 : CATCH_REQUIRE(c[2][0] == c20);
3792 1 : CATCH_REQUIRE(c[2][1] == c21);
3793 1 : CATCH_REQUIRE(c[2][2] == c22);
3794 1 : CATCH_REQUIRE(c[2][3] == c23);
3795 1 : CATCH_REQUIRE(c[3][0] == c30);
3796 1 : CATCH_REQUIRE(c[3][1] == c31);
3797 1 : CATCH_REQUIRE(c[3][2] == c32);
3798 1 : CATCH_REQUIRE(c[3][3] == c33);
3799 :
3800 : // run operation C = A / B
3801 : //
3802 1 : c = a / b;
3803 :
3804 1 : CATCH_REQUIRE(a[0][0] == a00);
3805 1 : CATCH_REQUIRE(a[0][1] == a01);
3806 1 : CATCH_REQUIRE(a[0][2] == a02);
3807 1 : CATCH_REQUIRE(a[0][3] == a03);
3808 1 : CATCH_REQUIRE(a[1][0] == a10);
3809 1 : CATCH_REQUIRE(a[1][1] == a11);
3810 1 : CATCH_REQUIRE(a[1][2] == a12);
3811 1 : CATCH_REQUIRE(a[1][3] == a13);
3812 1 : CATCH_REQUIRE(a[2][0] == a20);
3813 1 : CATCH_REQUIRE(a[2][1] == a21);
3814 1 : CATCH_REQUIRE(a[2][2] == a22);
3815 1 : CATCH_REQUIRE(a[2][3] == a23);
3816 1 : CATCH_REQUIRE(a[3][0] == a30);
3817 1 : CATCH_REQUIRE(a[3][1] == a31);
3818 1 : CATCH_REQUIRE(a[3][2] == a32);
3819 1 : CATCH_REQUIRE(a[3][3] == a33);
3820 :
3821 1 : CATCH_REQUIRE(b[0][0] == b00);
3822 1 : CATCH_REQUIRE(b[0][1] == b01);
3823 1 : CATCH_REQUIRE(b[0][2] == b02);
3824 1 : CATCH_REQUIRE(b[0][3] == b03);
3825 1 : CATCH_REQUIRE(b[1][0] == b10);
3826 1 : CATCH_REQUIRE(b[1][1] == b11);
3827 1 : CATCH_REQUIRE(b[1][2] == b12);
3828 1 : CATCH_REQUIRE(b[1][3] == b13);
3829 1 : CATCH_REQUIRE(b[2][0] == b20);
3830 1 : CATCH_REQUIRE(b[2][1] == b21);
3831 1 : CATCH_REQUIRE(b[2][2] == b22);
3832 1 : CATCH_REQUIRE(b[2][3] == b23);
3833 1 : CATCH_REQUIRE(b[3][0] == b30);
3834 1 : CATCH_REQUIRE(b[3][1] == b31);
3835 1 : CATCH_REQUIRE(b[3][2] == b32);
3836 1 : CATCH_REQUIRE(b[3][3] == b33);
3837 :
3838 : // this could fail
3839 : //CATCH_REQUIRE_FALSE(c[0][0] == c00);
3840 : //CATCH_REQUIRE_FALSE(c[0][1] == c01);
3841 : //CATCH_REQUIRE_FALSE(c[0][2] == c02);
3842 : //CATCH_REQUIRE_FALSE(c[0][3] == c03);
3843 : //CATCH_REQUIRE_FALSE(c[1][0] == c10);
3844 : //CATCH_REQUIRE_FALSE(c[1][1] == c11);
3845 : //CATCH_REQUIRE_FALSE(c[1][2] == c12);
3846 : //CATCH_REQUIRE_FALSE(c[1][3] == c13);
3847 : //CATCH_REQUIRE_FALSE(c[2][0] == c20);
3848 : //CATCH_REQUIRE_FALSE(c[2][1] == c21);
3849 : //CATCH_REQUIRE_FALSE(c[2][2] == c22);
3850 : //CATCH_REQUIRE_FALSE(c[2][3] == c23);
3851 : //CATCH_REQUIRE_FALSE(c[3][0] == c30);
3852 : //CATCH_REQUIRE_FALSE(c[3][1] == c31);
3853 : //CATCH_REQUIRE_FALSE(c[3][2] == c32);
3854 : //CATCH_REQUIRE_FALSE(c[3][3] == c33);
3855 :
3856 : // first level verification, which is exactly what the
3857 : // division function does, it does not mean that the
3858 : // division works properly, though
3859 : //
3860 2 : snap::matrix<double> r(4, 4);
3861 1 : r = a * t;
3862 :
3863 1 : CATCH_REQUIRE(c[0][0] == r[0][0]);
3864 1 : CATCH_REQUIRE(c[0][1] == r[0][1]);
3865 1 : CATCH_REQUIRE(c[0][2] == r[0][2]);
3866 1 : CATCH_REQUIRE(c[0][3] == r[0][3]);
3867 1 : CATCH_REQUIRE(c[1][0] == r[1][0]);
3868 1 : CATCH_REQUIRE(c[1][1] == r[1][1]);
3869 1 : CATCH_REQUIRE(c[1][2] == r[1][2]);
3870 1 : CATCH_REQUIRE(c[1][3] == r[1][3]);
3871 1 : CATCH_REQUIRE(c[2][0] == r[2][0]);
3872 1 : CATCH_REQUIRE(c[2][1] == r[2][1]);
3873 1 : CATCH_REQUIRE(c[2][2] == r[2][2]);
3874 1 : CATCH_REQUIRE(c[2][3] == r[2][3]);
3875 1 : CATCH_REQUIRE(c[3][0] == r[3][0]);
3876 1 : CATCH_REQUIRE(c[3][1] == r[3][1]);
3877 1 : CATCH_REQUIRE(c[3][2] == r[3][2]);
3878 1 : CATCH_REQUIRE(c[3][3] == r[3][3]);
3879 :
3880 1 : double const determinant(b.determinant());
3881 2 : snap::matrix<double> adjugate(b.adjugate());
3882 :
3883 2 : snap::matrix<double> inv(adjugate * (1.0 / determinant));
3884 2 : snap::matrix<double> div(a * inv);
3885 :
3886 1 : CATCH_REQUIRE(fabs(c[0][0] - div[0][0]) < 0.0001);
3887 1 : CATCH_REQUIRE(fabs(c[0][1] - div[0][1]) < 0.0001);
3888 1 : CATCH_REQUIRE(fabs(c[0][2] - div[0][2]) < 0.0001);
3889 1 : CATCH_REQUIRE(fabs(c[0][3] - div[0][3]) < 0.0001);
3890 1 : CATCH_REQUIRE(fabs(c[1][0] - div[1][0]) < 0.0001);
3891 1 : CATCH_REQUIRE(fabs(c[1][1] - div[1][1]) < 0.0001);
3892 1 : CATCH_REQUIRE(fabs(c[1][2] - div[1][2]) < 0.0001);
3893 1 : CATCH_REQUIRE(fabs(c[1][3] - div[1][3]) < 0.0001);
3894 1 : CATCH_REQUIRE(fabs(c[2][0] - div[2][0]) < 0.0001);
3895 1 : CATCH_REQUIRE(fabs(c[2][1] - div[2][1]) < 0.0001);
3896 1 : CATCH_REQUIRE(fabs(c[2][2] - div[2][2]) < 0.0001);
3897 1 : CATCH_REQUIRE(fabs(c[2][3] - div[2][3]) < 0.0001);
3898 1 : CATCH_REQUIRE(fabs(c[3][0] - div[3][0]) < 0.0001);
3899 1 : CATCH_REQUIRE(fabs(c[3][1] - div[3][1]) < 0.0001);
3900 1 : CATCH_REQUIRE(fabs(c[3][2] - div[3][2]) < 0.0001);
3901 1 : CATCH_REQUIRE(fabs(c[3][3] - div[3][3]) < 0.0001);
3902 : }
3903 : CATCH_END_SECTION()
3904 :
3905 8 : CATCH_START_SECTION("matrix: a/=b")
3906 : {
3907 : // setup A
3908 : //
3909 2 : snap::matrix<double> a(4, 4);
3910 :
3911 1 : CATCH_REQUIRE(a.rows() == 4);
3912 1 : CATCH_REQUIRE(a.columns() == 4);
3913 :
3914 1 : double const a00(frand());
3915 1 : double const a01(frand());
3916 1 : double const a02(frand());
3917 1 : double const a03(frand());
3918 1 : double const a10(frand());
3919 1 : double const a11(frand());
3920 1 : double const a12(frand());
3921 1 : double const a13(frand());
3922 1 : double const a20(frand());
3923 1 : double const a21(frand());
3924 1 : double const a22(frand());
3925 1 : double const a23(frand());
3926 1 : double const a30(frand());
3927 1 : double const a31(frand());
3928 1 : double const a32(frand());
3929 1 : double const a33(frand());
3930 :
3931 1 : a[0][0] = a00;
3932 1 : a[0][1] = a01;
3933 1 : a[0][2] = a02;
3934 1 : a[0][3] = a03;
3935 1 : a[1][0] = a10;
3936 1 : a[1][1] = a11;
3937 1 : a[1][2] = a12;
3938 1 : a[1][3] = a13;
3939 1 : a[2][0] = a20;
3940 1 : a[2][1] = a21;
3941 1 : a[2][2] = a22;
3942 1 : a[2][3] = a23;
3943 1 : a[3][0] = a30;
3944 1 : a[3][1] = a31;
3945 1 : a[3][2] = a32;
3946 1 : a[3][3] = a33;
3947 :
3948 1 : CATCH_REQUIRE(a[0][0] == a00);
3949 1 : CATCH_REQUIRE(a[0][1] == a01);
3950 1 : CATCH_REQUIRE(a[0][2] == a02);
3951 1 : CATCH_REQUIRE(a[0][3] == a03);
3952 1 : CATCH_REQUIRE(a[1][0] == a10);
3953 1 : CATCH_REQUIRE(a[1][1] == a11);
3954 1 : CATCH_REQUIRE(a[1][2] == a12);
3955 1 : CATCH_REQUIRE(a[1][3] == a13);
3956 1 : CATCH_REQUIRE(a[2][0] == a20);
3957 1 : CATCH_REQUIRE(a[2][1] == a21);
3958 1 : CATCH_REQUIRE(a[2][2] == a22);
3959 1 : CATCH_REQUIRE(a[2][3] == a23);
3960 1 : CATCH_REQUIRE(a[3][0] == a30);
3961 1 : CATCH_REQUIRE(a[3][1] == a31);
3962 1 : CATCH_REQUIRE(a[3][2] == a32);
3963 1 : CATCH_REQUIRE(a[3][3] == a33);
3964 :
3965 : // setup B
3966 : //
3967 2 : snap::matrix<double> b(4, 4);
3968 :
3969 1 : CATCH_REQUIRE(b.rows() == 4);
3970 1 : CATCH_REQUIRE(b.columns() == 4);
3971 :
3972 1 : double const b00(frand());
3973 1 : double const b01(frand());
3974 1 : double const b02(frand());
3975 1 : double const b03(frand());
3976 1 : double const b10(frand());
3977 1 : double const b11(frand());
3978 1 : double const b12(frand());
3979 1 : double const b13(frand());
3980 1 : double const b20(frand());
3981 1 : double const b21(frand());
3982 1 : double const b22(frand());
3983 1 : double const b23(frand());
3984 1 : double const b30(frand());
3985 1 : double const b31(frand());
3986 1 : double const b32(frand());
3987 1 : double const b33(frand());
3988 :
3989 1 : b[0][0] = b00;
3990 1 : b[0][1] = b01;
3991 1 : b[0][2] = b02;
3992 1 : b[0][3] = b03;
3993 1 : b[1][0] = b10;
3994 1 : b[1][1] = b11;
3995 1 : b[1][2] = b12;
3996 1 : b[1][3] = b13;
3997 1 : b[2][0] = b20;
3998 1 : b[2][1] = b21;
3999 1 : b[2][2] = b22;
4000 1 : b[2][3] = b23;
4001 1 : b[3][0] = b30;
4002 1 : b[3][1] = b31;
4003 1 : b[3][2] = b32;
4004 1 : b[3][3] = b33;
4005 :
4006 1 : CATCH_REQUIRE(b[0][0] == b00);
4007 1 : CATCH_REQUIRE(b[0][1] == b01);
4008 1 : CATCH_REQUIRE(b[0][2] == b02);
4009 1 : CATCH_REQUIRE(b[0][3] == b03);
4010 1 : CATCH_REQUIRE(b[1][0] == b10);
4011 1 : CATCH_REQUIRE(b[1][1] == b11);
4012 1 : CATCH_REQUIRE(b[1][2] == b12);
4013 1 : CATCH_REQUIRE(b[1][3] == b13);
4014 1 : CATCH_REQUIRE(b[2][0] == b20);
4015 1 : CATCH_REQUIRE(b[2][1] == b21);
4016 1 : CATCH_REQUIRE(b[2][2] == b22);
4017 1 : CATCH_REQUIRE(b[2][3] == b23);
4018 1 : CATCH_REQUIRE(b[3][0] == b30);
4019 1 : CATCH_REQUIRE(b[3][1] == b31);
4020 1 : CATCH_REQUIRE(b[3][2] == b32);
4021 1 : CATCH_REQUIRE(b[3][3] == b33);
4022 :
4023 1 : double const determinant(b.determinant());
4024 2 : snap::matrix<double> adjugate(b.adjugate());
4025 :
4026 2 : snap::matrix<double> inv(adjugate * (1.0 / determinant));
4027 2 : snap::matrix<double> div(a * inv);
4028 :
4029 : // run operation A /= B
4030 : //
4031 1 : a /= b;
4032 :
4033 : // this could fail if one of bXX is 0.0
4034 : //
4035 : //CATCH_REQUIRE(a[0][0] == a00);
4036 : //CATCH_REQUIRE(a[0][1] == a01);
4037 : //CATCH_REQUIRE(a[0][2] == a02);
4038 : //CATCH_REQUIRE(a[0][3] == a03);
4039 : //CATCH_REQUIRE(a[1][0] == a10);
4040 : //CATCH_REQUIRE(a[1][1] == a11);
4041 : //CATCH_REQUIRE(a[1][2] == a12);
4042 : //CATCH_REQUIRE(a[1][3] == a13);
4043 : //CATCH_REQUIRE(a[2][0] == a20);
4044 : //CATCH_REQUIRE(a[2][1] == a21);
4045 : //CATCH_REQUIRE(a[2][2] == a22);
4046 : //CATCH_REQUIRE(a[2][3] == a23);
4047 : //CATCH_REQUIRE(a[3][0] == a30);
4048 : //CATCH_REQUIRE(a[3][1] == a31);
4049 : //CATCH_REQUIRE(a[3][2] == a32);
4050 : //CATCH_REQUIRE(a[3][3] == a33);
4051 :
4052 1 : CATCH_REQUIRE(b[0][0] == b00);
4053 1 : CATCH_REQUIRE(b[0][1] == b01);
4054 1 : CATCH_REQUIRE(b[0][2] == b02);
4055 1 : CATCH_REQUIRE(b[0][3] == b03);
4056 1 : CATCH_REQUIRE(b[1][0] == b10);
4057 1 : CATCH_REQUIRE(b[1][1] == b11);
4058 1 : CATCH_REQUIRE(b[1][2] == b12);
4059 1 : CATCH_REQUIRE(b[1][3] == b13);
4060 1 : CATCH_REQUIRE(b[2][0] == b20);
4061 1 : CATCH_REQUIRE(b[2][1] == b21);
4062 1 : CATCH_REQUIRE(b[2][2] == b22);
4063 1 : CATCH_REQUIRE(b[2][3] == b23);
4064 1 : CATCH_REQUIRE(b[3][0] == b30);
4065 1 : CATCH_REQUIRE(b[3][1] == b31);
4066 1 : CATCH_REQUIRE(b[3][2] == b32);
4067 1 : CATCH_REQUIRE(b[3][3] == b33);
4068 :
4069 1 : CATCH_REQUIRE(fabs(a[0][0] - div[0][0]) < 0.0001);
4070 1 : CATCH_REQUIRE(fabs(a[0][1] - div[0][1]) < 0.0001);
4071 1 : CATCH_REQUIRE(fabs(a[0][2] - div[0][2]) < 0.0001);
4072 1 : CATCH_REQUIRE(fabs(a[0][3] - div[0][3]) < 0.0001);
4073 1 : CATCH_REQUIRE(fabs(a[1][0] - div[1][0]) < 0.0001);
4074 1 : CATCH_REQUIRE(fabs(a[1][1] - div[1][1]) < 0.0001);
4075 1 : CATCH_REQUIRE(fabs(a[1][2] - div[1][2]) < 0.0001);
4076 1 : CATCH_REQUIRE(fabs(a[1][3] - div[1][3]) < 0.0001);
4077 1 : CATCH_REQUIRE(fabs(a[2][0] - div[2][0]) < 0.0001);
4078 1 : CATCH_REQUIRE(fabs(a[2][1] - div[2][1]) < 0.0001);
4079 1 : CATCH_REQUIRE(fabs(a[2][2] - div[2][2]) < 0.0001);
4080 1 : CATCH_REQUIRE(fabs(a[2][3] - div[2][3]) < 0.0001);
4081 1 : CATCH_REQUIRE(fabs(a[3][0] - div[3][0]) < 0.0001);
4082 1 : CATCH_REQUIRE(fabs(a[3][1] - div[3][1]) < 0.0001);
4083 1 : CATCH_REQUIRE(fabs(a[3][2] - div[3][2]) < 0.0001);
4084 1 : CATCH_REQUIRE(fabs(a[3][3] - div[3][3]) < 0.0001);
4085 : }
4086 : CATCH_END_SECTION()
4087 : }
4088 8 : }
4089 :
4090 :
4091 5 : CATCH_TEST_CASE("matrix_color", "[matrix]")
4092 : {
4093 : // generate a few brightness matrices
4094 : //
4095 6 : CATCH_GIVEN("brightness")
4096 : {
4097 2 : CATCH_START_SECTION("matrix: b=a*<brightness> (a is identity)")
4098 : {
4099 : // setup A
4100 : //
4101 2 : snap::matrix<double> a(4, 4);
4102 :
4103 1 : CATCH_REQUIRE(a.rows() == 4);
4104 1 : CATCH_REQUIRE(a.columns() == 4);
4105 :
4106 : // setup B
4107 : //
4108 2 : snap::matrix<double> b(4, 4);
4109 :
4110 1 : CATCH_REQUIRE(b.rows() == 4);
4111 1 : CATCH_REQUIRE(b.columns() == 4);
4112 :
4113 1001 : for(int idx(0); idx < 1000; ++idx)
4114 : {
4115 1000 : double const brightness(static_cast<double>(idx) / 1000.0);
4116 1000 : b = a.brightness(brightness);
4117 :
4118 1000 : CATCH_REQUIRE(fabs(b[0][0] - brightness) < 0.0001);
4119 1000 : CATCH_REQUIRE(fabs(b[0][1] - 0.0) < 0.0001);
4120 1000 : CATCH_REQUIRE(fabs(b[0][2] - 0.0) < 0.0001);
4121 1000 : CATCH_REQUIRE(fabs(b[0][3] - 0.0) < 0.0001);
4122 1000 : CATCH_REQUIRE(fabs(b[1][0] - 0.0) < 0.0001);
4123 1000 : CATCH_REQUIRE(fabs(b[1][1] - brightness) < 0.0001);
4124 1000 : CATCH_REQUIRE(fabs(b[1][2] - 0.0) < 0.0001);
4125 1000 : CATCH_REQUIRE(fabs(b[1][3] - 0.0) < 0.0001);
4126 1000 : CATCH_REQUIRE(fabs(b[2][0] - 0.0) < 0.0001);
4127 1000 : CATCH_REQUIRE(fabs(b[2][1] - 0.0) < 0.0001);
4128 1000 : CATCH_REQUIRE(fabs(b[2][2] - brightness) < 0.0001);
4129 1000 : CATCH_REQUIRE(fabs(b[2][3] - 0.0) < 0.0001);
4130 1000 : CATCH_REQUIRE(fabs(b[3][0] - 0.0) < 0.0001);
4131 1000 : CATCH_REQUIRE(fabs(b[3][1] - 0.0) < 0.0001);
4132 1000 : CATCH_REQUIRE(fabs(b[3][2] - 0.0) < 0.0001);
4133 1000 : CATCH_REQUIRE(fabs(b[3][3] - 1.0) < 0.0001);
4134 :
4135 : // * brightness_r & 0 & 0 & 0
4136 : // * \\ 0 & brightness_g & 0 & 0
4137 : // * \\ 0 & 0 & brightness_b & 0
4138 : // * \\ 0 & 0 & 0 & 1
4139 :
4140 : }
4141 : }
4142 : CATCH_END_SECTION()
4143 : }
4144 :
4145 : // generate a few saturation matrices
4146 : //
4147 6 : CATCH_GIVEN("saturation")
4148 : {
4149 2 : CATCH_START_SECTION("matrix: b=a*<saturation> (a is identity)")
4150 : {
4151 : // setup A
4152 : //
4153 2 : snap::matrix<double> a(4, 4);
4154 :
4155 1 : CATCH_REQUIRE(a.rows() == 4);
4156 1 : CATCH_REQUIRE(a.columns() == 4);
4157 :
4158 : // setup B
4159 : //
4160 2 : snap::matrix<double> b(4, 4);
4161 :
4162 1 : CATCH_REQUIRE(b.rows() == 4);
4163 1 : CATCH_REQUIRE(b.columns() == 4);
4164 :
4165 : double luma[6][3];
4166 :
4167 1 : luma[0][0] = a.HDTV_LUMA_RED ;
4168 1 : luma[0][1] = a.HDTV_LUMA_GREEN;
4169 1 : luma[0][2] = a.HDTV_LUMA_BLUE ;
4170 :
4171 1 : luma[1][0] = a.LED_LUMA_RED ;
4172 1 : luma[1][1] = a.LED_LUMA_GREEN;
4173 1 : luma[1][2] = a.LED_LUMA_BLUE ;
4174 :
4175 1 : luma[2][0] = a.CRT_LUMA_RED ;
4176 1 : luma[2][1] = a.CRT_LUMA_GREEN;
4177 1 : luma[2][2] = a.CRT_LUMA_BLUE ;
4178 :
4179 1 : luma[3][0] = a.NTSC_LUMA_RED ;
4180 1 : luma[3][1] = a.NTSC_LUMA_GREEN;
4181 1 : luma[3][2] = a.NTSC_LUMA_BLUE ;
4182 :
4183 1 : luma[4][0] = a.AVERAGE_LUMA_RED ;
4184 1 : luma[4][1] = a.AVERAGE_LUMA_GREEN;
4185 1 : luma[4][2] = a.AVERAGE_LUMA_BLUE ;
4186 :
4187 1 : luma[5][0] = 0.2; // to test any dynamic version if such exists for this algorithm
4188 1 : luma[5][1] = 0.7;
4189 1 : luma[5][2] = 0.1;
4190 :
4191 7 : for(int l(0); l < 6; ++l)
4192 : {
4193 : // set the luma weights
4194 : //
4195 6 : a.set_luma_vector(luma[l][0], luma[l][1], luma[l][2]);
4196 :
4197 6006 : for(int idx(0); idx < 1000; ++idx)
4198 : {
4199 6000 : double const s(static_cast<double>(idx) / 1000.0);
4200 6000 : b = a.saturation(s);
4201 :
4202 6000 : CATCH_REQUIRE(fabs(b[0][0] - (luma[l][0] * (1.0 - s) + s)) < 0.0001);
4203 6000 : CATCH_REQUIRE(fabs(b[0][1] - (luma[l][0] * (1.0 - s))) < 0.0001);
4204 6000 : CATCH_REQUIRE(fabs(b[0][2] - (luma[l][0] * (1.0 - s))) < 0.0001);
4205 6000 : CATCH_REQUIRE(fabs(b[0][3] - (0.0)) < 0.0001);
4206 6000 : CATCH_REQUIRE(fabs(b[1][0] - (luma[l][1] * (1.0 - s))) < 0.0001);
4207 6000 : CATCH_REQUIRE(fabs(b[1][1] - (luma[l][1] * (1.0 - s) + s)) < 0.0001);
4208 6000 : CATCH_REQUIRE(fabs(b[1][2] - (luma[l][1] * (1.0 - s))) < 0.0001);
4209 6000 : CATCH_REQUIRE(fabs(b[1][3] - (0.0)) < 0.0001);
4210 6000 : CATCH_REQUIRE(fabs(b[2][0] - (luma[l][2] * (1.0 - s))) < 0.0001);
4211 6000 : CATCH_REQUIRE(fabs(b[2][1] - (luma[l][2] * (1.0 - s))) < 0.0001);
4212 6000 : CATCH_REQUIRE(fabs(b[2][2] - (luma[l][2] * (1.0 - s) + s)) < 0.0001);
4213 6000 : CATCH_REQUIRE(fabs(b[2][3] - (0.0)) < 0.0001);
4214 6000 : CATCH_REQUIRE(fabs(b[3][0] - (0.0)) < 0.0001);
4215 6000 : CATCH_REQUIRE(fabs(b[3][1] - (0.0)) < 0.0001);
4216 6000 : CATCH_REQUIRE(fabs(b[3][2] - (0.0)) < 0.0001);
4217 6000 : CATCH_REQUIRE(fabs(b[3][3] - (1.0)) < 0.0001);
4218 : }
4219 : }
4220 : }
4221 : CATCH_END_SECTION()
4222 : }
4223 :
4224 : // generate a few brightness matrices
4225 : //
4226 6 : CATCH_GIVEN("hue")
4227 : {
4228 2 : CATCH_START_SECTION("matrix: b=a*<hue> (a is identity)")
4229 : {
4230 : // setup A
4231 : //
4232 2 : snap::matrix<double> a(4, 4);
4233 :
4234 1 : CATCH_REQUIRE(a.rows() == 4);
4235 1 : CATCH_REQUIRE(a.columns() == 4);
4236 :
4237 : // setup B
4238 : //
4239 2 : snap::matrix<double> b(4, 4);
4240 :
4241 1 : CATCH_REQUIRE(b.rows() == 4);
4242 1 : CATCH_REQUIRE(b.columns() == 4);
4243 :
4244 : double luma[6][3];
4245 :
4246 1 : luma[0][0] = a.HDTV_LUMA_RED ;
4247 1 : luma[0][1] = a.HDTV_LUMA_GREEN;
4248 1 : luma[0][2] = a.HDTV_LUMA_BLUE ;
4249 :
4250 1 : luma[1][0] = a.LED_LUMA_RED ;
4251 1 : luma[1][1] = a.LED_LUMA_GREEN;
4252 1 : luma[1][2] = a.LED_LUMA_BLUE ;
4253 :
4254 1 : luma[2][0] = a.CRT_LUMA_RED ;
4255 1 : luma[2][1] = a.CRT_LUMA_GREEN;
4256 1 : luma[2][2] = a.CRT_LUMA_BLUE ;
4257 :
4258 1 : luma[3][0] = a.NTSC_LUMA_RED ;
4259 1 : luma[3][1] = a.NTSC_LUMA_GREEN;
4260 1 : luma[3][2] = a.NTSC_LUMA_BLUE ;
4261 :
4262 1 : luma[4][0] = a.AVERAGE_LUMA_RED ;
4263 1 : luma[4][1] = a.AVERAGE_LUMA_GREEN;
4264 1 : luma[4][2] = a.AVERAGE_LUMA_BLUE ;
4265 :
4266 1 : luma[5][0] = 0.2; // to test any dynamic version if such exists for this algorithm
4267 1 : luma[5][1] = 0.7;
4268 1 : luma[5][2] = 0.1;
4269 :
4270 : std::vector<std::string> last_hue_matrix{
4271 : "hdtv",
4272 : "led",
4273 : "crt",
4274 : "ntsc",
4275 : "average",
4276 : "dynamic"
4277 2 : };
4278 :
4279 7 : for(int l(0); l < 6; ++l)
4280 : {
4281 : // set the luma weights
4282 : //
4283 6 : a.set_luma_vector(luma[l][0], luma[l][1], luma[l][2]);
4284 :
4285 : //std::cerr << "*** working on luma " << l << "\n";
4286 6006 : for(int idx(0); idx < 1000; ++idx)
4287 : {
4288 : // hue is an angle from 0 to 360 (albeit in radian)
4289 : //
4290 6000 : double const hue(static_cast<double>(idx) / 1000.0 * M_PI * 2.0);
4291 6000 : b = a.hue(hue);
4292 :
4293 : #ifdef _DEBUG
4294 6000 : CATCH_REQUIRE(a.get_last_hue_matrix() == last_hue_matrix[l]);
4295 : #endif
4296 :
4297 : // this one requires us to work!
4298 : // here we calculate the hue matrix by hand instead of using
4299 : // pre-calculated numbers; that way we know we have it right
4300 : //
4301 :
4302 : // $R_r$ (red rotation)
4303 : //
4304 12000 : snap::matrix<double> r_r(4, 4);
4305 6000 : r_r[1][1] = 1.0 / sqrt(2.0);
4306 6000 : r_r[1][2] = 1.0 / sqrt(2.0);
4307 6000 : r_r[2][1] = -1.0 / sqrt(2.0);
4308 6000 : r_r[2][2] = 1.0 / sqrt(2.0);
4309 :
4310 : // $R_g$ (green rotation)
4311 : //
4312 12000 : snap::matrix<double> r_g(4, 4);
4313 6000 : r_g[0][0] = sqrt(2.0) / sqrt(3.0);
4314 6000 : r_g[0][2] = 1.0 / sqrt(3.0);
4315 6000 : r_g[2][0] = -1.0 / sqrt(3.0);
4316 6000 : r_g[2][2] = sqrt(2.0) / sqrt(3.0);
4317 :
4318 : // $R_rg = R_r R_g$ (red and green rotations combined)
4319 : //
4320 12000 : snap::matrix<double> r_rg(r_r * r_g);
4321 :
4322 : // $w$ (luma vector, a.k.a. color weights to calcalute the perfect grayscale for your monitor)
4323 : //
4324 12000 : snap::matrix<double> w(a.get_luma_vector());
4325 : //w[0][0] = a.RED_WEIGHT;
4326 : //w[1][0] = a.GREEN_WEIGHT;
4327 : //w[2][0] = a.BLUE_WEIGHT;
4328 : //w[3][0] = 0;
4329 :
4330 : // sm (skew matrix)
4331 : //
4332 12000 : snap::matrix<double> sm(r_rg * w);
4333 :
4334 : // s (scaling with skew matrix)
4335 : //
4336 12000 : snap::matrix<double> s(4, 4);
4337 6000 : s[0][2] = sm[0][0] / sm[2][0];
4338 6000 : s[1][2] = sm[1][0] / sm[2][0];
4339 :
4340 : // p (skewed red & green rotation)
4341 : //
4342 12000 : snap::matrix<double> p(r_rg);
4343 6000 : p *= s;
4344 :
4345 : // r_b (blue rotation)
4346 : //
4347 12000 : snap::matrix<double> r_b(4, 4);
4348 6000 : double const rot_cos(cos(hue));
4349 6000 : double const rot_sin(sin(hue));
4350 6000 : r_b[0][0] = rot_cos;
4351 6000 : r_b[0][1] = rot_sin;
4352 6000 : r_b[1][0] = -rot_sin;
4353 6000 : r_b[1][1] = rot_cos;
4354 :
4355 : // hue_matrix (the resulting matrix depending on angle)
4356 : //
4357 12000 : snap::matrix<double> hue_matrix(p * r_b / p);
4358 :
4359 : //std::cout << "Got b = " << b << "\n";
4360 : //std::cout << "Got our hue matrix = " << hue_matrix << "\n";
4361 :
4362 6000 : CATCH_REQUIRE(fabs(b[0][0] - hue_matrix[0][0]) < 0.0001);
4363 6000 : CATCH_REQUIRE(fabs(b[0][1] - hue_matrix[0][1]) < 0.0001);
4364 6000 : CATCH_REQUIRE(fabs(b[0][2] - hue_matrix[0][2]) < 0.0001);
4365 6000 : CATCH_REQUIRE(fabs(b[0][3] - hue_matrix[0][3]) < 0.0001);
4366 6000 : CATCH_REQUIRE(fabs(b[1][0] - hue_matrix[1][0]) < 0.0001);
4367 6000 : CATCH_REQUIRE(fabs(b[1][1] - hue_matrix[1][1]) < 0.0001);
4368 6000 : CATCH_REQUIRE(fabs(b[1][2] - hue_matrix[1][2]) < 0.0001);
4369 6000 : CATCH_REQUIRE(fabs(b[1][3] - hue_matrix[1][3]) < 0.0001);
4370 6000 : CATCH_REQUIRE(fabs(b[2][0] - hue_matrix[2][0]) < 0.0001);
4371 6000 : CATCH_REQUIRE(fabs(b[2][1] - hue_matrix[2][1]) < 0.0001);
4372 6000 : CATCH_REQUIRE(fabs(b[2][2] - hue_matrix[2][2]) < 0.0001);
4373 6000 : CATCH_REQUIRE(fabs(b[2][3] - hue_matrix[2][3]) < 0.0001);
4374 6000 : CATCH_REQUIRE(fabs(b[3][0] - hue_matrix[3][0]) < 0.0001);
4375 6000 : CATCH_REQUIRE(fabs(b[3][1] - hue_matrix[3][1]) < 0.0001);
4376 6000 : CATCH_REQUIRE(fabs(b[3][2] - hue_matrix[3][2]) < 0.0001);
4377 6000 : CATCH_REQUIRE(fabs(b[3][3] - hue_matrix[3][3]) < 0.0001);
4378 :
4379 : // * $$
4380 : // * R_r =
4381 : // * \begin{bmatrix}
4382 : // * 1 & 0 & 0 & 0
4383 : // * \\ 0 & {1 \over \sqrt 2 } & {1 \over \sqrt 2 } & 0
4384 : // * \\ 0 & -{1 \over \sqrt 2 } & {1 \over \sqrt 2 } & 0
4385 : // * \\ 0 & 0 & 0 & 1
4386 : // * \end{bmatrix}
4387 : // * $$
4388 : // *
4389 : // * $$
4390 : // * R_g =
4391 : // * \begin{bmatrix}
4392 : // * 1 & 0 & 0 & 0
4393 : // * \\ 0 & {\sqrt 2 \over \sqrt 3} & -{1 \over \sqrt 3} & 0
4394 : // * \\ 0 & {1 \over \sqrt 3} & {\sqrt 2 \over \sqrt 3} & 0
4395 : // * \\ 0 & 0 & 0 & 1
4396 : // * \end{bmatrix}
4397 : // * $$
4398 : // *
4399 : // * $$
4400 : // * R_{rg} = R_r R_g
4401 : // * $$
4402 : // *
4403 : // * $$
4404 : // * \begin{bmatrix}
4405 : // * L_r
4406 : // * \\ L_g
4407 : // * \\ L_b
4408 : // * \\ 0
4409 : // * \end{bmatrix}
4410 : // * =
4411 : // * R_{rg}
4412 : // * \begin{bmatrix}
4413 : // * W_r
4414 : // * \\ W_g
4415 : // * \\ W_b
4416 : // * \\ 0
4417 : // * \end{bmatrix}
4418 : // * $$
4419 : // *
4420 : // * Now we define a rotation matrix for the blue axis. This one uses
4421 : // * a variable as the angle. This is the actual rotation angle which
4422 : // * can go from 0 to $2 \pi$:
4423 : // *
4424 : // * $$
4425 : // * R_b =
4426 : // * \begin{bmatrix}
4427 : // * cos( \theta ) & sin( \theta ) & 0 & 0
4428 : // * \\ -sin( \theta ) & cos( \theta ) & 0 & 0
4429 : // * \\ 0 & 0 & 1 & 0
4430 : // * \\ 0 & 0 & 0 & 1
4431 : // * \end{bmatrix}
4432 : // * $$
4433 : // *
4434 : // * Now we have all the matrices to caculate the hue rotation
4435 : // * of all the components of an image:
4436 : // *
4437 : // * $$
4438 : // * H = R_{rg} S R_b S^{-1} R_{rg}^{-1}
4439 : // * $$
4440 : // *
4441 : // * $H$ can then be used as in:
4442 : // *
4443 : // * $$
4444 : // * \begin{bmatrix}
4445 : // * R'
4446 : // * \\ G'
4447 : // * \\ B'
4448 : // * \end{bmatrix}
4449 : // * =
4450 : // * H
4451 : // * \begin{bmatrix}
4452 : // * R
4453 : // * \\ G
4454 : // * \\ B
4455 : // * \end{bmatrix}
4456 : // * $$
4457 : // *
4458 : }
4459 : }
4460 : }
4461 : CATCH_END_SECTION()
4462 : }
4463 9 : }
4464 :
4465 :
4466 : // vim: ts=4 sw=4 et
|