1 // Copyright (C) 2006  Davis E. King (davis@dlib.net)
2 // License: Boost Software License   See LICENSE.txt for the full license.
3 
4 
5 #include <dlib/matrix.h>
6 #include <sstream>
7 #include <string>
8 #include <cstdlib>
9 #include <ctime>
10 #include <vector>
11 #include "../stl_checked.h"
12 #include "../array.h"
13 #include "../rand.h"
14 
15 #include "tester.h"
16 #include <dlib/memory_manager_stateless.h>
17 #include <dlib/array2d.h>
18 
19 namespace
20 {
21 
22     using namespace test;
23     using namespace dlib;
24     using namespace std;
25 
26     logger dlog("test.matrix2");
27 
28     dlib::rand rnd;
29 
matrix_test1()30     void matrix_test1 (
31     )
32     {
33         typedef memory_manager_stateless<char>::kernel_2_2a MM;
34         print_spinner();
35 
36         const double ident[] = {
37             1, 0, 0, 0,
38             0, 1, 0, 0,
39             0, 0, 1, 0,
40             0, 0, 0, 1 };
41 
42         const double uniform3[] = {
43             3, 3, 3, 3,
44             3, 3, 3, 3,
45             3, 3, 3, 3,
46             3, 3, 3, 3
47         };
48 
49         const double uniform1[] = {
50             1, 1, 1, 1,
51             1, 1, 1, 1,
52             1, 1, 1, 1,
53             1, 1, 1, 1
54         };
55 
56         const double uniform0[] = {
57             0, 0, 0, 0,
58             0, 0, 0, 0,
59             0, 0, 0, 0,
60             0, 0, 0, 0
61         };
62 
63         const int array[] = {
64             42, 58, 9, 1,
65             9, 5, 8, 2,
66             98, 28, 4, 77,
67             9, 2, 44, 88 };
68 
69         const int array2[] = {
70             1, 22, 3,
71             4, 52, 6,
72             7, 8, 9 };
73 
74         const int array2_r[] = {
75             52, 6, 4,
76             8, 9, 7,
77             22, 3, 1
78         };
79 
80         const double array_f[] = {
81             -0.99,
82             0.99};
83 
84 
85         matrix<double,2,1,MM> fm(array_f);
86 
87         DLIB_TEST(fm.size() == 2);
88         matrix<double> dfm(fm);
89         DLIB_TEST(round(fm)(0) == -1);
90         DLIB_TEST(round(fm)(1) == 1);
91         DLIB_TEST(round(dfm)(0) == -1);
92         DLIB_TEST(round(dfm)(1) == 1);
93         DLIB_TEST(round(dfm).size() == dfm.size());
94 
95 
96         const int array3[] = { 1, 2, 3, 4 };
97 
98         matrix<double,3,3,MM> m3(array2);
99         matrix<double> dm3;
100         DLIB_TEST(dm3.size() == 0);
101         DLIB_TEST(dm3.nr() == 0);
102         DLIB_TEST(dm3.nc() == 0);
103         dm3.set_size(3,4);
104         DLIB_TEST(dm3.nr() == 3);
105         DLIB_TEST(dm3.nc() == 4);
106         DLIB_TEST(dm3.size() == 3*4);
107         dm3.set_size(3,3);
108         DLIB_TEST(dm3.nr() == 3);
109         DLIB_TEST(dm3.nc() == 3);
110         dm3 = m3;
111         dm3(0,0)++;
112         DLIB_TEST( dm3 != m3);
113         dm3 = m3;
114         DLIB_TEST( dm3 == m3);
115         DLIB_TEST( abs(sum(squared(normalize(dm3))) - 1.0) < 1e-10);
116 
117         matrix<double,3,4> mrc;
118         mrc.set_size(3,4);
119 
120         set_all_elements(mrc,1);
121 
122         DLIB_TEST(diag(mrc) == uniform_matrix<double>(3,1,1));
123         DLIB_TEST(diag(matrix<double>(mrc)) == uniform_matrix<double>(3,1,1));
124 
125         matrix<double,2,3> mrc2;
126         set_all_elements(mrc2,1);
127         DLIB_TEST((removerc<1,1>(mrc) == mrc2));
128         DLIB_TEST((removerc(mrc,1,1) == mrc2));
129 
130         matrix<int,3,3> m4, m5, m6;
131         set_all_elements(m4, 4);
132         set_all_elements(m5, 4);
133         set_all_elements(m6, 1);
134 
135         DLIB_TEST(squared(m4) == pointwise_multiply(m4,m4));
136         DLIB_TEST(cubed(m4) == pointwise_multiply(m4,m4,m4));
137         DLIB_TEST(m4 == pointwise_divide(squared(m4),m4));
138         DLIB_TEST(m4 == pointwise_divide(cubed(m4),m4,m4));
139         DLIB_TEST(m4 == pointwise_divide(pointwise_multiply(cubed(m4),m4),m4,m4,m4));
140         DLIB_TEST(squared(m4) == pointwise_divide(cubed(m4),m4));
141         DLIB_TEST(pow(matrix_cast<double>(m4),2) == squared(matrix_cast<double>(m4)));
142         DLIB_TEST(pow(matrix_cast<double>(m4),3) == cubed(matrix_cast<double>(m4)));
143 
144         matrix<int> dm4;
145         matrix<int,0,0,memory_manager_stateless<char>::kernel_2_2a> dm5;
146         dm4 = dm4;
147         dm4 = dm5;
148         DLIB_TEST(dm4.nr() == 0);
149         dm4 = m4;
150         dm5 = m5;
151         DLIB_TEST(dm4 == dm5);
152 
153 
154         DLIB_TEST(m4 == m5);
155         DLIB_TEST(m6 != m5);
156         m4.swap(m6);
157         DLIB_TEST(m6 == m5);
158         DLIB_TEST(m4 != m5);
159 
160         DLIB_TEST(m3.nr() == 3);
161         DLIB_TEST(m3.nc() == 3);
162 
163         matrix<double,4,1> v(array3), v2;
164         DLIB_TEST(v.nr() == 4);
165         DLIB_TEST(v.nc() == 1);
166 
167         std::vector<double> stdv(4);
168         std_vector_c<double> stdv_c(4);
169         dlib::array<double> arr;
170         arr.resize(4);
171         for (long i = 0; i < 4; ++i)
172             stdv[i] = stdv_c[i] = arr[i] = i+1;
173 
174         DLIB_TEST(mat(stdv)(0) == 1);
175         DLIB_TEST(mat(stdv)(1) == 2);
176         DLIB_TEST(mat(stdv)(2) == 3);
177         DLIB_TEST(mat(stdv)(3) == 4);
178         DLIB_TEST(mat(stdv).nr() == 4);
179         DLIB_TEST(mat(stdv).nc() == 1);
180         DLIB_TEST(mat(stdv).size() == 4);
181         DLIB_TEST(equal(trans(mat(stdv))*mat(stdv), trans(v)*v));
182         DLIB_TEST(equal(trans(mat(stdv))*mat(stdv), tmp(trans(v)*v)));
183 
184         DLIB_TEST(mat(stdv_c)(0) == 1);
185         DLIB_TEST(mat(stdv_c)(1) == 2);
186         DLIB_TEST(mat(stdv_c)(2) == 3);
187         DLIB_TEST(mat(stdv_c)(3) == 4);
188         DLIB_TEST(mat(stdv_c).nr() == 4);
189         DLIB_TEST(mat(stdv_c).nc() == 1);
190         DLIB_TEST(mat(stdv_c).size() == 4);
191         DLIB_TEST(equal(trans(mat(stdv_c))*mat(stdv_c), trans(v)*v));
192 
193         DLIB_TEST(mat(arr)(0) == 1);
194         DLIB_TEST(mat(arr)(1) == 2);
195         DLIB_TEST(mat(arr)(2) == 3);
196         DLIB_TEST(mat(arr)(3) == 4);
197         DLIB_TEST(mat(arr).nr() == 4);
198         DLIB_TEST(mat(arr).nc() == 1);
199         DLIB_TEST(mat(arr).size() == 4);
200         DLIB_TEST(equal(trans(mat(arr))*mat(arr), trans(v)*v));
201 
202         DLIB_TEST(v(0) == 1);
203         DLIB_TEST(v(1) == 2);
204         DLIB_TEST(v(2) == 3);
205         DLIB_TEST(v(3) == 4);
206         matrix<double> dv = v;
207         DLIB_TEST((trans(v)*v).size() == 1);
208         DLIB_TEST((trans(v)*v).nr() == 1);
209         DLIB_TEST((trans(v)*dv).nr() == 1);
210         DLIB_TEST((trans(dv)*dv).nr() == 1);
211         DLIB_TEST((trans(dv)*v).nr() == 1);
212         DLIB_TEST((trans(v)*v).nc() == 1);
213         DLIB_TEST((trans(v)*dv).nc() == 1);
214         DLIB_TEST((trans(dv)*dv).nc() == 1);
215         DLIB_TEST((trans(dv)*v).nc() == 1);
216         DLIB_TEST((trans(v)*v)(0) == 1*1 + 2*2 + 3*3 + 4*4);
217         DLIB_TEST((trans(dv)*v)(0) == 1*1 + 2*2 + 3*3 + 4*4);
218         DLIB_TEST((trans(dv)*dv)(0) == 1*1 + 2*2 + 3*3 + 4*4);
219         DLIB_TEST((trans(v)*dv)(0) == 1*1 + 2*2 + 3*3 + 4*4);
220 
221         dv = trans(dv)*v;
222         DLIB_TEST(dv.nr() == 1);
223         DLIB_TEST(dv.nc() == 1);
224 
225         dm3 = m3;
226         DLIB_TEST(floor(det(m3)+0.01) == -444);
227         DLIB_TEST(floor(det(dm3)+0.01) == -444);
228         DLIB_TEST(min(m3) == 1);
229         DLIB_TEST(m3(min_point(m3).y(),min_point(m3).x()) == 1);
230         DLIB_TEST(min(dm3) == 1);
231         DLIB_TEST(max(m3) == 52);
232         DLIB_TEST(m3(max_point(m3).y(),max_point(m3).x()) == 52);
233         DLIB_TEST(max(dm3) == 52);
234         DLIB_TEST(sum(m3) == 112);
235         DLIB_TEST(sum(dm3) == 112);
236         DLIB_TEST(prod(m3) == 41513472);
237         DLIB_TEST(prod(dm3) == 41513472);
238         DLIB_TEST(prod(diag(m3)) == 1*52*9);
239         DLIB_TEST(prod(diag(dm3)) == 1*52*9);
240         DLIB_TEST(sum(diag(m3)) == 1+52+9);
241         DLIB_TEST(sum(diag(dm3)) == 1+52+9);
242         DLIB_TEST(equal(round(10000*m3*inv(m3))/10000 , identity_matrix<double,3>()));
243         DLIB_TEST(equal(round(10000*dm3*inv(m3))/10000 , identity_matrix<double,3>()));
244         DLIB_TEST(equal(round(10000*dm3*inv(dm3))/10000 , identity_matrix<double,3>()));
245         DLIB_TEST(equal(round(10000*m3*inv(dm3))/10000 , identity_matrix<double,3>()));
246         DLIB_TEST(equal(round(10000*tmp(m3*inv(m3)))/10000 , identity_matrix<double,3>()));
247         DLIB_TEST(equal(round(10000*tmp(dm3*inv(m3)))/10000 , identity_matrix<double,3>()));
248         DLIB_TEST(equal(round(10000*tmp(dm3*inv(dm3)))/10000 , identity_matrix<double,3>()));
249         DLIB_TEST(equal(round(10000*tmp(m3*inv(dm3)))/10000 , identity_matrix<double,3>()));
250         DLIB_TEST(-1*m3 == -m3);
251         DLIB_TEST(-1*dm3 == -m3);
252         DLIB_TEST(-1*m3 == -dm3);
253         DLIB_TEST(-1*dm3 == -dm3);
254 
255         DLIB_TEST(m3 == dm3);
256         m3(1,1) = 99;
257         DLIB_TEST(m3 != dm3);
258         m3 = dm3;
259         DLIB_TEST(m3 == dm3);
260 
261         matrix<double,4,4,MM> mident(ident);
262         matrix<double,4,4> muniform0(uniform0);
263         matrix<double,4,4> muniform1(uniform1);
264         matrix<double,4,4> muniform3(uniform3);
265         matrix<double,4,4> m1(array), m2;
266         DLIB_TEST(m1.nr() == 4);
267         DLIB_TEST(m1.nc() == 4);
268 
269         DLIB_TEST(muniform1 + muniform1 + muniform1 == muniform3);
270         DLIB_TEST(muniform1*2 + muniform1 + muniform1 - muniform1 == muniform3);
271         DLIB_TEST(2*muniform1 + muniform1 + muniform1 - muniform1 == muniform3);
272         DLIB_TEST(muniform1 + muniform1 + muniform1 - muniform3 == muniform0);
273         DLIB_TEST(equal(muniform3/3 , muniform1));
274         DLIB_TEST(v != m1);
275         DLIB_TEST(v == v);
276         DLIB_TEST(m1 == m1);
277 
278         muniform0.swap(muniform1);
279         DLIB_TEST((muniform1 == matrix_cast<double>(uniform_matrix<long,4,4,0>())));
280         DLIB_TEST((muniform0 == matrix_cast<double>(uniform_matrix<long,4,4,1>())));
281         DLIB_TEST((muniform1 == matrix_cast<double>(uniform_matrix<long>(4,4,0))));
282         DLIB_TEST((muniform0 == matrix_cast<double>(uniform_matrix<long>(4,4,1))));
283         swap(muniform0,muniform1);
284 
285         DLIB_TEST((mident == identity_matrix<double,4>()));
286         DLIB_TEST((muniform0 == matrix_cast<double>(uniform_matrix<long,4,4,0>())));
287         DLIB_TEST((muniform1 == matrix_cast<double>(uniform_matrix<long,4,4,1>())));
288         DLIB_TEST((muniform3 == matrix_cast<double>(uniform_matrix<long,4,4,3>())));
289         DLIB_TEST((muniform1*8 == matrix_cast<double>(uniform_matrix<long,4,4,8>())));
290 
291         set_all_elements(m2,7);
292         DLIB_TEST(m2 == muniform1*7);
293         m2 = array;
294         DLIB_TEST(m2 == m1);
295 
296         const double m1inv[] = {
297             -0.00946427624, 0.0593272941,  0.00970564379,  -0.00973323731,
298             0.0249312057,   -0.0590122427, -0.00583102756, 0.00616002729,
299             -0.00575431149, 0.110081189,   -0.00806792253, 0.00462297692,
300             0.00327847478,  -0.0597669712, 0.00317386196,  0.00990759201
301         };
302 
303         m2 = m1inv;
304         DLIB_TEST((round(m2*m1) == identity_matrix<double,4>()));
305         DLIB_TEST((round(tmp(m2*m1)) == identity_matrix<double,4>()));
306 
307         DLIB_TEST_MSG(round(m2*10000) == round(inv(m1)*10000),
308                      round(m2*10000) - round(inv(m1)*10000)
309                      << "\n\n" << round(m2*10000)
310                      << "\n\n" << round(inv(m1)*10000)
311                      << "\n\n" << m2
312                      << "\n\n" << inv(m1)
313                      );
314         DLIB_TEST(m1 == abs(-1*m1));
315         DLIB_TEST(abs(m2) == abs(-1*m2));
316 
317         DLIB_TEST_MSG(floor(det(m1)+0.01) == 3297875,"\nm1: \n" << m1 << "\ndet(m1): " << det(m1));
318 
319 
320         ostringstream sout;
321         m1 = m2;
322         serialize(m1,sout);
323         set_all_elements(m1,0);
324         istringstream sin(sout.str());
325         deserialize(m1,sin);
326         DLIB_TEST_MSG(round(100000*m1) == round(100000*m2),"m1: \n" << m1 << endl << "m2: \n" << m2);
327 
328 
329         set_all_elements(v,2);
330         v2 = pointwise_divide(v*2,v);
331         DLIB_TEST(v == v2);
332         DLIB_TEST(v == tmp(v2));
333 
334         v2 = pointwise_multiply(v,v*2);
335         set_all_elements(v,8);
336         DLIB_TEST(v == v2);
337         DLIB_TEST(v == tmp(v2));
338         DLIB_TEST((v == rotate<2,0>(v)));
339 
340         m4 = array2;
341         m5 = array2_r;
342         DLIB_TEST((m5 == rotate<1,1>(m4)));
343 
344         m5 = array2;
345         DLIB_TEST((m5*2 == pointwise_multiply(m5,uniform_matrix<int,3,3,2>())));
346         DLIB_TEST((tmp(m5*2) == tmp(pointwise_multiply(m5,uniform_matrix<int,3,3,2>()))));
347         DLIB_TEST((m5/2 == pointwise_divide(m5,uniform_matrix<int,3,3,2>())));
348         DLIB_TEST((tmp(m5/2) == tmp(pointwise_divide(m5,uniform_matrix<int,3,3,2>()))));
349 
350         v = tmp(v);
351 
352 
353 
354 
355         matrix<double> dm10(10,5);
356         DLIB_TEST(dm10.nr() == 10);
357         DLIB_TEST(dm10.nc() == 5);
358         set_all_elements(dm10,4);
359         DLIB_TEST(dm10.nr() == 10);
360         DLIB_TEST(dm10.nc() == 5);
361         matrix<double,10,5> m10;
362         DLIB_TEST(m10.nr() == 10);
363         DLIB_TEST(m10.nc() == 5);
364         set_all_elements(m10,4);
365         DLIB_TEST(dm10 == m10);
366         DLIB_TEST((clamp<0,3>(dm10) == clamp<0,3>(m10)));
367         DLIB_TEST((clamp<0,3>(dm10)(0,2) == 3));
368 
369         set_all_elements(dm10,1);
370         set_all_elements(m10,4);
371         DLIB_TEST(4*dm10 == m10);
372         DLIB_TEST(5*dm10 - dm10 == m10);
373         DLIB_TEST((16*dm10)/4 == m10);
374         DLIB_TEST(dm10+dm10+2*dm10 == m10);
375         DLIB_TEST(dm10+tmp(dm10+2*dm10) == m10);
376         set_all_elements(dm10,4);
377         DLIB_TEST(dm10 == m10);
378         DLIB_TEST_MSG(sum(abs(sigmoid(dm10) -sigmoid(m10))) < 1e-10,sum(abs(sigmoid(dm10) -sigmoid(m10))) );
379 
380         {
381             matrix<double,2,1> x, l, u, out;
382             x = 3,4;
383 
384             l = 1,1;
385             u = 2,2.2;
386 
387             out = 2, 2.2;
388             DLIB_TEST(equal(dlib::clamp(x, l, u) , out));
389             out = 3, 2.2;
390             DLIB_TEST(!equal(dlib::clamp(x, l, u) , out));
391             out = 2, 4.2;
392             DLIB_TEST(!equal(dlib::clamp(x, l, u) , out));
393 
394             x = 1.5, 1.5;
395             out = x;
396             DLIB_TEST(equal(dlib::clamp(x, l, u) , out));
397 
398             x = 0.5, 1.5;
399             out = 1, 1.5;
400             DLIB_TEST(equal(dlib::clamp(x, l, u) , out));
401 
402             x = 1.5, 0.5;
403             out = 1.5, 1.0;
404             DLIB_TEST(equal(dlib::clamp(x, l, u) , out));
405 
406         }
407 
408         matrix<double, 7, 7,MM,column_major_layout> m7;
409         matrix<double> dm7(7,7);
410         dm7 = randm(7,7, rnd);
411         m7 = dm7;
412 
413         DLIB_TEST_MSG(max(abs(dm7*inv(dm7) - identity_matrix<double>(7))) < 1e-12, max(abs(dm7*inv(dm7) - identity_matrix<double>(7))));
414         DLIB_TEST(equal(inv(dm7),  inv(m7)));
415         DLIB_TEST(abs(det(dm7) - det(m7)) < 1e-14);
416         DLIB_TEST(abs(min(dm7) - min(m7)) < 1e-14);
417         DLIB_TEST(abs(max(dm7) - max(m7)) < 1e-14);
418         DLIB_TEST_MSG(abs(sum(dm7) - sum(m7)) < 1e-13,sum(dm7) - sum(m7));
419         DLIB_TEST(abs(prod(dm7) -prod(m7)) < 1e-14);
420         DLIB_TEST(equal(diag(dm7) , diag(m7)));
421         DLIB_TEST(equal(trans(dm7) , trans(m7)));
422         DLIB_TEST(equal(abs(dm7) , abs(m7)));
423         DLIB_TEST(equal(round(dm7) , round(m7)));
424         DLIB_TEST(matrix_cast<int>(dm7) == matrix_cast<int>(m7));
425         DLIB_TEST((rotate<2,3>(dm7) == rotate<2,3>(m7)));
426         DLIB_TEST((sum(pointwise_multiply(dm7,dm7) - pointwise_multiply(m7,m7))) < 1e-10);
427         DLIB_TEST((sum(pointwise_multiply(dm7,dm7,dm7) - pointwise_multiply(m7,m7,m7))) < 1e-10);
428         DLIB_TEST_MSG((sum(pointwise_multiply(dm7,dm7,dm7,dm7) - pointwise_multiply(m7,m7,m7,m7))) < 1e-10,
429                      (sum(pointwise_multiply(dm7,dm7,dm7,dm7) - pointwise_multiply(m7,m7,m7,m7)))
430         );
431 
432 
433         matrix<double> temp(5,5);
434         matrix<double> dsm(5,5);
435         matrix<double,5,5,MM> sm;
436 
437         set_all_elements(dsm,1);
438         set_all_elements(sm,1);
439         set_all_elements(temp,1);
440 
441         dsm += dsm;
442         sm += sm;
443         DLIB_TEST(dsm == 2*temp);
444         DLIB_TEST(sm == 2*temp);
445         temp = dsm*sm + dsm;
446         dsm += dsm*sm;
447         DLIB_TEST_MSG(temp == dsm,temp - dsm);
448 
449         set_all_elements(dsm,1);
450         set_all_elements(sm,1);
451         set_all_elements(temp,1);
452 
453         dsm += dsm;
454         sm += sm;
455         DLIB_TEST(dsm == 2*temp);
456         DLIB_TEST(sm == 2*temp);
457         temp = dsm*sm + dsm;
458         sm += dsm*sm;
459         DLIB_TEST_MSG(temp == sm,temp - sm);
460 
461         set_all_elements(dsm,1);
462         set_all_elements(sm,1);
463         set_all_elements(temp,1);
464 
465         dsm += dsm;
466         sm += sm;
467         DLIB_TEST(dsm == 2*temp);
468         DLIB_TEST(sm == 2*temp);
469         temp = sm - dsm*sm ;
470         sm -= dsm*sm;
471         DLIB_TEST_MSG(temp == sm,temp - sm);
472 
473         set_all_elements(dsm,1);
474         set_all_elements(sm,1);
475         set_all_elements(temp,1);
476 
477         dsm += dsm;
478         sm += sm;
479         DLIB_TEST(dsm == 2*temp);
480         DLIB_TEST(sm == 2*temp);
481         temp = dsm - dsm*sm ;
482         dsm -= dsm*sm;
483         DLIB_TEST_MSG(temp == dsm,temp - dsm);
484 
485         set_all_elements(dsm,1);
486         set_all_elements(sm,1);
487         set_all_elements(temp,2);
488 
489         dsm *= 2;
490         sm *= 2;
491         DLIB_TEST(dsm == temp);
492         DLIB_TEST(sm == temp);
493         dsm /= 2;
494         sm /= 2;
495         DLIB_TEST(dsm == temp/2);
496         DLIB_TEST(sm == temp/2);
497 
498         dsm += dsm;
499         sm += sm;
500         DLIB_TEST(dsm == temp);
501         DLIB_TEST(sm == temp);
502         dsm += sm;
503         sm += dsm;
504         DLIB_TEST(dsm == 2*temp);
505         DLIB_TEST(sm == temp*3);
506         dsm -= sm;
507         sm -= dsm;
508         DLIB_TEST(dsm == -temp);
509         DLIB_TEST(sm == 4*temp);
510         sm -= sm;
511         dsm -= dsm;
512         DLIB_TEST(dsm == 0*temp);
513         DLIB_TEST(sm == 0*temp);
514 
515         set_all_elements(dsm,1);
516         set_all_elements(sm,1);
517         set_all_elements(temp,3);
518         dsm += sm+sm;
519         DLIB_TEST(dsm == temp);
520 
521         set_all_elements(dsm,1);
522         set_all_elements(sm,1);
523         set_all_elements(temp,-1);
524         dsm -= sm+sm;
525         DLIB_TEST(dsm == temp);
526 
527         set_all_elements(dsm,1);
528         set_all_elements(sm,1);
529         set_all_elements(temp,-1);
530         sm -= dsm+dsm;
531         DLIB_TEST(sm == temp);
532 
533         set_all_elements(dsm,1);
534         set_all_elements(sm,1);
535         set_all_elements(temp,3);
536         sm += dsm+dsm;
537         DLIB_TEST(sm == temp);
538 
539 
540 
541         // test the implicit conversion to bool stuff
542         {
543             matrix<float> bt1(3,1);
544             matrix<float,3,1> bt2;
545             set_all_elements(bt1,2);
546             set_all_elements(bt2,3);
547 
548             float val = trans(bt1)*bt2;
549             DLIB_TEST((float)(trans(bt1)*bt2) == 18);
550             DLIB_TEST((float)(trans(bt1)*bt2) != 19);
551             DLIB_TEST(val == 18);
552         }
553         {
554             matrix<float,3,1> bt1;
555             matrix<float> bt2(3,1);
556             set_all_elements(bt1,2);
557             set_all_elements(bt2,3);
558 
559             float val = trans(bt1)*bt2;
560             DLIB_TEST((float)(trans(bt1)*bt2) == 18);
561             DLIB_TEST((float)(trans(bt1)*bt2) != 19);
562             DLIB_TEST(val == 18);
563         }
564         {
565             matrix<float> bt1(3,1);
566             matrix<float> bt2(3,1);
567             set_all_elements(bt1,2);
568             set_all_elements(bt2,3);
569 
570             float val = trans(bt1)*bt2;
571             DLIB_TEST((float)(trans(bt1)*bt2) == 18);
572             DLIB_TEST((float)(trans(bt1)*bt2) != 19);
573             DLIB_TEST(val == 18);
574         }
575         {
576             matrix<float,3,1> bt1;
577             matrix<float,3,1> bt2;
578             set_all_elements(bt1,2);
579             set_all_elements(bt2,3);
580 
581             float val = trans(bt1)*bt2;
582             DLIB_TEST((float)(trans(bt1)*bt2) == 18);
583             DLIB_TEST((float)(trans(bt1)*bt2) != 19);
584             DLIB_TEST(val == 18);
585         }
586 
587 
588 
589 
590         {
591             srand(423452);
592             const long M = 50;
593             const long N = 40;
594 
595             matrix<double> a(M,N);
596             for (long r = 0; r < a.nr(); ++r)
597             {
598                 for (long c = 0; c < a.nc(); ++c)
599                 {
600                     a(r,c) = 10*((double)::rand())/RAND_MAX;
601                 }
602             }
603 
604             matrix<double> u, u2;
605             matrix<double> q, q2;
606             matrix<double> v, v2;
607 
608             matrix<double> a2;
609             a2 = tmp(a/2);
610 
611 
612             svd2(true,true,a2+a2,u,q,v);
613 
614             double err = max(abs(a - subm(u,get_rect(a2+a2))*diagm(q)*trans(v)));
615             DLIB_TEST_MSG( err < 1e-11,"err: " << err);
616             using dlib::equal;
617             DLIB_TEST((equal(trans(u)*u , identity_matrix<double,M>(), 1e-10)));
618             DLIB_TEST((equal(trans(v)*v , identity_matrix<double,N>(), 1e-10)));
619 
620             svd2(false,true,a2+a2,u,q,v2);
621             svd2(true,false,a2+a2,u2,q,v);
622             svd2(false,false,a2+a2,u,q2,v);
623 
624             err = max(abs(a - subm(u2,get_rect(a2+a2))*diagm(q2)*trans(v2)));
625             DLIB_TEST_MSG( err < 1e-11,"err: " << err);
626             DLIB_TEST((equal(trans(u2)*u2 , identity_matrix<double,M>(), 1e-10)));
627             DLIB_TEST((equal(trans(v2)*v2 , identity_matrix<double,N>(), 1e-10)));
628 
629         }
630 
631 
632         {
633             srand(423452);
634             const long M = 3;
635             const long N = 3;
636 
637             matrix<double> a(M,N);
638             for (long r = 0; r < a.nr(); ++r)
639             {
640                 for (long c = 0; c < a.nc(); ++c)
641                 {
642                     a(r,c) = 10*((double)::rand())/RAND_MAX;
643                 }
644             }
645 
646             matrix<double,M,M> u, u2;
647             matrix<double> q, q2;
648             matrix<double,N,N> v, v2;
649 
650             matrix<double,M,N,MM> a2;
651             a2 = tmp(a/2);
652 
653 
654             svd2(true,true,a2+a2,u,q,v);
655 
656             double err = max(abs(a - subm(u,get_rect(a2+a2))*diagm(q)*trans(v)));
657             DLIB_TEST_MSG( err < 1e-11,"err: " << err);
658             using dlib::equal;
659             DLIB_TEST((equal(trans(u)*u , identity_matrix<double,M>(), 1e-10)));
660             DLIB_TEST((equal(trans(v)*v , identity_matrix<double,N>(), 1e-10)));
661 
662             svd2(false,true,a2+a2,u,q,v2);
663             svd2(true,false,a2+a2,u2,q,v);
664             svd2(false,false,a2+a2,u,q2,v);
665 
666             err = max(abs(a - subm(u2,get_rect(a2+a2))*diagm(q2)*trans(v2)));
667             DLIB_TEST_MSG( err < 1e-11,"err: " << err);
668             DLIB_TEST((equal(trans(u2)*u2 , identity_matrix<double,M>(), 1e-10)));
669             DLIB_TEST((equal(trans(v2)*v2 , identity_matrix<double,N>(), 1e-10)));
670 
671         }
672 
673         {
674             srand(423452);
675             const long M = 3;
676             const long N = 3;
677 
678 
679             matrix<double,0,0,default_memory_manager, column_major_layout> a(M,N);
680             for (long r = 0; r < a.nr(); ++r)
681             {
682                 for (long c = 0; c < a.nc(); ++c)
683                 {
684                     a(r,c) = 10*((double)::rand())/RAND_MAX;
685                 }
686             }
687 
688             matrix<double,M,M,default_memory_manager, column_major_layout> u, u2;
689             matrix<double,0,0,default_memory_manager, column_major_layout> q, q2;
690             matrix<double,N,N,default_memory_manager, column_major_layout> v, v2;
691 
692             matrix<double,M,N,MM, column_major_layout> a2;
693             a2 = tmp(a/2);
694 
695 
696             svd2(true,true,a2+a2,u,q,v);
697 
698             double err = max(abs(a - subm(u,get_rect(a2+a2))*diagm(q)*trans(v)));
699             DLIB_TEST_MSG( err < 1e-11,"err: " << err);
700             using dlib::equal;
701             DLIB_TEST((equal(trans(u)*u , identity_matrix<double,M>(), 1e-10)));
702             DLIB_TEST((equal(trans(v)*v , identity_matrix<double,N>(), 1e-10)));
703 
704             svd2(false,true,a2+a2,u,q,v2);
705             svd2(true,false,a2+a2,u2,q,v);
706             svd2(false,false,a2+a2,u,q2,v);
707 
708             err = max(abs(a - subm(u2,get_rect(a2+a2))*diagm(q2)*trans(v2)));
709             DLIB_TEST_MSG( err < 1e-11,"err: " << err);
710             DLIB_TEST((equal(trans(u2)*u2 , identity_matrix<double,M>(), 1e-10)));
711             DLIB_TEST((equal(trans(v2)*v2 , identity_matrix<double,N>(), 1e-10)));
712 
713         }
714 
715 
716 
717         {
718             srand(423452);
719             const long M = 10;
720             const long N = 7;
721 
722             matrix<double> a(M,N);
723             for (long r = 0; r < a.nr(); ++r)
724             {
725                 for (long c = 0; c < a.nc(); ++c)
726                 {
727                     a(r,c) = 10*((double)::rand())/RAND_MAX;
728                 }
729             }
730 
731             matrix<double,M,M> u;
732             matrix<double> q;
733             matrix<double,N,N> v;
734 
735             matrix<double,M,N,MM> a2;
736             a2 = tmp(a/2);
737 
738 
739             svd2(true,true,a2+a2,u,q,v);
740 
741             double err = sum(round(1e10*(a - subm(u,get_rect(a2+a2))*diagm(q)*trans(v))));
742             DLIB_TEST_MSG(  err == 0,"err: " << err);
743             DLIB_TEST((round(1e10*trans(u)*u)  == 1e10*identity_matrix<double,M>()));
744             DLIB_TEST((round(1e10*trans(v)*v)  == 1e10*identity_matrix<double,N>()));
745         }
746 
747 
748     }
749 
750 
matrix_test2()751     void matrix_test2 (
752     )
753     {
754         typedef memory_manager_stateless<char>::kernel_2_2a MM;
755         {
756             srand(423452);
757             const long M = 10;
758             const long N = 7;
759 
760             matrix<double> a(M,N);
761             for (long r = 0; r < a.nr(); ++r)
762             {
763                 for (long c = 0; c < a.nc(); ++c)
764                 {
765                     a(r,c) = 10*((double)::rand())/RAND_MAX;
766                 }
767             }
768 
769             matrix<double,M> u(M,N);
770             matrix<double> w;
771             matrix<double,N,N> v(N,N);
772 
773             matrix<double,M,N,MM> a2;
774             a2 = tmp(a/2);
775 
776 
777             svd(a2+a2,u,w,v);
778 
779             DLIB_TEST(  sum(round(1e10*(a - u*w*trans(v)))) == 0);
780             DLIB_TEST((round(1e10*trans(u)*u)  == 1e10*identity_matrix<double,N>()));
781             DLIB_TEST((round(1e10*trans(v)*v)  == 1e10*identity_matrix<double,N>()));
782         }
783 
784         {
785             srand(423452);
786             const long M = 1;
787             const long N = 1;
788 
789             matrix<double> a(M,N);
790             for (long r = 0; r < a.nr(); ++r)
791             {
792                 for (long c = 0; c < a.nc(); ++c)
793                 {
794                     a(r,c) = 10*((double)::rand())/RAND_MAX;
795                 }
796             }
797 
798             matrix<double,M,N> u;
799             matrix<double> w;
800             matrix<double,N,N> v;
801 
802             matrix<double,M,N> a2;
803             a2 = 0;
804             a2 = tmp(a/2);
805 
806 
807             svd(a2+a2,u,w,v);
808 
809             DLIB_TEST(  sum(round(1e10*(a - u*w*trans(v)))) == 0);
810             DLIB_TEST((round(1e10*trans(u)*u)  == 1e10*identity_matrix<double,N>()));
811             DLIB_TEST((round(1e10*trans(v)*v)  == 1e10*identity_matrix<double,N>()));
812         }
813 
814 
815         {
816             srand(53434);
817             const long M = 5;
818             const long N = 5;
819 
820             matrix<double> a(M,N);
821             for (long r = 0; r < a.nr(); ++r)
822             {
823                 for (long c = 0; c < a.nc(); ++c)
824                 {
825                     a(r,c) = 10*((double)::rand())/RAND_MAX;
826                 }
827             }
828 
829             matrix<double,0,N> u(M,N);
830             matrix<double,N,N> w;
831             matrix<double> v;
832 
833             svd(a,u,w,v);
834 
835             DLIB_TEST(  sum(round(1e10*(a - u*w*trans(v)))) == 0);
836             DLIB_TEST((round(1e10*trans(u)*u)  == 1e10*identity_matrix<double,N>()));
837             DLIB_TEST((round(1e10*trans(v)*v)  == 1e10*identity_matrix<double,N>()));
838         }
839 
840 
841         {
842             srand(11234);
843             const long M = 9;
844             const long N = 4;
845 
846             matrix<double,0,0,MM> a(M,N);
847             for (long r = 0; r < a.nr(); ++r)
848             {
849                 for (long c = 0; c < a.nc(); ++c)
850                 {
851                     a(r,c) = 10*((double)::rand())/RAND_MAX;
852                 }
853             }
854 
855             matrix<double> u;
856             matrix<double,0,0,MM> w;
857             matrix<double> v;
858 
859             svd(a,u,w,v);
860 
861             DLIB_TEST(  sum(round(1e10*(a - u*w*trans(v)))) == 0);
862             DLIB_TEST((round(1e10*trans(u)*u)  == 1e10*identity_matrix<double,N>()));
863             DLIB_TEST((round(1e10*trans(v)*v)  == 1e10*identity_matrix<double,N>()));
864         }
865 
866 
867 
868         {
869             srand(53934);
870             const long M = 2;
871             const long N = 4;
872 
873             matrix<double> a(M,N);
874             for (long r = 0; r < a.nr(); ++r)
875             {
876                 for (long c = 0; c < a.nc(); ++c)
877                 {
878                     a(r,c) = 10*((double)::rand())/RAND_MAX;
879                 }
880             }
881 
882             matrix<double> u;
883             matrix<double> w;
884             matrix<double> v;
885 
886             svd(a,u,w,v);
887 
888             DLIB_TEST(  sum(round(1e10*(a - u*w*trans(v)))) == 0);
889         }
890 
891 
892         {
893             srand(53234);
894             const long M = 9;
895             const long N = 40;
896 
897             matrix<double> a(M,N);
898             for (long r = 0; r < a.nr(); ++r)
899             {
900                 for (long c = 0; c < a.nc(); ++c)
901                 {
902                     a(r,c) = 10*((double)::rand())/RAND_MAX;
903                 }
904             }
905 
906             matrix<double> u;
907             matrix<double> w;
908             matrix<double> v;
909 
910             svd(a,u,w,v);
911 
912             DLIB_TEST(  sum(round(1e10*(a - u*w*trans(v)))) == 0);
913         }
914 
915         {
916             srand(53234);
917             const long M = 9;
918             const long N = 40;
919 
920             typedef matrix<double,0,0,default_memory_manager, column_major_layout> mat;
921             mat a(M,N);
922             for (long r = 0; r < a.nr(); ++r)
923             {
924                 for (long c = 0; c < a.nc(); ++c)
925                 {
926                     a(r,c) = 10*((double)::rand())/RAND_MAX;
927                 }
928             }
929 
930             mat u;
931             mat w;
932             mat v;
933 
934             svd(a,u,w,v);
935 
936             DLIB_TEST(  sum(round(1e10*(a - u*w*trans(v)))) == 0);
937         }
938 
939 
940         {
941             matrix<double> a(3,3);
942             matrix<double,3,3> b;
943             set_all_elements(a,0);
944 
945             a(0,0) = 1;
946             a(1,1) = 2;
947             a(2,2) = 3;
948             b = a;
949 
950             DLIB_TEST(diag(a)(0) == 1);
951             DLIB_TEST(diag(a)(1) == 2);
952             DLIB_TEST(diag(a)(2) == 3);
953             DLIB_TEST(diag(a).nr() == 3);
954             DLIB_TEST(diag(a).nc() == 1);
955 
956             DLIB_TEST(diag(b)(0) == 1);
957             DLIB_TEST(diag(b)(1) == 2);
958             DLIB_TEST(diag(b)(2) == 3);
959             DLIB_TEST(diag(b).nr() == 3);
960             DLIB_TEST(diag(b).nc() == 1);
961 
962             DLIB_TEST(pointwise_multiply(a,b)(0,0) == 1);
963             DLIB_TEST(pointwise_multiply(a,b)(1,1) == 4);
964             DLIB_TEST(pointwise_multiply(a,b)(2,2) == 9);
965             DLIB_TEST(pointwise_multiply(a,b)(1,0) == 0);
966             DLIB_TEST(pointwise_multiply(a,b,a)(1,0) == 0);
967             DLIB_TEST(pointwise_multiply(a,b,a,b)(1,0) == 0);
968 
969 
970             DLIB_TEST(complex_matrix(a,b)(0,0) == std::complex<double>(1,1));
971             DLIB_TEST(complex_matrix(a,b)(2,2) == std::complex<double>(3,3));
972             DLIB_TEST(complex_matrix(a,b)(2,1) == std::complex<double>(0,0));
973         }
974 
975         {
976             matrix<complex<double> > m(2,2), m2(2,2);
977             complex<double> val1(1,2), val2(1.0/complex<double>(1,2));
978             m = val1;
979             m2 = val2;
980 
981             DLIB_TEST(equal(reciprocal(m),m2));
982             DLIB_TEST(equal(pointwise_multiply(m,m2),pointwise_divide(m,m)));
983         }
984         {
985             matrix<complex<float> > m(2,2), m2(2,2);
986             complex<float> val1(1,2), val2(1.0f/complex<float>(1,2));
987             m = val1;
988             m2 = val2;
989 
990             DLIB_TEST(equal(reciprocal(m),m2));
991             DLIB_TEST(equal(pointwise_multiply(m,m2),pointwise_divide(m,m)));
992         }
993 
994         {
995             matrix<float,3,1> m1, m2;
996             set_all_elements(m1,2.0);
997             set_all_elements(m2,1.0/2.0);
998             DLIB_TEST(reciprocal(m1) == m2);
999             DLIB_TEST((reciprocal(uniform_matrix<float,3,1>(2.0)) == m2));
1000             DLIB_TEST((round_zeros(uniform_matrix<float,3,1>(1e-8f)) == uniform_matrix<float,3,1>(0)) );
1001             set_all_elements(m1,2.0);
1002             m2 = m1;
1003             m1(1,0) = static_cast<float>(1e-8);
1004             m2(1,0) = 0;
1005             DLIB_TEST(round_zeros(m1) == m2);
1006             m1 = round_zeros(m1);
1007             DLIB_TEST(m1 == m2);
1008         }
1009 
1010         {
1011             matrix<matrix<double,2,2> > m;
1012             m.set_size(3,3);
1013             set_all_elements(m,uniform_matrix<double,2,2>(1));
1014             DLIB_TEST((sum(m) == uniform_matrix<double,2,2>(9)));
1015             DLIB_TEST((round_zeros(sqrt(sum(m)) - uniform_matrix<double,2,2>(3)) == uniform_matrix<double,2,2>(0)));
1016         }
1017 
1018         {
1019             matrix<int,2,2> m1;
1020             matrix<int> m2;
1021             m2.set_size(2,2);
1022 
1023             set_all_elements(m1,2);
1024             m2 = uniform_matrix<int,2,2>(2);
1025 
1026             m1 = m1 + m2;
1027             DLIB_TEST((m1 == uniform_matrix<int,2,2>(4)));
1028 
1029             set_all_elements(m1,2);
1030             set_all_elements(m2,2);
1031             m1 = m1*m1;
1032             DLIB_TEST((m1 == uniform_matrix<int,2,2>(8)));
1033 
1034             m1(1,0) = 1;
1035             set_all_elements(m2,8);
1036             m2(0,1) = 1;
1037             m1 = trans(m1);
1038             DLIB_TEST(m1 == m2);
1039         }
1040 
1041         {
1042             matrix<double,2,3> m;
1043             matrix<double> m2(2,3);
1044 
1045             set_all_elements(m,1);
1046             DLIB_TEST(mean(m) == 1);
1047             set_all_elements(m,2);
1048             DLIB_TEST(mean(m) == 2);
1049             m(0,0) = 1;
1050             m(0,1) = 1;
1051             m(0,2) = 1;
1052             DLIB_TEST(abs(mean(m) - 1.5) < 1e-10);
1053             DLIB_TEST(abs(variance(m) - 0.3) < 1e-10);
1054 
1055             set_all_elements(m2,1);
1056             DLIB_TEST(mean(m2) == 1);
1057             set_all_elements(m2,2);
1058             DLIB_TEST(mean(m2) == 2);
1059             m2(0,0) = 1;
1060             m2(0,1) = 1;
1061             m2(0,2) = 1;
1062             DLIB_TEST(abs(mean(m2) - 1.5) < 1e-10);
1063             DLIB_TEST(abs(variance(m2) - 0.3) < 1e-10);
1064 
1065             set_all_elements(m,0);
1066             DLIB_TEST(abs(variance(m)) < 1e-10);
1067             set_all_elements(m,1);
1068             DLIB_TEST(abs(variance(m)) < 1e-10);
1069             set_all_elements(m,23.4);
1070             DLIB_TEST(abs(variance(m)) < 1e-10);
1071         }
1072 
1073         {
1074             matrix<matrix<double,3,1,MM>,2,2,MM> m;
1075             set_all_elements(m,uniform_matrix<double,3,1>(1));
1076             DLIB_TEST((round_zeros(variance(m)) == uniform_matrix<double,3,1>(0)));
1077             DLIB_TEST((round_zeros(mean(m)) == uniform_matrix<double,3,1>(1)));
1078             m(0,0) = uniform_matrix<double,3,1>(9);
1079             DLIB_TEST((round_zeros(variance(m)) == uniform_matrix<double,3,1>(16)));
1080             DLIB_TEST((round_zeros(mean(m)) == uniform_matrix<double,3,1>(3)));
1081 
1082             matrix<matrix<double> > m2(2,2);
1083             set_all_elements(m2,uniform_matrix<double,3,1>(1));
1084             DLIB_TEST((round_zeros(variance(m2)) == uniform_matrix<double,3,1>(0)));
1085             DLIB_TEST((round_zeros(mean(m2)) == uniform_matrix<double,3,1>(1)));
1086             m2(0,0) = uniform_matrix<double,3,1>(9);
1087             DLIB_TEST((round_zeros(variance(m2)) == uniform_matrix<double,3,1>(16)));
1088             DLIB_TEST((round_zeros(mean(m2)) == uniform_matrix<double,3,1>(3)));
1089         }
1090 
1091 
1092         {
1093             matrix<double> m(4,4), m2;
1094             m = 1,2,3,4,
1095                 1,2,3,4,
1096                 4,6,8,10,
1097                 4,6,8,10;
1098             m2 = m;
1099 
1100             DLIB_TEST(colm(m,range(0,3)) == m);
1101             DLIB_TEST(rowm(m,range(0,3)) == m);
1102             DLIB_TEST(colm(m,range(0,0)) == colm(m,0));
1103             DLIB_TEST(rowm(m,range(0,0)) == rowm(m,0));
1104             DLIB_TEST(colm(m,range(1,1)) == colm(m,1));
1105             DLIB_TEST(rowm(m,range(1,1)) == rowm(m,1));
1106 
1107             DLIB_TEST(colm(m,range(2,2)) == colm(m,2));
1108             DLIB_TEST(rowm(m,range(2,2)) == rowm(m,2));
1109 
1110             DLIB_TEST(colm(m,range(1,2)) == subm(m,0,1,4,2));
1111             DLIB_TEST(rowm(m,range(1,2)) == subm(m,1,0,2,4));
1112 
1113             set_colm(m,range(1,2)) = 9;
1114             set_subm(m2,0,1,4,2) = 9;
1115             DLIB_TEST(m == m2);
1116 
1117             set_colm(m,range(1,2)) = 11;
1118             set_subm(m2,0,1,4,2) = 11;
1119             DLIB_TEST(m == m2);
1120         }
1121 
1122         {
1123             print_spinner();
1124             matrix<double,1,1> m1;
1125             matrix<double,2,2> m2;
1126             matrix<double,3,3> m3;
1127             matrix<double,4,4> m4;
1128 
1129             dlib::rand rnd;
1130             for (int i = 0; i < 50; ++i)
1131             {
1132                 m1 = randm(1,1,rnd);
1133                 m2 = randm(2,2,rnd);
1134                 m3 = randm(3,3,rnd);
1135                 m4 = randm(4,4,rnd);
1136 
1137                 DLIB_TEST(max(abs(m1*inv(m1) - identity_matrix(m1))) < 1e-13);
1138                 DLIB_TEST(max(abs(m2*inv(m2) - identity_matrix(m2))) < 1e-12);
1139                 DLIB_TEST(max(abs(m3*inv(m3) - identity_matrix(m3))) < 1e-13);
1140                 DLIB_TEST_MSG(max(abs(m4*inv(m4) - identity_matrix(m4))) < 1e-12, max(abs(m4*inv(m4) - identity_matrix(m4))));
1141             }
1142         }
1143 
1144     }
1145 
1146 
1147 
1148 
1149 
1150 
1151     class matrix_tester : public tester
1152     {
1153     public:
matrix_tester()1154         matrix_tester (
1155         ) :
1156             tester ("test_matrix2",
1157                     "Runs tests on the matrix component.")
1158         {}
1159 
perform_test()1160         void perform_test (
1161         )
1162         {
1163             matrix_test1();
1164             matrix_test2();
1165         }
1166     } a;
1167 
1168 }
1169 
1170 
1171