2 // SPDX-License-Identifier: BSD-3-Clause
3 // Copyright Contributors to the OpenEXR Project.
10 #include <ImathInt64.h>
11 #include <ImathMath.h>
12 #include <ImathMatrix.h>
13 #include <ImathMatrixAlgo.h>
14 #include <ImathRandom.h>
18 #include "testMatrix.h"
21 // Include ImathForward *after* other headers to validate forward declarations
22 #include <ImathForward.h>
25 using IMATH_INTERNAL_NAMESPACE::Int64;
28 // This file is not currently intended to exhaustively test
29 // the Imath Matrix33<T> and Matrix44<T> classes. We leave
30 // that to PyImathTest.
32 // Instead, in this file we test only those aspects of the
33 // Imath Matrix33<T> and Matrix44<T> classes that must be
34 // or are more convenient to test from C++.
38 testMatrix22ArrayConstructor(const float a[2][2])
40 IMATH_INTERNAL_NAMESPACE::M22f m(a);
41 assert(m == IMATH_INTERNAL_NAMESPACE::M22f());
45 testMatrix33ArrayConstructor(const float a[3][3])
47 IMATH_INTERNAL_NAMESPACE::M33f m(a);
48 assert(m == IMATH_INTERNAL_NAMESPACE::M33f());
52 testMatrix44ArrayConstructor(const float a[4][4])
54 IMATH_INTERNAL_NAMESPACE::M44f m(a);
55 assert(m == IMATH_INTERNAL_NAMESPACE::M44f());
62 cout << "Testing functions in ImathMatrix.h" << endl;
69 nanf.i = 0x7f800001; // NAN
76 nand.i = 0x7ff0000000000001ULL; // NAN
79 cout << "Imath::M22f constructors and equality operators" << endl;
81 IMATH_INTERNAL_NAMESPACE::M22f m1;
85 const IMATH_INTERNAL_NAMESPACE::M22f test (m1);
88 IMATH_INTERNAL_NAMESPACE::M22f test2;
89 assert (test != test2);
91 IMATH_INTERNAL_NAMESPACE::M22f test3;
93 assert (test2 == test3);
95 const float a[2][2] = {
99 testMatrix22ArrayConstructor(a);
102 assert (m1[0][0] == 42 && m1[0][1] == 42 && m1[1][0] == 42 && m1[1][1] == 42);
104 const float* i1 = test.getValue();
105 assert(i1[0] == 99.0f);
106 assert(i1[3] == 101.0f);
108 float* i2 = m1.getValue();
109 assert(i2[0] == 42.0f);
110 assert(i2[1] == 42.0f);
111 assert(i2[2] == 42.0f);
112 assert(i2[3] == 42.0f);
114 IMATH_INTERNAL_NAMESPACE::M22f test4;
115 test.getValue(test4);
116 assert (test == test4);
118 test4.setTheMatrix(test3);
119 assert(test4 == test3);
123 cout << "M22d constructors and equality operators" << endl;
125 IMATH_INTERNAL_NAMESPACE::M22d m2;
129 IMATH_INTERNAL_NAMESPACE::M22d test (m2);
132 IMATH_INTERNAL_NAMESPACE::M22d test2;
133 assert (test != test2);
135 IMATH_INTERNAL_NAMESPACE::M22d test3;
136 test3.makeIdentity();
137 assert (test2 == test3);
139 IMATH_INTERNAL_NAMESPACE::M22f test4 (1.0f, 2.0f, 3.0f, 4.0f);
141 IMATH_INTERNAL_NAMESPACE::M22d test5 = IMATH_INTERNAL_NAMESPACE::M22d (test4);
143 assert (test5[0][0] == 1.0);
144 assert (test5[0][1] == 2.0);
146 assert (test5[1][0] == 3.0);
147 assert (test5[1][1] == 4.0);
149 const float a[3][3] = {
150 { 1.0f, 0.0f, 0.0f },
151 { 0.0f, 1.0f, 0.0f },
154 testMatrix33ArrayConstructor(a);
158 cout << "M22f inversion operators" << endl;
160 IMATH_INTERNAL_NAMESPACE::M22f m1 (3.0f, 3.0f, 5.0f, 5.0f);
161 IMATH_INTERNAL_NAMESPACE::M22f m2 = m1;
162 assert(m1.inverse(false) == m1.inverse());
167 IMATH_INTERNAL_NAMESPACE::M22f m3 (4.0f, 7.0f, 2.0f, 6.0f);
169 assert(m2.inverse(true) == m2.inverse());
176 cout << "Imath::M33f shear functions" << endl;
178 IMATH_INTERNAL_NAMESPACE::M33f m1, m2;
180 assert (m1[0][0] == 1.0f && m1[0][1] == 0.0f && m1[0][2] == 0.0f && m1[1][0] == 2.0f &&
181 m1[1][1] == 1.0f && m1[1][2] == 0.0f && m1[2][0] == 0.0f && m1[2][1] == 0.0f &&
184 m2.setShear (IMATH_INTERNAL_NAMESPACE::V2f (3.0f, 4.0f));
185 assert (m2[0][0] == 1.0f && m2[0][1] == 4.0f && m2[0][2] == 0.0f && m2[1][0] == 3.0f &&
186 m2[1][1] == 1.0f && m2[1][2] == 0.0f && m2[2][0] == 0.0f && m2[2][1] == 0.0f &&
189 m1.shear (IMATH_INTERNAL_NAMESPACE::V2f (5.0f, 6.0f));
190 assert (m1[0][0] == 13.0f && m1[0][1] == 6.0f && m1[0][2] == 0.0f && m1[1][0] == 7.0f &&
191 m1[1][1] == 1.0f && m1[1][2] == 0.0f && m1[2][0] == 0.0f && m1[2][1] == 0.0f &&
195 assert (m2[0][0] == 1.0f && m2[0][1] == 4.0f && m2[0][2] == 0.0f && m2[1][0] == 10.0f &&
196 m2[1][1] == 29.0f && m2[1][2] == 0.0f && m2[2][0] == 0.0f && m2[2][1] == 0.0f &&
199 cout << "M33f constructors and equality operators" << endl;
201 const IMATH_INTERNAL_NAMESPACE::M33f test (m2);
204 IMATH_INTERNAL_NAMESPACE::M33f test2;
205 assert (test != test2);
207 IMATH_INTERNAL_NAMESPACE::M33f test3;
208 test3.makeIdentity();
209 assert (test2 == test3);
212 assert (m1[0][0] == 42 && m1[0][1] == 42 && m1[0][2] == 42 &&
213 m1[1][0] == 42 && m1[1][1] == 42 && m1[1][2] == 42 &&
214 m1[2][0] == 42 && m1[2][1] == 42 && m1[2][2] == 42);
216 const float* i1 = test.getValue();
217 assert (i1[0] == 1.0f && i1[1] == 4.0f && i1[2] == 0.0f &&
218 i1[3] == 10.0f && i1[4] == 29.0f && i1[5] == 0.0f &&
219 i1[6] == 0.0f && i1[7] == 0.0f && i1[8] == 1.0f);
221 float* i2 = m1.getValue();
222 assert(i2[0] == 42.0f);
223 assert(i2[1] == 42.0f);
224 assert(i2[2] == 42.0f);
225 assert(i2[3] == 42.0f);
227 IMATH_INTERNAL_NAMESPACE::M33f test4;
228 test.getValue(test4);
229 assert (test == test4);
231 test4.setTheMatrix(test3);
232 assert(test4 == test3);
234 IMATH_INTERNAL_NAMESPACE::V3f v(2.0f);
235 IMATH_INTERNAL_NAMESPACE::M33f m(2.0f);
237 assert (IMATH_INTERNAL_NAMESPACE::equal(v[0], 12.0f, 0.0001f));
238 assert (IMATH_INTERNAL_NAMESPACE::equal(v[1], 12.0f, 0.0001f));
239 assert (IMATH_INTERNAL_NAMESPACE::equal(v[2], 12.0f, 0.0001f));
243 cout << "M33f inversion operators" << endl;
245 IMATH_INTERNAL_NAMESPACE::M33f m1 (0.0f, 2.0f, -1.0f, 3.0f, -2.0f, 1.0f, 3.0f, 2.0f, -1.0f);
246 IMATH_INTERNAL_NAMESPACE::M33f m2 = m1;
247 assert(m1.inverse(false) == m1.inverse());
252 IMATH_INTERNAL_NAMESPACE::M33f m3 (1.0f, 0.0f, 5.0f, 2.0f, 1.0f, 6.0f, 3.0f, 4.0f, 0.0f);
254 assert(m3.inverse(true) == m3.inverse());
259 IMATH_INTERNAL_NAMESPACE::M33f m4 (0.0f, 2.0f, -1.0f, 3.0f, -2.0f, 1.0f, 3.0f, 2.0f, -1.0f);
261 assert(m4.gjInverse(false) == m4.gjInverse());
266 IMATH_INTERNAL_NAMESPACE::M33f m5 (1.0f, 0.0f, 5.0f, 2.0f, 1.0f, 6.0f, 3.0f, 4.0f, 0.0f);
268 assert(m5.gjInverse(true) == m5.gjInverse());
275 cout << "M33d constructors and equality operators" << endl;
277 IMATH_INTERNAL_NAMESPACE::M33d m2;
281 IMATH_INTERNAL_NAMESPACE::M33d test (m2);
284 IMATH_INTERNAL_NAMESPACE::M33d test2;
285 assert (test != test2);
287 IMATH_INTERNAL_NAMESPACE::M33d test3;
288 test3.makeIdentity();
289 assert (test2 == test3);
291 IMATH_INTERNAL_NAMESPACE::M33f test4 (1.0f, 2.0f, 3.0f, 4.0f, 5.0f, 6.0f, 7.0f, 8.0f, 9.0f);
293 IMATH_INTERNAL_NAMESPACE::M33d test5 = IMATH_INTERNAL_NAMESPACE::M33d (test4);
295 assert (test5[0][0] == 1.0);
296 assert (test5[0][1] == 2.0);
297 assert (test5[0][2] == 3.0);
299 assert (test5[1][0] == 4.0);
300 assert (test5[1][1] == 5.0);
301 assert (test5[1][2] == 6.0);
303 assert (test5[2][0] == 7.0);
304 assert (test5[2][1] == 8.0);
305 assert (test5[2][2] == 9.0);
309 IMATH_INTERNAL_NAMESPACE::M44f m2;
313 cout << "M44f constructors and equality operators" << endl;
315 IMATH_INTERNAL_NAMESPACE::M44f test (m2);
318 IMATH_INTERNAL_NAMESPACE::M44f test2;
319 assert (test != test2);
321 IMATH_INTERNAL_NAMESPACE::M44f test3;
322 test3.makeIdentity();
323 assert (test2 == test3);
326 // Test non-equality when a NAN is in the same
327 // place in two identical matrices
330 test2[0][0] = nanf.f;
332 assert (test2 != test3);
336 IMATH_INTERNAL_NAMESPACE::M44d m2;
340 cout << "M44d constructors and equality operators" << endl;
342 IMATH_INTERNAL_NAMESPACE::M44d test (m2);
345 IMATH_INTERNAL_NAMESPACE::M44d test2;
346 assert (test != test2);
348 IMATH_INTERNAL_NAMESPACE::M44d test3;
349 test3.makeIdentity();
350 assert (test2 == test3);
352 const float a[4][4] = {
353 { 1.0f, 0.0f, 0.0f, 0.0f },
354 { 0.0f, 1.0f, 0.0f, 0.0f },
355 { 0.0f, 0.0f, 1.0f, 0.0f },
356 { 0.0f, 0.0f, 0.0f, 1.0f }
358 testMatrix44ArrayConstructor(a);
361 // Test non-equality when a NAN is in the same
362 // place in two identical matrices
365 test2[0][0] = nand.d;
367 assert (test2 != test3);
369 IMATH_INTERNAL_NAMESPACE::M44f test4 (1.0f,
386 IMATH_INTERNAL_NAMESPACE::M44d test5 = IMATH_INTERNAL_NAMESPACE::M44d (test4);
388 assert (test5[0][0] == 1.0);
389 assert (test5[0][1] == 2.0);
390 assert (test5[0][2] == 3.0);
391 assert (test5[0][3] == 4.0);
393 assert (test5[1][0] == 5.0);
394 assert (test5[1][1] == 6.0);
395 assert (test5[1][2] == 7.0);
396 assert (test5[1][3] == 8.0);
398 assert (test5[2][0] == 9.0);
399 assert (test5[2][1] == 10.0);
400 assert (test5[2][2] == 11.0);
401 assert (test5[2][3] == 12.0);
403 assert (test5[3][0] == 13.0);
404 assert (test5[3][1] == 14.0);
405 assert (test5[3][2] == 15.0);
406 assert (test5[3][3] == 16.0);
410 cout << "M44f *= operators" << endl;
412 IMATH_INTERNAL_NAMESPACE::V3f v(2.0f);
413 IMATH_INTERNAL_NAMESPACE::M44f m(2.0f);
416 assert (IMATH_INTERNAL_NAMESPACE::equal(v[0], 4.0f, 0.0001f));
417 assert (IMATH_INTERNAL_NAMESPACE::equal(v[1], 4.0f, 0.0001f));
418 assert (IMATH_INTERNAL_NAMESPACE::equal(v[2], 4.0f, 0.0001f));
420 IMATH_INTERNAL_NAMESPACE::V4f v4f(2.0f);
421 IMATH_INTERNAL_NAMESPACE::V4f v4f2 = v4f * m;
423 assert (IMATH_INTERNAL_NAMESPACE::equal(v4f2[0], 4.0f, 0.0001f));
424 assert (IMATH_INTERNAL_NAMESPACE::equal(v4f2[1], 4.0f, 0.0001f));
425 assert (IMATH_INTERNAL_NAMESPACE::equal(v4f2[2], 4.0f, 0.0001f));
426 assert (IMATH_INTERNAL_NAMESPACE::equal(v4f2[3], 2.0f, 0.0001f));
429 assert (v4f == v4f2);
431 IMATH_INTERNAL_NAMESPACE::M44f a(2.0f);
432 IMATH_INTERNAL_NAMESPACE::M44f b(3.0f);
433 IMATH_INTERNAL_NAMESPACE::M44f c;
435 IMATH_INTERNAL_NAMESPACE::M44f::multiply(a, b, c);
436 assert (IMATH_INTERNAL_NAMESPACE::equal(c[0][0], 24.0f, 0.0001f));
437 assert (IMATH_INTERNAL_NAMESPACE::equal(c[1][1], 24.0f, 0.0001f));
438 assert (IMATH_INTERNAL_NAMESPACE::equal(c[2][2], 24.0f, 0.0001f));
439 assert (IMATH_INTERNAL_NAMESPACE::equal(c[3][3], 24.0f, 0.0001f));
442 cout << "Matrix << operators" << endl;
446 s << IMATH_INTERNAL_NAMESPACE::identity22f;
447 const char v[] = "( 1.000000e+00 0.000000e+00\n 0.000000e+00 1.000000e+00)\n";
448 assert (s.str() == v);
453 s << IMATH_INTERNAL_NAMESPACE::identity33f;
454 const char v[] = "( 1.000000e+00 0.000000e+00 0.000000e+00\n 0.000000e+00 1.000000e+00 0.000000e+00\n 0.000000e+00 0.000000e+00 1.000000e+00)\n";
455 assert (s.str() == v);
460 s << IMATH_INTERNAL_NAMESPACE::identity44f;
461 const char v[] = "( 1.000000e+00 0.000000e+00 0.000000e+00 0.000000e+00\n 0.000000e+00 1.000000e+00 0.000000e+00 0.000000e+00\n 0.000000e+00 0.000000e+00 1.000000e+00 0.000000e+00\n 0.000000e+00 0.000000e+00 0.000000e+00 1.000000e+00)\n";
462 assert (s.str() == v);
466 cout << "M44f inversion operators" << endl;
468 IMATH_INTERNAL_NAMESPACE::M44f m1 (1.0f,
484 IMATH_INTERNAL_NAMESPACE::M44f m2 = m1;
485 assert(m1.inverse(false) == m1.inverse());
490 IMATH_INTERNAL_NAMESPACE::M44f m3 (5.0f,
507 assert(m3.inverse(true) == m3.inverse());
512 IMATH_INTERNAL_NAMESPACE::M44f m4 (1.0f,
529 assert(m4.gjInverse(false) == m4.gjInverse());
534 IMATH_INTERNAL_NAMESPACE::M44f m5 (5.0f,
551 assert(m5.gjInverse(true) == m5.gjInverse());
558 cout << "Converting between M33 and M44" << endl;
560 IMATH_INTERNAL_NAMESPACE::M44d m1;
562 IMATH_INTERNAL_NAMESPACE::M44f m2;
564 assert (m2[0][0] == (float) m1[0][0]);
567 assert (m2[0][0] == (float) m1[0][0]);
572 cout << "3x3 Matrix minors" << endl;
574 IMATH_INTERNAL_NAMESPACE::M33f a (1, 2, 3, 4, 5, 6, 7, 8, 9);
576 assert (a.minorOf (0, 0) == a.fastMinor (1, 2, 1, 2));
577 assert (a.minorOf (0, 1) == a.fastMinor (1, 2, 0, 2));
578 assert (a.minorOf (0, 2) == a.fastMinor (1, 2, 0, 1));
579 assert (a.minorOf (1, 0) == a.fastMinor (0, 2, 1, 2));
580 assert (a.minorOf (1, 1) == a.fastMinor (0, 2, 0, 2));
581 assert (a.minorOf (1, 2) == a.fastMinor (0, 2, 0, 1));
582 assert (a.minorOf (2, 0) == a.fastMinor (0, 1, 1, 2));
583 assert (a.minorOf (2, 1) == a.fastMinor (0, 1, 0, 2));
584 assert (a.minorOf (2, 2) == a.fastMinor (0, 1, 0, 1));
587 IMATH_INTERNAL_NAMESPACE::M33d a (1, 2, 3, 4, 5, 6, 7, 8, 9);
589 assert (a.minorOf (0, 0) == a.fastMinor (1, 2, 1, 2));
590 assert (a.minorOf (0, 1) == a.fastMinor (1, 2, 0, 2));
591 assert (a.minorOf (0, 2) == a.fastMinor (1, 2, 0, 1));
592 assert (a.minorOf (1, 0) == a.fastMinor (0, 2, 1, 2));
593 assert (a.minorOf (1, 1) == a.fastMinor (0, 2, 0, 2));
594 assert (a.minorOf (1, 2) == a.fastMinor (0, 2, 0, 1));
595 assert (a.minorOf (2, 0) == a.fastMinor (0, 1, 1, 2));
596 assert (a.minorOf (2, 1) == a.fastMinor (0, 1, 0, 2));
597 assert (a.minorOf (2, 2) == a.fastMinor (0, 1, 0, 1));
600 // Determinants (by building a random singular value decomposition)
603 cout << "2x2 determinant" << endl;
605 IMATH_INTERNAL_NAMESPACE::Rand32 random;
607 IMATH_INTERNAL_NAMESPACE::M22f u;
608 IMATH_INTERNAL_NAMESPACE::M22f v;
609 IMATH_INTERNAL_NAMESPACE::M22f s;
611 u.setRotation (random.nextf());
612 v.setRotation (random.nextf());
613 s[0][0] = random.nextf();
614 s[1][1] = random.nextf();
616 IMATH_INTERNAL_NAMESPACE::M22f c = u * s * v.transpose();
617 assert (fabsf (c.determinant() - s[0][0] * s[1][1]) <= u.baseTypeEpsilon());
620 IMATH_INTERNAL_NAMESPACE::Rand32 random;
622 IMATH_INTERNAL_NAMESPACE::M22d u;
623 IMATH_INTERNAL_NAMESPACE::M22d v;
624 IMATH_INTERNAL_NAMESPACE::M22d s;
626 u.setRotation ((double) random.nextf());
627 v.setRotation ((double) random.nextf());
628 s[0][0] = (double) random.nextf();
629 s[1][1] = (double) random.nextf();
631 IMATH_INTERNAL_NAMESPACE::M22d c = u * s * v.transpose();
632 assert (fabs (c.determinant() - s[0][0] * s[1][1]) <= u.baseTypeEpsilon());
636 cout << "3x3 determinant" << endl;
638 IMATH_INTERNAL_NAMESPACE::Rand32 random;
640 IMATH_INTERNAL_NAMESPACE::M33f u;
641 IMATH_INTERNAL_NAMESPACE::M33f v;
642 IMATH_INTERNAL_NAMESPACE::M33f s;
644 u.setRotation (random.nextf());
645 v.setRotation (random.nextf());
646 s[0][0] = random.nextf();
647 s[1][1] = random.nextf();
648 s[2][2] = random.nextf();
650 IMATH_INTERNAL_NAMESPACE::M33f c = u * s * v.transpose();
651 assert (fabsf (c.determinant() - s[0][0] * s[1][1] * s[2][2]) <= u.baseTypeEpsilon());
654 IMATH_INTERNAL_NAMESPACE::Rand32 random;
656 IMATH_INTERNAL_NAMESPACE::M33d u;
657 IMATH_INTERNAL_NAMESPACE::M33d v;
658 IMATH_INTERNAL_NAMESPACE::M33d s;
660 u.setRotation ((double) random.nextf());
661 v.setRotation ((double) random.nextf());
662 s[0][0] = (double) random.nextf();
663 s[1][1] = (double) random.nextf();
664 s[2][2] = (double) random.nextf();
666 IMATH_INTERNAL_NAMESPACE::M33d c = u * s * v.transpose();
667 assert (fabs (c.determinant() - s[0][0] * s[1][1] * s[2][2]) <= u.baseTypeEpsilon());
670 // Outer product of two 3D vectors
672 cout << "Outer product of two 3D vectors" << endl;
674 IMATH_INTERNAL_NAMESPACE::V3f a (1, 2, 3);
675 IMATH_INTERNAL_NAMESPACE::V3f b (4, 5, 6);
676 IMATH_INTERNAL_NAMESPACE::M33f p = IMATH_INTERNAL_NAMESPACE::outerProduct (a, b);
678 for (int i = 0; i < 3; i++)
680 for (int j = 0; j < 3; j++)
682 assert (p[i][j] == a[i] * b[j]);
687 IMATH_INTERNAL_NAMESPACE::V3d a (1, 2, 3);
688 IMATH_INTERNAL_NAMESPACE::V3d b (4, 5, 6);
689 IMATH_INTERNAL_NAMESPACE::M33d p = IMATH_INTERNAL_NAMESPACE::outerProduct (a, b);
691 for (int i = 0; i < 3; i++)
693 for (int j = 0; j < 3; j++)
695 assert (p[i][j] == a[i] * b[j]);
700 // Determinants (by building a random singular value decomposition)
702 cout << "4x4 determinants" << endl;
704 IMATH_INTERNAL_NAMESPACE::Rand32 random;
706 IMATH_INTERNAL_NAMESPACE::M44f u = IMATH_INTERNAL_NAMESPACE::rotationMatrix (
707 IMATH_INTERNAL_NAMESPACE::V3f (random.nextf(), random.nextf(), random.nextf())
709 IMATH_INTERNAL_NAMESPACE::V3f (random.nextf(), random.nextf(), random.nextf())
711 IMATH_INTERNAL_NAMESPACE::M44f v = IMATH_INTERNAL_NAMESPACE::rotationMatrix (
712 IMATH_INTERNAL_NAMESPACE::V3f (random.nextf(), random.nextf(), random.nextf())
714 IMATH_INTERNAL_NAMESPACE::V3f (random.nextf(), random.nextf(), random.nextf())
716 IMATH_INTERNAL_NAMESPACE::M44f s;
718 s[0][0] = random.nextf();
719 s[1][1] = random.nextf();
720 s[2][2] = random.nextf();
721 s[3][3] = random.nextf();
723 IMATH_INTERNAL_NAMESPACE::M44f c = u * s * v.transpose();
724 assert (fabsf (c.determinant() - s[0][0] * s[1][1] * s[2][2] * s[3][3]) <=
725 u.baseTypeEpsilon());
728 IMATH_INTERNAL_NAMESPACE::Rand32 random;
730 IMATH_INTERNAL_NAMESPACE::M44d u = IMATH_INTERNAL_NAMESPACE::rotationMatrix (
731 IMATH_INTERNAL_NAMESPACE::V3d (random.nextf(), random.nextf(), random.nextf())
733 IMATH_INTERNAL_NAMESPACE::V3d (random.nextf(), random.nextf(), random.nextf())
735 IMATH_INTERNAL_NAMESPACE::M44d v = IMATH_INTERNAL_NAMESPACE::rotationMatrix (
736 IMATH_INTERNAL_NAMESPACE::V3d (random.nextf(), random.nextf(), random.nextf())
738 IMATH_INTERNAL_NAMESPACE::V3d (random.nextf(), random.nextf(), random.nextf())
740 IMATH_INTERNAL_NAMESPACE::M44d s;
742 s[0][0] = random.nextf();
743 s[1][1] = random.nextf();
744 s[2][2] = random.nextf();
745 s[3][3] = random.nextf();
747 IMATH_INTERNAL_NAMESPACE::M44d c = u * s * v.transpose();
748 assert (fabs (c.determinant() - s[0][0] * s[1][1] * s[2][2] * s[3][3]) <=
749 u.baseTypeEpsilon());
754 cout << "2x2 trace" << endl;
756 IMATH_INTERNAL_NAMESPACE::Rand32 random;
758 IMATH_INTERNAL_NAMESPACE::M22f u;
760 for (int i = 0; i < 2; i++)
762 for (int j = 0; j < 2; j++)
764 const float randomNum = random.nextf ();
766 if (i == j) { trace += randomNum; }
770 assert (fabsf (u.trace () - trace) <= u.baseTypeEpsilon ());
773 IMATH_INTERNAL_NAMESPACE::Rand32 random;
775 IMATH_INTERNAL_NAMESPACE::M22d u;
777 for (int i = 0; i < 2; i++)
779 for (int j = 0; j < 2; j++)
781 const double randomNum = random.nextf ();
783 if (i == j) { trace += randomNum; }
787 assert (fabs (u.trace () - trace) <= u.baseTypeEpsilon ());
790 cout << "3x3 trace" << endl;
792 IMATH_INTERNAL_NAMESPACE::Rand32 random;
794 IMATH_INTERNAL_NAMESPACE::M33f u;
796 for (int i = 0; i < 3; i++)
798 for (int j = 0; j < 3; j++)
800 const float randomNum = random.nextf ();
802 if (i == j) { trace += randomNum; }
806 assert (fabsf (u.trace () - trace) <= u.baseTypeEpsilon ());
809 IMATH_INTERNAL_NAMESPACE::Rand32 random;
811 IMATH_INTERNAL_NAMESPACE::M33d u;
813 for (int i = 0; i < 3; i++)
815 for (int j = 0; j < 3; j++)
817 const double randomNum = random.nextf ();
819 if (i == j) { trace += randomNum; }
823 assert (fabs (u.trace () - trace) <= u.baseTypeEpsilon ());
826 cout << "4x4 trace" << endl;
828 IMATH_INTERNAL_NAMESPACE::Rand32 random;
830 IMATH_INTERNAL_NAMESPACE::M44f u;
832 for (int i = 0; i < 4; i++)
834 for (int j = 0; j < 4; j++)
836 const float randomNum = random.nextf ();
838 if (i == j) { trace += randomNum; }
842 assert (fabsf (u.trace () - trace) <= u.baseTypeEpsilon ());
845 IMATH_INTERNAL_NAMESPACE::Rand32 random;
847 IMATH_INTERNAL_NAMESPACE::M44d u;
849 for (int i = 0; i < 4; i++)
851 for (int j = 0; j < 4; j++)
853 const double randomNum = random.nextf ();
855 if (i == j) { trace += randomNum; }
859 assert (fabs (u.trace () - trace) <= u.baseTypeEpsilon ());
864 cout << "4x4 matrix minors" << endl;
866 IMATH_INTERNAL_NAMESPACE::M44d a (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
868 assert (a.minorOf (0, 0) == a.fastMinor (1, 2, 3, 1, 2, 3));
869 assert (a.minorOf (0, 1) == a.fastMinor (1, 2, 3, 0, 2, 3));
870 assert (a.minorOf (0, 2) == a.fastMinor (1, 2, 3, 0, 1, 3));
871 assert (a.minorOf (0, 3) == a.fastMinor (1, 2, 3, 0, 1, 2));
872 assert (a.minorOf (1, 0) == a.fastMinor (0, 2, 3, 1, 2, 3));
873 assert (a.minorOf (1, 1) == a.fastMinor (0, 2, 3, 0, 2, 3));
874 assert (a.minorOf (1, 2) == a.fastMinor (0, 2, 3, 0, 1, 3));
875 assert (a.minorOf (1, 3) == a.fastMinor (0, 2, 3, 0, 1, 2));
876 assert (a.minorOf (2, 0) == a.fastMinor (0, 1, 3, 1, 2, 3));
877 assert (a.minorOf (2, 1) == a.fastMinor (0, 1, 3, 0, 2, 3));
878 assert (a.minorOf (2, 2) == a.fastMinor (0, 1, 3, 0, 1, 3));
879 assert (a.minorOf (2, 3) == a.fastMinor (0, 1, 3, 0, 1, 2));
880 assert (a.minorOf (3, 0) == a.fastMinor (0, 1, 2, 1, 2, 3));
881 assert (a.minorOf (3, 1) == a.fastMinor (0, 1, 2, 0, 2, 3));
882 assert (a.minorOf (3, 2) == a.fastMinor (0, 1, 2, 0, 1, 3));
883 assert (a.minorOf (3, 3) == a.fastMinor (0, 1, 2, 0, 1, 2));
886 IMATH_INTERNAL_NAMESPACE::M44f a (1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16);
888 assert (a.minorOf (0, 0) == a.fastMinor (1, 2, 3, 1, 2, 3));
889 assert (a.minorOf (0, 1) == a.fastMinor (1, 2, 3, 0, 2, 3));
890 assert (a.minorOf (0, 2) == a.fastMinor (1, 2, 3, 0, 1, 3));
891 assert (a.minorOf (0, 3) == a.fastMinor (1, 2, 3, 0, 1, 2));
892 assert (a.minorOf (1, 0) == a.fastMinor (0, 2, 3, 1, 2, 3));
893 assert (a.minorOf (1, 1) == a.fastMinor (0, 2, 3, 0, 2, 3));
894 assert (a.minorOf (1, 2) == a.fastMinor (0, 2, 3, 0, 1, 3));
895 assert (a.minorOf (1, 3) == a.fastMinor (0, 2, 3, 0, 1, 2));
896 assert (a.minorOf (2, 0) == a.fastMinor (0, 1, 3, 1, 2, 3));
897 assert (a.minorOf (2, 1) == a.fastMinor (0, 1, 3, 0, 2, 3));
898 assert (a.minorOf (2, 2) == a.fastMinor (0, 1, 3, 0, 1, 3));
899 assert (a.minorOf (2, 3) == a.fastMinor (0, 1, 3, 0, 1, 2));
900 assert (a.minorOf (3, 0) == a.fastMinor (0, 1, 2, 1, 2, 3));
901 assert (a.minorOf (3, 1) == a.fastMinor (0, 1, 2, 0, 2, 3));
902 assert (a.minorOf (3, 2) == a.fastMinor (0, 1, 2, 0, 1, 3));
903 assert (a.minorOf (3, 3) == a.fastMinor (0, 1, 2, 0, 1, 2));
906 // VC 2005 64 bits compiler has a bug with __restrict keword.
907 // Pointers with __restrict should not alias the same symbol.
908 // But, with optimization on, VC removes intermediate temp variable
909 // and ignores __restrict.
911 cout << "M44 multiplicaftion test" << endl;
912 IMATH_INTERNAL_NAMESPACE::M44f M (1.0f,
929 IMATH_INTERNAL_NAMESPACE::M44f N;
932 // N should be equal to M
933 // This typical test fails
934 // when __restrict is used for pointers in "multiply" function.
941 cout << "M44 multiplication test has failed, error." << endl
949 cout << "ok\n" << endl;