Blender V4.3
numeric_test.cc
Go to the documentation of this file.
1// Copyright (c) 2007, 2008 libmv authors.
2//
3// Permission is hereby granted, free of charge, to any person obtaining a copy
4// of this software and associated documentation files (the "Software"), to
5// deal in the Software without restriction, including without limitation the
6// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
7// sell copies of the Software, and to permit persons to whom the Software is
8// furnished to do so, subject to the following conditions:
9//
10// The above copyright notice and this permission notice shall be included in
11// all copies or substantial portions of the Software.
12//
13// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
18// FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
19// IN THE SOFTWARE.
20
22#include "testing/testing.h"
23
24using namespace libmv;
25
26namespace {
27
28TEST(Numeric, DynamicSizedNullspace) {
29 Mat A(3, 4);
30 // clang-format off
31 A << 0.76026643, 0.01799744, 0.55192142, 0.8699745,
32 0.42016166, 0.97863392, 0.33711682, 0.14479271,
33 0.51016811, 0.66528302, 0.54395496, 0.57794893;
34 // clang-format on
35 Vec x;
36 double s = Nullspace(&A, &x);
37 EXPECT_NEAR(0.0, s, 1e-15);
38 EXPECT_NEAR(0.0, (A * x).norm(), 1e-15);
39 EXPECT_NEAR(1.0, x.norm(), 1e-15);
40}
41
42TEST(Numeric, FixedSizeMatrixNullspace) {
43 Mat34 A;
44 // clang-format off
45 A << 0.76026643, 0.01799744, 0.55192142, 0.8699745,
46 0.42016166, 0.97863392, 0.33711682, 0.14479271,
47 0.51016811, 0.66528302, 0.54395496, 0.57794893;
48 // clang-format on
49 Vec x;
50 double s = Nullspace(&A, &x);
51 EXPECT_NEAR(0.0, s, 1e-15);
52 EXPECT_NEAR(0.0, (A * x).norm(), 1e-15);
53 EXPECT_NEAR(1.0, x.norm(), 1e-15);
54}
55
56TEST(Numeric, NullspaceMatchesLapackSVD) {
57 Mat43 A;
58 // clang-format off
59 A << 0.76026643, 0.01799744, 0.55192142,
60 0.8699745, 0.42016166, 0.97863392,
61 0.33711682, 0.14479271, 0.51016811,
62 0.66528302, 0.54395496, 0.57794893;
63 // clang-format on
64 Vec x;
65 double s = Nullspace(&A, &x);
66 EXPECT_NEAR(1.0, x.norm(), 1e-15);
67 EXPECT_NEAR(0.206694992663, s, 1e-9);
68 EXPECT_NEAR(0.206694992663, (A * x).norm(), 1e-9);
69
70 EXPECT_NEAR(-0.64999717, x(0), 1e-8);
71 EXPECT_NEAR(-0.18452646, x(1), 1e-8);
72 EXPECT_NEAR(0.7371931, x(2), 1e-8);
73}
74
75TEST(Numeric, Nullspace2) {
76 Mat43 A;
77 // clang-format off
78 A << 0.76026643, 0.01799744, 0.55192142,
79 0.8699745, 0.42016166, 0.97863392,
80 0.33711682, 0.14479271, 0.51016811,
81 0.66528302, 0.54395496, 0.57794893;
82 // clang-format on
83 Vec3 x1, x2;
84 double s = Nullspace2(&A, &x1, &x2);
85 EXPECT_NEAR(1.0, x1.norm(), 1e-15);
86 EXPECT_NEAR(0.206694992663, s, 1e-9);
87 EXPECT_NEAR(0.206694992663, (A * x1).norm(), 1e-9);
88
89 EXPECT_NEAR(-0.64999717, x1(0), 1e-8);
90 EXPECT_NEAR(-0.18452646, x1(1), 1e-8);
91 EXPECT_NEAR(0.7371931, x1(2), 1e-8);
92
93 if (x2(0) < 0) {
94 x2 *= -1;
95 }
96 EXPECT_NEAR(0.34679618, x2(0), 1e-8);
97 EXPECT_NEAR(-0.93519689, x2(1), 1e-8);
98 EXPECT_NEAR(0.07168809, x2(2), 1e-8);
99}
100
101TEST(Numeric, TinyMatrixSquareTranspose) {
102 Mat2 A;
103 A << 1.0, 2.0, 3.0, 4.0;
105 EXPECT_EQ(1.0, A(0, 0));
106 EXPECT_EQ(3.0, A(0, 1));
107 EXPECT_EQ(2.0, A(1, 0));
108 EXPECT_EQ(4.0, A(1, 1));
109}
110
111TEST(Numeric, NormalizeL1) {
112 Vec2 x;
113 x << 1, 2;
114 double l1 = NormalizeL1(&x);
115 EXPECT_DOUBLE_EQ(3., l1);
116 EXPECT_DOUBLE_EQ(1. / 3., x(0));
117 EXPECT_DOUBLE_EQ(2. / 3., x(1));
118}
119
120TEST(Numeric, NormalizeL2) {
121 Vec2 x;
122 x << 1, 2;
123 double l2 = NormalizeL2(&x);
124 EXPECT_DOUBLE_EQ(sqrt(5.0), l2);
125 EXPECT_DOUBLE_EQ(1. / sqrt(5.), x(0));
126 EXPECT_DOUBLE_EQ(2. / sqrt(5.), x(1));
127}
128
129TEST(Numeric, Diag) {
130 Vec x(2);
131 x << 1, 2;
132 Mat D = Diag(x);
133 EXPECT_EQ(1, D(0, 0));
134 EXPECT_EQ(0, D(0, 1));
135 EXPECT_EQ(0, D(1, 0));
136 EXPECT_EQ(2, D(1, 1));
137}
138
139TEST(Numeric, Determinant) {
140 Mat A(2, 2);
141 A << 1, 2, -1, 3;
142 double detA = A.determinant();
143 EXPECT_NEAR(5, detA, 1e-8);
144
145 Mat B(4, 4);
146 // clang-format off
147 B << 0, 1, 2, 3,
148 4, 5, 6, 7,
149 8, 9, 10, 11,
150 12, 13, 14, 15;
151 // clang-format on
152 double detB = B.determinant();
153 EXPECT_NEAR(0, detB, 1e-8);
154
155 Mat3 C;
156 C << 0, 1, 2, 3, 4, 5, 6, 7, 1;
157 double detC = C.determinant();
158 EXPECT_NEAR(21, detC, 1e-8);
159}
160
161TEST(Numeric, Inverse) {
162 Mat A(2, 2), A1;
163 // clang-format off
164 A << 1, 2,
165 -1, 3;
166 // clang-format on
167 Mat I = A * A.inverse();
168
169 EXPECT_NEAR(1, I(0, 0), 1e-8);
170 EXPECT_NEAR(0, I(0, 1), 1e-8);
171 EXPECT_NEAR(0, I(1, 0), 1e-8);
172 EXPECT_NEAR(1, I(1, 1), 1e-8);
173
174 Mat B(4, 4), B1;
175 // clang-format off
176 B << 0, 1, 2, 3,
177 4, 5, 6, 7,
178 8, 9, 2, 11,
179 12, 13, 14, 4;
180 // clang-format on
181 Mat I2 = B * B.inverse();
182 EXPECT_NEAR(1, I2(0, 0), 1e-8);
183 EXPECT_NEAR(0, I2(0, 1), 1e-8);
184 EXPECT_NEAR(0, I2(0, 2), 1e-8);
185 EXPECT_NEAR(0, I2(1, 0), 1e-8);
186 EXPECT_NEAR(1, I2(1, 1), 1e-8);
187 EXPECT_NEAR(0, I2(1, 2), 1e-8);
188 EXPECT_NEAR(0, I2(2, 0), 1e-8);
189 EXPECT_NEAR(0, I2(2, 1), 1e-8);
190 EXPECT_NEAR(1, I2(2, 2), 1e-8);
191}
192
194 int n = 4;
195 Mat points(2, n);
196 // clang-format off
197 points << 0, 0, 1, 1,
198 0, 2, 1, 3;
199 // clang-format on
200
201 Vec mean, variance;
202 MeanAndVarianceAlongRows(points, &mean, &variance);
203
204 EXPECT_NEAR(0.5, mean(0), 1e-8);
205 EXPECT_NEAR(1.5, mean(1), 1e-8);
206 EXPECT_NEAR(0.25, variance(0), 1e-8);
207 EXPECT_NEAR(1.25, variance(1), 1e-8);
208}
209
210TEST(Numeric, HorizontalStack) {
211 Mat x(2, 1), y(2, 1), z;
212 x << 1, 2;
213 y << 3, 4;
214
215 HorizontalStack(x, y, &z);
216
217 EXPECT_EQ(2, z.cols());
218 EXPECT_EQ(2, z.rows());
219 EXPECT_EQ(1, z(0, 0));
220 EXPECT_EQ(2, z(1, 0));
221 EXPECT_EQ(3, z(0, 1));
222 EXPECT_EQ(4, z(1, 1));
223}
224
225TEST(Numeric, HStack) {
226 Mat x(2, 1), y(2, 1), z(2, 2);
227 x << 1, 2;
228 y << 3, 4;
229 // clang-format off
230 z << 1, 3,
231 2, 4;
232 // clang-format on
233 Vec2 xC = x, yC = y;
234
235 Mat2 xy = HStack(x, y);
236 EXPECT_MATRIX_EQ(z, xy);
237
238 EXPECT_MATRIX_EQ(z, HStack(x, y));
239 EXPECT_MATRIX_EQ(z, HStack(x, yC));
240 EXPECT_MATRIX_EQ(z, HStack(xC, y));
241 EXPECT_MATRIX_EQ(z, HStack(xC, yC));
242}
243
244// TODO(keir): Need some way of verifying that the compile time types of the
245// resulting stacked matrices properly propagate the fixed dimensions.
246TEST(Numeric, VStack) {
247 Mat x(2, 2), y(2, 2), z(4, 2);
248 // clang-format off
249 x << 1, 2,
250 3, 4;
251 y << 10, 20,
252 30, 40;
253 z << 1, 2,
254 3, 4,
255 10, 20,
256 30, 40;
257 // clang-format on
258 Mat2 xC = x, yC = y;
259
260 Mat xy = VStack(x, y);
261 EXPECT_MATRIX_EQ(z, xy);
262
263 EXPECT_MATRIX_EQ(z, VStack(x, y));
264 EXPECT_MATRIX_EQ(z, VStack(x, yC));
265 EXPECT_MATRIX_EQ(z, VStack(xC, y));
266 EXPECT_MATRIX_EQ(z, VStack(xC, yC));
267}
268
269TEST(Numeric, VerticalStack) {
270 Mat x(1, 2), y(1, 2), z;
271 x << 1, 2;
272 y << 3, 4;
273 VerticalStack(x, y, &z);
274
275 EXPECT_EQ(2, z.cols());
276 EXPECT_EQ(2, z.rows());
277 EXPECT_EQ(1, z(0, 0));
278 EXPECT_EQ(2, z(0, 1));
279 EXPECT_EQ(3, z(1, 0));
280 EXPECT_EQ(4, z(1, 1));
281}
282
283TEST(Numeric, CrossProduct) {
284 Vec3 x, y, z;
285 x << 1, 0, 0;
286 y << 0, 1, 0;
287 z << 0, 0, 1;
288 Vec3 xy = CrossProduct(x, y);
289 Vec3 yz = CrossProduct(y, z);
290 Vec3 zx = CrossProduct(z, x);
291 EXPECT_NEAR(0, DistanceLInfinity(xy, z), 1e-8);
292 EXPECT_NEAR(0, DistanceLInfinity(yz, x), 1e-8);
293 EXPECT_NEAR(0, DistanceLInfinity(zx, y), 1e-8);
294}
295
296TEST(Numeric, CrossProductMatrix) {
297 Vec3 x, y;
298 x << 1, 2, 3;
299 y << 2, 3, 4;
300 Vec3 xy = CrossProduct(x, y);
301 Vec3 yx = CrossProduct(y, x);
303 Vec3 Xy, Xty;
304 Xy = X * y;
305 Xty = X.transpose() * y;
306 EXPECT_NEAR(0, DistanceLInfinity(xy, Xy), 1e-8);
307 EXPECT_NEAR(0, DistanceLInfinity(yx, Xty), 1e-8);
308}
309
310TEST(Numeric, MatrixColumn) {
311 Mat A2(2, 3);
312 Vec2 v2;
313 // clang-format off
314 A2 << 1, 2, 3,
315 4, 5, 6;
316 // clang-format on
317 MatrixColumn(A2, 1, &v2);
318 EXPECT_EQ(2, v2(0));
319 EXPECT_EQ(5, v2(1));
320
321 Mat A3(3, 3);
322 Vec3 v3;
323 // clang-format off
324 A3 << 1, 2, 3,
325 4, 5, 6,
326 7, 8, 9;
327 // clang-format on
328 MatrixColumn(A3, 1, &v3);
329 EXPECT_EQ(2, v3(0));
330 EXPECT_EQ(5, v3(1));
331 EXPECT_EQ(8, v3(2));
332
333 Mat A4(4, 3);
334 Vec4 v4;
335 // clang-format off
336 A4 << 1, 2, 3,
337 4, 5, 6,
338 7, 8, 9,
339 10, 11, 12;
340 // clang-format on
341 MatrixColumn(A4, 1, &v4);
342 EXPECT_EQ(2, v4(0));
343 EXPECT_EQ(5, v4(1));
344 EXPECT_EQ(8, v4(2));
345 EXPECT_EQ(11, v4(3));
346}
347
348// This used to give a compile error with FLENS.
349TEST(Numeric, TinyMatrixView) {
350 Mat34 P;
351 Mat K = P.block(0, 0, 3, 3);
352}
353
354// This gives a compile error.
355TEST(Numeric, Mat3MatProduct) {
356 Mat3 A;
357 Mat3 B;
358 Mat C = A * B;
359}
360
361// This gives a compile error.
362TEST(Numeric, Vec3Negative) {
363 Vec3 y;
364 y << 1, 2, 3;
365 Vec3 x = -y;
366 EXPECT_EQ(-1, x(0));
367 EXPECT_EQ(-2, x(1));
368 EXPECT_EQ(-3, x(2));
369}
370
371// This gives a compile error.
372TEST(Numeric, Vec3VecInteroperability) {
373 Vec y(3);
374 y << 1, 2, 3;
375 Vec3 x = y + y;
376 EXPECT_EQ(2, x(0));
377 EXPECT_EQ(4, x(1));
378 EXPECT_EQ(6, x(2));
379}
380
381// This segfaults inside lapack.
382TEST(Numeric, DeterminantLU7) {
383 Mat A(5, 5);
384 // clang-format off
385 A << 1, 0, 0, 0, 0,
386 0, 1, 0, 0, 0,
387 0, 0, 1, 0, 0,
388 0, 0, 0, 1, 0,
389 0, 0, 0, 0, 1;
390 // clang-format on
391 EXPECT_NEAR(1, A.determinant(), 1e-8);
392}
393
394// This segfaults inside lapack.
395TEST(Numeric, DeterminantLU) {
396 Mat A(2, 2);
397 // clang-format off
398 A << 1, 2,
399 -1, 3;
400 // clang-format on
401 EXPECT_NEAR(5, A.determinant(), 1e-8);
402}
403
404// This does unexpected things.
405// Keir: Not with eigen2!
406TEST(Numeric, InplaceProduct) {
407 Mat2 K, S;
408 // clang-format off
409 K << 1, 0,
410 0, 1;
411 S << 1, 0,
412 0, 1;
413 K = K * S;
414 // clang-format on
415 EXPECT_MATRIX_NEAR(Mat2::Identity(), K, 1e-8);
416}
417
418TEST(Numeric, ExtractColumns) {
419 Mat2X A(2, 5);
420 // clang-format off
421 A << 1, 2, 3, 4, 5,
422 6, 7, 8, 9, 10;
423 // clang-format on
424 Vec2i columns;
425 columns << 0, 2;
426 Mat2X extracted = ExtractColumns(A, columns);
427 EXPECT_NEAR(1, extracted(0, 0), 1e-15);
428 EXPECT_NEAR(3, extracted(0, 1), 1e-15);
429 EXPECT_NEAR(6, extracted(1, 0), 1e-15);
430 EXPECT_NEAR(8, extracted(1, 1), 1e-15);
431}
432
433TEST(Numeric, RotationRodrigues) {
434 Vec3 x, y, z;
435 x << 1, 0, 0;
436 y << 0, 1, 0;
437 z << 0, 0, 1;
438
439 Mat3 rodrigues_x = RotationRodrigues(x);
440 Mat3 rodrigues_y = RotationRodrigues(y);
441 Mat3 rodrigues_z = RotationRodrigues(z);
442
443 Mat3 Rx = RotationAroundX(1);
444 Mat3 Ry = RotationAroundY(1);
445 Mat3 Rz = RotationAroundZ(1);
446
447 EXPECT_MATRIX_NEAR(Rx, rodrigues_x, 1e-15);
448 EXPECT_MATRIX_NEAR(Ry, rodrigues_y, 1e-15);
449 EXPECT_MATRIX_NEAR(Rz, rodrigues_z, 1e-15);
450}
451
452TEST(Numeric, LookAt) {
453 // Simple orthogonality check.
454 Vec3 e;
455 e << 1, 2, 3;
456 Mat3 R = LookAt(e), I = Mat3::Identity();
457 Mat3 RRT = R * R.transpose();
458 Mat3 RTR = R.transpose() * R;
459
460 EXPECT_MATRIX_NEAR(I, RRT, 1e-15);
461 EXPECT_MATRIX_NEAR(I, RTR, 1e-15);
462}
463
464TEST(Numeric, Reshape) {
465 Vec4 x;
466 x << 1, 2, 3, 4;
467 Mat2 M, M_expected;
468 reshape(x, 2, 2, &M);
469 M_expected << 1, 2, 3, 4;
470 EXPECT_MATRIX_NEAR(M_expected, M, 1e-15);
471}
472
473} // namespace
#define D
sqrt(x)+1/max(0
EXPECT_EQ(BLI_expr_pylike_eval(expr, nullptr, 0, &result), EXPR_PYLIKE_INVALID)
#define K(key)
#define X
#define A2
Definition RandGen.cpp:28
#define C
Definition RandGen.cpp:29
#define A1
Definition RandGen.cpp:27
ATTR_WARN_UNUSED_RESULT const BMVert * v2
ATTR_WARN_UNUSED_RESULT const BMVert const BMEdge * e
#define A
SIMD_FORCE_INLINE const btScalar & z() const
Return the z value.
Definition btQuadWord.h:117
SIMD_FORCE_INLINE btScalar norm() const
Return the norm (length) of the vector.
Definition btVector3.h:263
float[3][3] Mat3
Definition gpu_matrix.cc:28
#define M
#define B
#define R
double DistanceLInfinity(const TVec &x, const TVec &y)
Definition numeric.h:216
Mat Diag(const TVec &x)
Definition numeric.h:268
Eigen::VectorXd Vec
Definition numeric.h:61
double Nullspace(TMat *A, TVec *nullspace)
Definition numeric.h:158
Eigen::Vector4d Vec4
Definition numeric.h:107
Mat3 CrossProductMatrix(const Vec3 &x)
Definition numeric.cc:80
void TransposeInPlace(TA *A)
Definition numeric.h:187
void VerticalStack(const TTop &top, const TBot &bottom, TStacked *stacked)
Definition numeric.h:418
Eigen::Vector2d Vec2
Definition numeric.h:105
double NormalizeL1(TVec *x)
Definition numeric.h:223
Mat3 RotationAroundX(double angle)
Definition numeric.cc:25
TEST(PolynomialCameraIntrinsics2, ApplyOnFocalCenter)
Eigen::MatrixXd Mat
Definition numeric.h:60
void MatrixColumn(const Mat &A, int i, Vec2 *v)
Definition numeric.cc:127
void MeanAndVarianceAlongRows(const Mat &A, Vec *mean_pointer, Vec *variance_pointer)
Definition numeric.cc:90
Eigen::Matrix< T, ROWS, COLS > HStack(const Eigen::Matrix< T, RowsLeft, ColsLeft > &left, const Eigen::Matrix< T, RowsRight, ColsRight > &right)
Definition numeric.h:378
Mat3 RotationRodrigues(const Vec3 &axis)
Definition numeric.cc:61
Eigen::Matrix< double, 3, 4 > Mat34
Definition numeric.h:73
Eigen::Vector3d Vec3
Definition numeric.h:106
Eigen::Vector2i Vec2i
Definition numeric.h:131
Eigen::Matrix< T, COLS, ROWS > VStack(const Eigen::Matrix< T, ColsLeft, RowsLeft > &top, const Eigen::Matrix< T, ColsRight, RowsRight > &bottom)
Definition numeric.h:398
void HorizontalStack(const Mat &left, const Mat &right, Mat *stacked)
Definition numeric.cc:116
Mat3 RotationAroundZ(double angle)
Definition numeric.cc:49
void reshape(const TMat &a, int rows, int cols, TDest *b)
Definition numeric.h:443
Eigen::Matrix< double, 2, Eigen::Dynamic > Mat2X
Definition numeric.h:91
Mat3 RotationAroundY(double angle)
Definition numeric.cc:37
double NormalizeL2(TVec *x)
Definition numeric.h:232
double Nullspace2(TMat *A, TVec1 *x1, TVec2 *x2)
Definition numeric.h:174
Eigen::Matrix< double, 2, 2 > Mat2
Definition numeric.h:70
TMat ExtractColumns(const TMat &A, const TCols &columns)
Definition numeric.h:434
Mat3 LookAt(Vec3 center)
Definition numeric.cc:69
Vec3 CrossProduct(const Vec3 &x, const Vec3 &y)
Definition numeric.h:282
Eigen::Matrix< double, 4, 3 > Mat43
Definition numeric.h:76
#define I
int xy[2]
Definition wm_draw.cc:170