1 /*
2 * Copyright (c) 2019 Kevin Townsend (KTOWN)
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6
7 #include <zephyr/ztest.h>
8 #include <zsl/zsl.h>
9 #include <zsl/matrices.h>
10 #include <zsl/vectors.h>
11 #include "floatcheck.h"
12
13 /**
14 * @brief zsl_mtx_init unit tests.
15 *
16 * This test verifies the zsl_mtx_init function.
17 */
ZTEST(zsl_tests,test_matrix_init)18 ZTEST(zsl_tests, test_matrix_init)
19 {
20 int rc;
21 zsl_real_t x;
22
23 ZSL_MATRIX_DEF(m, 3, 3);
24
25 /* Initialise the matrix with the default (empty) entry_fn. */
26 rc = zsl_mtx_init(&m, NULL);
27 zassert_equal(rc, 0, NULL);
28
29 rc = zsl_mtx_get(&m, 1, 0, &x);
30 zassert_equal(rc, 0, NULL);
31 zassert_equal(x, 0.0, NULL);
32
33 rc = zsl_mtx_get(&m, 2, 2, &x);
34 zassert_equal(rc, 0, NULL);
35 zassert_equal(x, 0.0, NULL);
36
37 /* Reinitialise the matrix as an identity/diagonal matrix. */
38 rc = zsl_mtx_init(&m, zsl_mtx_entry_fn_identity);
39 zassert_equal(rc, 0, NULL);
40
41 rc = zsl_mtx_get(&m, 0, 0, &x);
42 zassert_equal(rc, 0, NULL);
43 zassert_true(val_is_equal(x, 1.0, 1E-5), NULL);
44
45 rc = zsl_mtx_get(&m, 1, 1, &x);
46 zassert_equal(rc, 0, NULL);
47 zassert_true(val_is_equal(x, 1.0, 1E-5), NULL);
48
49 rc = zsl_mtx_get(&m, 2, 2, &x);
50 zassert_equal(rc, 0, NULL);
51 zassert_true(val_is_equal(x, 1.0, 1E-5), NULL);
52
53 rc = zsl_mtx_get(&m, 0, 1, &x);
54 zassert_equal(x, 0.0, NULL);
55 zassert_equal(rc, 0, NULL);
56 }
57
58 /**
59 * @brief zsl_mtx_from_arr unit tests.
60 *
61 * This test verifies the zsl_mtx_from_arr function.
62 */
ZTEST(zsl_tests,test_matrix_from_arr)63 ZTEST(zsl_tests, test_matrix_from_arr)
64 {
65 int rc;
66 zsl_real_t x;
67
68 /* Destination matrix. */
69 ZSL_MATRIX_DEF(m, 3, 3);
70
71 /* Source array. */
72 zsl_real_t data[9] = { 1.0, 0.0, 0.0,
73 0.0, 0.5, 0.0,
74 0.0, 0.0, 0.1 };
75
76 /* Init matrix m. */
77 zsl_mtx_init(&m, NULL);
78
79 /* Initialise the matrix with the default (empty) entry_fn. */
80 rc = zsl_mtx_from_arr(&m, data);
81 zassert_true(rc == 0, NULL);
82
83 rc = zsl_mtx_get(&m, 0, 0, &x);
84 zassert_equal(rc, 0, NULL);
85 zassert_true(val_is_equal(x, 1.0, 1E-5), NULL);
86
87 rc = zsl_mtx_get(&m, 1, 1, &x);
88 zassert_equal(rc, 0, NULL);
89 zassert_true(val_is_equal(x, 0.5, 1E-5), NULL);
90
91 rc = zsl_mtx_get(&m, 2, 2, &x);
92 zassert_equal(rc, 0, NULL);
93 zassert_true(val_is_equal(x, 0.1, 1E-5), NULL);
94
95 rc = zsl_mtx_get(&m, 1, 0, &x);
96 zassert_equal(rc, 0, NULL);
97 zassert_equal(x, 0.0, NULL);
98 }
99
100 /**
101 * @brief zsl_mtx_copy and zsl_mtx_is_equal unit tests.
102 *
103 * This test verifies the zsl_mtx_copy and zsl_mtx_is_equal functions.
104 */
ZTEST(zsl_tests,test_matrix_copy)105 ZTEST(zsl_tests, test_matrix_copy)
106 {
107 int rc;
108
109 /* Source array. */
110 zsl_real_t data[9] = { 1.0, 0.0, 0.0,
111 0.0, 0.5, 0.0,
112 0.0, 0.0, 0.1 };
113
114 /* Destination matrix. */
115 ZSL_MATRIX_DEF(m, 3, 3);
116 zsl_mtx_init(&m, NULL);
117
118 /* Source matrix. */
119 ZSL_MATRIX_DEF(msrc, 3, 3);
120 rc = zsl_mtx_from_arr(&msrc, data);
121 zassert_true(rc == 0, NULL);
122
123 /* Copy msrc to m. */
124 rc = zsl_mtx_copy(&m, &msrc);
125 zassert_true(rc == 0, NULL);
126
127 /* Verify copy using zsl_mtx_is_equal. */
128 zassert_true(zsl_mtx_is_equal(&m, &msrc), NULL);
129 }
130
131 /**
132 * @brief zsl_mtx_get unit tests.
133 *
134 * This test verifies the zsl_mtx_get function.
135 */
ZTEST(zsl_tests,test_matrix_get)136 ZTEST(zsl_tests, test_matrix_get)
137 {
138 int rc;
139 zsl_real_t x;
140 zsl_real_t data[9] = { 1.0, 0.0, 0.0,
141 0.0, 0.5, 0.0,
142 0.0, 0.0, 0.1 };
143
144 struct zsl_mtx m = {
145 .sz_rows = 3,
146 .sz_cols = 3,
147 .data = data
148 };
149
150 /* Read values from the matrix above. */
151 rc = zsl_mtx_get(&m, 0, 0, &x);
152 zassert_equal(rc, 0, NULL);
153 zassert_true(val_is_equal(x, 1.0, 1E-5), NULL);
154
155 rc = zsl_mtx_get(&m, 1, 0, &x);
156 zassert_equal(rc, 0, NULL);
157 zassert_equal(x, 0.0, NULL);
158
159 rc = zsl_mtx_get(&m, 2, 2, &x);
160 zassert_equal(rc, 0, NULL);
161 zassert_true(val_is_equal(x, 0.1, 1E-5), NULL);
162
163 /* Check for out of bounds error. */
164 zassert_true(zsl_mtx_get(&m, 3, 3, &x) == -EINVAL, NULL);
165 }
166
167 /**
168 * @brief zsl_mtx_set unit tests.
169 *
170 * This test verifies the zsl_mtx_set function.
171 */
ZTEST(zsl_tests,test_matrix_set)172 ZTEST(zsl_tests, test_matrix_set)
173 {
174 int rc = 0;
175 zsl_real_t x;
176
177 ZSL_MATRIX_DEF(m, 3, 3);
178
179 /* Init matrix m. */
180 zsl_mtx_init(&m, NULL);
181
182 /* Set values in matrix m. */
183 rc = zsl_mtx_set(&m, 0, 0, 1.0);
184 zassert_equal(rc, 0, NULL);
185
186 rc = zsl_mtx_set(&m, 1, 1, 0.5);
187 zassert_equal(rc, 0, NULL);
188
189 rc = zsl_mtx_set(&m, 2, 2, 0.1);
190 zassert_equal(rc, 0, NULL);
191
192 /* Verify assigned values */
193 rc = zsl_mtx_get(&m, 0, 0, &x);
194 zassert_equal(rc, 0, NULL);
195 zassert_true(val_is_equal(x, 1.0, 1E-5), NULL);
196
197 rc = zsl_mtx_get(&m, 1, 1, &x);
198 zassert_equal(rc, 0, NULL);
199 zassert_true(val_is_equal(x, 0.5, 1E-5), NULL);
200
201 rc = zsl_mtx_get(&m, 2, 2, &x);
202 zassert_equal(rc, 0, NULL);
203 zassert_true(val_is_equal(x, 0.1, 1E-5), NULL);
204
205 /* Check for out of bounbds error. */
206 zassert_true(zsl_mtx_set(&m, 3, 3, 0.0) == -EINVAL, NULL);
207 }
208
ZTEST(zsl_tests,test_matrix_get_set_row)209 ZTEST(zsl_tests, test_matrix_get_set_row)
210 {
211 int rc = 0;
212 zsl_real_t x;
213 zsl_real_t v[] = { 1.0, 2.0, 3.0 };
214
215 ZSL_MATRIX_DEF(m, 3, 3);
216 ZSL_VECTOR_DEF(v2, 3);
217
218 /* Init matrix m. */
219 zsl_mtx_init(&m, NULL);
220
221 /* Set row 0 in m with the values in 3-vector v. */
222 rc = zsl_mtx_set_row(&m, 0, v);
223 zassert_equal(rc, 0, NULL);
224
225 /* Set row 2 in m with the values in 3-vector v. */
226 rc = zsl_mtx_set_row(&m, 2, v);
227 zassert_equal(rc, 0, NULL);
228
229 /* Verify row 0. */
230 rc = zsl_mtx_get(&m, 0, 0, &x);
231 zassert_true(val_is_equal(x, v[0], 1E-5), NULL);
232 rc = zsl_mtx_get(&m, 0, 1, &x);
233 zassert_true(val_is_equal(x, v[1], 1E-5), NULL);
234 rc = zsl_mtx_get(&m, 0, 2, &x);
235 zassert_true(val_is_equal(x, v[2], 1E-5), NULL);
236
237 /* Verify row 1 (should be all zeroes). */
238 rc = zsl_mtx_get(&m, 1, 0, &x);
239 zassert_true(val_is_equal(x, 0.0, 1E-5), NULL);
240 rc = zsl_mtx_get(&m, 1, 0, &x);
241 zassert_true(val_is_equal(x, 0.0, 1E-5), NULL);
242 rc = zsl_mtx_get(&m, 1, 0, &x);
243 zassert_true(val_is_equal(x, 0.0, 1E-5), NULL);
244
245 /* Verify row 2. */
246 rc = zsl_mtx_get(&m, 2, 0, &x);
247 zassert_true(val_is_equal(x, v[0], 1E-5), NULL);
248 rc = zsl_mtx_get(&m, 2, 1, &x);
249 zassert_true(val_is_equal(x, v[1], 1E-5), NULL);
250 rc = zsl_mtx_get(&m, 2, 2, &x);
251 zassert_true(val_is_equal(x, v[2], 1E-5), NULL);
252
253 /* Now test the get method. */
254 rc = zsl_vec_init(&v2);
255 zassert_equal(rc, 0, NULL);
256
257 /* Read row zero, assigning it to v2.data. */
258 rc = zsl_mtx_get_row(&m, 0, v2.data);
259 zassert_equal(rc, 0, NULL);
260 zassert_true(val_is_equal(v2.data[0], v[0], 1E-5), NULL);
261 zassert_true(val_is_equal(v2.data[1], v[1], 1E-5), NULL);
262 zassert_true(val_is_equal(v2.data[2], v[2], 1E-5), NULL);
263 }
264
ZTEST(zsl_tests,test_matrix_get_set_col)265 ZTEST(zsl_tests, test_matrix_get_set_col)
266 {
267 int rc = 0;
268 zsl_real_t x;
269 zsl_real_t v[] = { 1.0, 2.0, 3.0 };
270
271 ZSL_MATRIX_DEF(m, 3, 3);
272 ZSL_VECTOR_DEF(v2, 3);
273
274 /* TODO: Test get method! */
275
276 /* Init matrix m. */
277 zsl_mtx_init(&m, NULL);
278
279 /* Set col 0 in m with the values in 3-vector v. */
280 rc = zsl_mtx_set_col(&m, 0, v);
281 zassert_equal(rc, 0, NULL);
282
283 /* Set col 2 in m with the values in 3-vector v. */
284 rc = zsl_mtx_set_col(&m, 2, v);
285 zassert_equal(rc, 0, NULL);
286
287 /* Verify col 0. */
288 rc = zsl_mtx_get(&m, 0, 0, &x);
289 zassert_true(val_is_equal(x, v[0], 1E-5), NULL);
290 rc = zsl_mtx_get(&m, 1, 0, &x);
291 zassert_true(val_is_equal(x, v[1], 1E-5), NULL);
292 rc = zsl_mtx_get(&m, 2, 0, &x);
293 zassert_true(val_is_equal(x, v[2], 1E-5), NULL);
294
295 /* Verify col 1 (should be all zeroes). */
296 rc = zsl_mtx_get(&m, 0, 1, &x);
297 zassert_true(val_is_equal(x, 0.0, 1E-5), NULL);
298 rc = zsl_mtx_get(&m, 1, 1, &x);
299 zassert_true(val_is_equal(x, 0.0, 1E-5), NULL);
300 rc = zsl_mtx_get(&m, 2, 1, &x);
301 zassert_true(val_is_equal(x, 0.0, 1E-5), NULL);
302
303 /* Verify col 2. */
304 rc = zsl_mtx_get(&m, 0, 2, &x);
305 zassert_true(val_is_equal(x, v[0], 1E-5), NULL);
306 rc = zsl_mtx_get(&m, 1, 2, &x);
307 zassert_true(val_is_equal(x, v[1], 1E-5), NULL);
308 rc = zsl_mtx_get(&m, 2, 2, &x);
309 zassert_true(val_is_equal(x, v[2], 1E-5), NULL);
310
311 /* Now test the get method. */
312 rc = zsl_vec_init(&v2);
313 zassert_equal(rc, 0, NULL);
314
315 /* Read row zero, assigning it to v2.data. */
316 rc = zsl_mtx_get_col(&m, 2, v2.data);
317 zassert_equal(rc, 0, NULL);
318 zassert_true(val_is_equal(v2.data[0], v[0], 1E-5), NULL);
319 zassert_true(val_is_equal(v2.data[1], v[1], 1E-5), NULL);
320 zassert_true(val_is_equal(v2.data[2], v[2], 1E-5), NULL);
321 }
322
ZTEST(zsl_tests,test_matrix_row_from_vec)323 ZTEST(zsl_tests, test_matrix_row_from_vec)
324 {
325 int rc;
326 zsl_real_t x;
327
328 ZSL_VECTOR_DEF(v, 3);
329 ZSL_MATRIX_DEF(m, 3, 3);
330
331 /* Init matrix m. */
332 zsl_mtx_init(&m, NULL);
333
334 /* Assign some values to the vector. */
335 v.data[0] = 1.0;
336 v.data[1] = 2.0;
337 v.data[2] = 3.0;
338
339 /* Now assign the vector to matrix row 1 via the .data field. */
340 rc = zsl_mtx_set_row(&m, 1, v.data);
341 zassert_true(rc == 0, NULL);
342
343 /* Make sure the row assignment worked. */
344 rc = zsl_mtx_get(&m, 1, 0, &x);
345 zassert_true(val_is_equal(x, v.data[0], 1E-5), NULL);
346 rc = zsl_mtx_get(&m, 1, 1, &x);
347 zassert_true(val_is_equal(x, v.data[1], 1E-5), NULL);
348 rc = zsl_mtx_get(&m, 1, 2, &x);
349 zassert_true(val_is_equal(x, v.data[2], 1E-5), NULL);
350
351 /* Now read one back. */
352 rc = zsl_mtx_get_row(&m, 0, v.data);
353 zassert_true(rc == 0, NULL);
354
355 /* Vector values should have changed to all be 0.0 now. */
356 zassert_true(val_is_equal(v.data[0], 0.0, 1E-5), NULL);
357 zassert_true(val_is_equal(v.data[1], 0.0, 1E-5), NULL);
358 zassert_true(val_is_equal(v.data[2], 0.0, 1E-5), NULL);
359 }
360
ZTEST(zsl_tests,test_matrix_unary_op)361 ZTEST(zsl_tests, test_matrix_unary_op)
362 {
363 int rc;
364
365 zsl_real_t data[9] = { 1.0, 0.0, 0.0,
366 0.0, 0.5, 0.0,
367 0.0, 0.0, 0.1 };
368
369 struct zsl_mtx m = {
370 .sz_rows = 3,
371 .sz_cols = 3,
372 .data = data
373 };
374
375 rc = zsl_mtx_unary_op(&m, ZSL_MTX_UNARY_OP_INCREMENT);
376 zassert_true(rc == 0, NULL);
377 zassert_true(val_is_equal(m.data[0], 2.0, 1E-5), NULL);
378 zassert_true(val_is_equal(m.data[8], 1.1, 1E-5), NULL);
379
380 /* TODO: Test other operands! */
381 }
382
ZTEST(zsl_tests,test_matrix_unary_func)383 ZTEST(zsl_tests, test_matrix_unary_func)
384 {
385
386 }
387
ZTEST(zsl_tests,test_matrix_binary_op)388 ZTEST(zsl_tests, test_matrix_binary_op)
389 {
390 int rc;
391
392 ZSL_MATRIX_DEF(mc, 3, 3);
393
394 zsl_real_t data_a[9] = { 1.0, 0.0, 0.0,
395 0.0, 0.5, 0.0,
396 0.0, 0.0, 0.1 };
397
398 zsl_real_t data_b[9] = { 1.0, 0.0, 0.0,
399 0.0, 0.5, 0.0,
400 0.0, 0.0, 0.1 };
401
402 struct zsl_mtx ma = {
403 .sz_rows = 3,
404 .sz_cols = 3,
405 .data = data_a
406 };
407
408 struct zsl_mtx mb = {
409 .sz_rows = 3,
410 .sz_cols = 3,
411 .data = data_b
412 };
413
414 /* Init matrix mc. */
415 zsl_mtx_init(&mc, NULL);
416
417 rc = zsl_mtx_binary_op(&ma, &mb, &mc, ZSL_MTX_BINARY_OP_ADD);
418 zassert_true(rc == 0, NULL);
419 zassert_true(val_is_equal(mc.data[0], ma.data[0] + mb.data[0], 1E-5),
420 NULL);
421 zassert_true(val_is_equal(mc.data[8], ma.data[8] + mb.data[8], 1E-5),
422 NULL);
423
424 /* TODO: Test other operands! */
425 }
426
ZTEST(zsl_tests,test_matrix_binary_func)427 ZTEST(zsl_tests, test_matrix_binary_func)
428 {
429
430 }
431
ZTEST(zsl_tests,test_matrix_add)432 ZTEST(zsl_tests, test_matrix_add)
433 {
434 int rc;
435 zsl_real_t x;
436
437 ZSL_MATRIX_DEF(mc, 3, 4);
438
439 zsl_real_t a[12] = { 1.0, 2.0, 4.0, 7.0,
440 0.0, 0.5, 0.0, 6.2,
441 9.0, 0.8, 0.1, 0.4 };
442
443 zsl_real_t b[12] = { 3.0, 0.0, 0.0, 5.1,
444 6.0, 2.5, 1.0, 4.4,
445 0.0, 7.0, 4.1, 2.1 };
446
447 struct zsl_mtx ma = {
448 .sz_rows = 3,
449 .sz_cols = 4,
450 .data = a
451 };
452
453 struct zsl_mtx mb = {
454 .sz_rows = 3,
455 .sz_cols = 4,
456 .data = b
457 };
458
459 /* Init matrix mc. */
460 rc = zsl_mtx_init(&mc, NULL);
461 zassert_true(rc == 0, NULL);
462
463 /* Add 'ma' and 'mb'. */
464 rc = zsl_mtx_add(&ma, &mb, &mc);
465 zassert_true(rc == 0, NULL);
466
467 /* Check the output. */
468 for (size_t g = 0; g < (ma.sz_rows * ma.sz_cols); g++) {
469 x = ma.data[g] + mb.data[g];
470 zassert_true(val_is_equal(mc.data[g], x, 1E-5), NULL);
471 }
472 }
473
ZTEST(zsl_tests,test_matrix_add_d)474 ZTEST(zsl_tests, test_matrix_add_d)
475 {
476 int rc;
477 zsl_real_t x;
478
479 ZSL_MATRIX_DEF(mcopy, 3, 4);
480
481 zsl_real_t a[12] = { 1.0, 2.0, 4.0, 7.0,
482 0.0, 0.5, 0.0, 6.2,
483 9.0, 0.8, 0.1, 0.4 };
484
485 zsl_real_t b[12] = { 3.0, 0.0, 0.0, 5.1,
486 6.0, 2.5, 1.0, 4.4,
487 0.0, 7.0, 4.1, 2.1 };
488
489 struct zsl_mtx ma = {
490 .sz_rows = 3,
491 .sz_cols = 4,
492 .data = a
493 };
494
495 struct zsl_mtx mb = {
496 .sz_rows = 3,
497 .sz_cols = 4,
498 .data = b
499 };
500
501 /* Copy 'ma' into 'mcopy'. */
502 rc = zsl_mtx_copy(&mcopy, &ma);
503 zassert_equal(rc, 0, NULL);
504
505 /* Add 'ma' and 'mb'. */
506 rc = zsl_mtx_add_d(&ma, &mb);
507 zassert_equal(rc, 0, NULL);
508
509 /* Check the output. */
510 for (size_t g = 0; g < (ma.sz_rows * ma.sz_cols); g++) {
511 x = mcopy.data[g] + mb.data[g];
512 zassert_true(val_is_equal(ma.data[g], x, 1E-5), NULL);
513 }
514 }
515
ZTEST(zsl_tests,test_matrix_sum_rows_d)516 ZTEST(zsl_tests, test_matrix_sum_rows_d)
517 {
518 int rc;
519
520 ZSL_MATRIX_DEF(mcopy, 3, 4);
521
522 zsl_real_t a[12] = { 1.0, 2.0, 4.0, 7.0,
523 0.0, 0.5, 5.4, 6.2,
524 9.0, 0.8, 0.1, 0.4 };
525
526 struct zsl_mtx ma = {
527 .sz_rows = 3,
528 .sz_cols = 4,
529 .data = a
530 };
531
532 /* Copy 'ma' into 'mcopy'. */
533 rc = zsl_mtx_copy(&mcopy, &ma);
534 zassert_true(rc == 0, NULL);
535
536 /* Add row 3 to row 2. */
537 rc = zsl_mtx_sum_rows_d(&ma, 1, 2);
538 zassert_true(rc == 0, NULL);
539
540 /* Check the output. */
541 rc = zsl_mtx_set(&mcopy, 1, 0, 9.0);
542 zassert_true(rc == 0, NULL);
543 rc = zsl_mtx_set(&mcopy, 1, 1, 1.3);
544 zassert_true(rc == 0, NULL);
545 rc = zsl_mtx_set(&mcopy, 1, 2, 5.5);
546 zassert_true(rc == 0, NULL);
547 rc = zsl_mtx_set(&mcopy, 1, 3, 6.6);
548 zassert_true(rc == 0, NULL);
549
550 for (size_t i = 0; i < (ma.sz_rows * ma.sz_cols); i++) {
551 zassert_true(val_is_equal(mcopy.data[i], ma.data[i], 1E-6),
552 NULL);
553 }
554
555 /* Add row 2 to row 1. */
556 rc = zsl_mtx_sum_rows_d(&ma, 0, 1);
557 zassert_true(rc == 0, NULL);
558
559 /* Check the output. */
560 rc = zsl_mtx_set(&mcopy, 0, 0, 10.0);
561 zassert_true(rc == 0, NULL);
562 rc = zsl_mtx_set(&mcopy, 0, 1, 3.3);
563 zassert_true(rc == 0, NULL);
564 rc = zsl_mtx_set(&mcopy, 0, 2, 9.5);
565 zassert_true(rc == 0, NULL);
566 rc = zsl_mtx_set(&mcopy, 0, 3, 13.6);
567 zassert_true(rc == 0, NULL);
568
569 for (size_t i = 0; i < (ma.sz_rows * ma.sz_cols); i++) {
570 zassert_true(val_is_equal(mcopy.data[i], ma.data[i], 1E-6),
571 NULL);
572 }
573
574 /* Add row 2 to row 5. An error is expected. */
575 rc = zsl_mtx_sum_rows_d(&ma, 4, 1);
576 zassert_true(rc == -EINVAL, NULL);
577 }
578
ZTEST(zsl_tests,test_matrix_sum_rows_scaled_d)579 ZTEST(zsl_tests, test_matrix_sum_rows_scaled_d)
580 {
581 int rc;
582
583 ZSL_MATRIX_DEF(mcopy, 3, 4);
584
585 zsl_real_t a[12] = { 1.0, 2.0, 4.0, 7.0,
586 0.0, 0.5, 5.4, 6.2,
587 9.0, 0.8, 0.1, 0.4 };
588
589 struct zsl_mtx ma = {
590 .sz_rows = 3,
591 .sz_cols = 4,
592 .data = a
593 };
594
595 /* Copy 'ma' into 'mcopy'. */
596 rc = zsl_mtx_copy(&mcopy, &ma);
597 zassert_true(rc == 0, NULL);
598
599 /* Add 4.1 times row 3 to row 2. */
600 rc = zsl_mtx_sum_rows_scaled_d(&ma, 1, 2, 4.1);
601 zassert_true(rc == 0, NULL);
602
603 /* Check the output. */
604 rc = zsl_mtx_set(&mcopy, 1, 0, 36.9);
605 zassert_true(rc == 0, NULL);
606 rc = zsl_mtx_set(&mcopy, 1, 1, 3.78);
607 zassert_true(rc == 0, NULL);
608 rc = zsl_mtx_set(&mcopy, 1, 2, 5.81);
609 zassert_true(rc == 0, NULL);
610 rc = zsl_mtx_set(&mcopy, 1, 3, 7.84);
611 zassert_true(rc == 0, NULL);
612
613 for (size_t i = 0; i < (ma.sz_rows * ma.sz_cols); i++) {
614 #ifdef CONFIG_ZSL_SINGLE_PRECISION
615 zassert_true(val_is_equal(mcopy.data[i], ma.data[i], 1E-5),
616 NULL);
617 #else
618 zassert_true(val_is_equal(mcopy.data[i], ma.data[i], 1E-8),
619 NULL);
620 #endif
621 }
622
623 /* Add -0.2 time row 2 to row 1. */
624 rc = zsl_mtx_sum_rows_scaled_d(&ma, 0, 1, -0.2);
625 zassert_true(rc == 0, NULL);
626
627 /* Check the output. */
628 rc = zsl_mtx_set(&mcopy, 0, 0, -6.38);
629 zassert_true(rc == 0, NULL);
630 rc = zsl_mtx_set(&mcopy, 0, 1, 1.244);
631 zassert_true(rc == 0, NULL);
632 rc = zsl_mtx_set(&mcopy, 0, 2, 2.838);
633 zassert_true(rc == 0, NULL);
634 rc = zsl_mtx_set(&mcopy, 0, 3, 5.432);
635 zassert_true(rc == 0, NULL);
636
637 for (size_t i = 0; i < (ma.sz_rows * ma.sz_cols); i++) {
638 #ifdef CONFIG_ZSL_SINGLE_PRECISION
639 zassert_true(val_is_equal(mcopy.data[i], ma.data[i], 1E-5),
640 NULL);
641 #else
642 zassert_true(val_is_equal(mcopy.data[i], ma.data[i], 1E-8),
643 NULL);
644 #endif
645 }
646
647 /* Add two times row 2 to row 5. An error is expected. */
648 rc = zsl_mtx_sum_rows_scaled_d(&ma, 4, 1, 2.0);
649 zassert_true(rc == -EINVAL, NULL);
650 }
651
ZTEST(zsl_tests,test_matrix_sub)652 ZTEST(zsl_tests, test_matrix_sub)
653 {
654 int rc;
655 zsl_real_t x;
656
657 ZSL_MATRIX_DEF(mc, 3, 4);
658
659 zsl_real_t a[12] = { 1.0, 2.0, 4.0, 7.0,
660 0.0, 0.5, 0.0, 6.2,
661 9.0, 0.8, 0.1, 0.4 };
662
663 zsl_real_t b[12] = { 3.0, 0.0, 0.0, 5.1,
664 6.0, 2.5, 1.0, 4.4,
665 0.0, 7.0, 4.1, 2.1 };
666
667 struct zsl_mtx ma = {
668 .sz_rows = 3,
669 .sz_cols = 4,
670 .data = a
671 };
672
673 struct zsl_mtx mb = {
674 .sz_rows = 3,
675 .sz_cols = 4,
676 .data = b
677 };
678
679 /* Init matrix mc. */
680 rc = zsl_mtx_init(&mc, NULL);
681 zassert_true(rc == 0, NULL);
682
683 /* Substract 'mb' from 'ma'. */
684 rc = zsl_mtx_sub(&ma, &mb, &mc);
685 zassert_true(rc == 0, NULL);
686
687 /* Check the output. */
688 for (size_t g = 0; g < (ma.sz_rows * ma.sz_cols); g++) {
689 x = ma.data[g] - mb.data[g];
690 zassert_true(val_is_equal(mc.data[g], x, 1E-5), NULL);
691 }
692 }
693
ZTEST(zsl_tests,test_matrix_sub_d)694 ZTEST(zsl_tests, test_matrix_sub_d)
695 {
696 int rc;
697 zsl_real_t x;
698
699 ZSL_MATRIX_DEF(mcopy, 3, 4);
700
701 zsl_real_t a[12] = { 1.0, 2.0, 4.0, 7.0,
702 0.0, 0.5, 0.0, 6.2,
703 9.0, 0.8, 0.1, 0.4 };
704
705 zsl_real_t b[12] = { 3.0, 0.0, 0.0, 5.1,
706 6.0, 2.5, 1.0, 4.4,
707 0.0, 7.0, 4.1, 2.1 };
708
709 struct zsl_mtx ma = {
710 .sz_rows = 3,
711 .sz_cols = 4,
712 .data = a
713 };
714
715 struct zsl_mtx mb = {
716 .sz_rows = 3,
717 .sz_cols = 4,
718 .data = b
719 };
720
721 /* Copy 'ma' into 'mcopy'. */
722 rc = zsl_mtx_copy(&mcopy, &ma);
723 zassert_equal(rc, 0, NULL);
724
725 /* Substract 'mb' from 'ma'. */
726 rc = zsl_mtx_sub_d(&ma, &mb);
727 zassert_equal(rc, 0, NULL);
728
729 /* Check the output. */
730 for (size_t g = 0; g < (ma.sz_rows * ma.sz_cols); g++) {
731 x = mcopy.data[g] - mb.data[g];
732 zassert_true(val_is_equal(ma.data[g], x, 1E-5), NULL);
733 }
734 }
735
736 /**
737 * @brief zsl_mtx_mult unit tests with square matrices.
738 *
739 * This test verifies the zsl_mtx_mult function with square matrices.
740 */
ZTEST(zsl_tests,test_matrix_mult_sq)741 ZTEST(zsl_tests, test_matrix_mult_sq)
742 {
743 int rc = 0;
744
745 ZSL_MATRIX_DEF(mc, 3, 3);
746
747 /* Input matrix a. */
748 zsl_real_t data_a[9] = { 1.0, 2.0, 3.0,
749 4.0, 5.0, 6.0,
750 7.0, 8.0, 9.0 };
751 struct zsl_mtx ma = {
752 .sz_rows = 3,
753 .sz_cols = 3,
754 .data = data_a
755 };
756
757 /* Input matrix b. */
758 zsl_real_t data_b[9] = { 10.0, 20.0, 30.0,
759 40.0, 50.0, 60.0,
760 70.0, 80.0, 90.0 };
761 struct zsl_mtx mb = {
762 .sz_rows = 3,
763 .sz_cols = 3,
764 .data = data_b
765 };
766
767 /* Init matrix mc. */
768 zsl_mtx_init(&mc, NULL);
769
770 /* Output reference matrix (for comparison). */
771 zsl_real_t data_ref[9] = { 300.0, 360.0, 420.0,
772 660.0, 810.0, 960.0,
773 1020.0, 1260.0, 1500.0 };
774 struct zsl_mtx mref = {
775 .sz_rows = 3,
776 .sz_cols = 3,
777 .data = data_ref
778 };
779
780 /* Perform a valid 3x3 square matrix multiplication. */
781 rc = zsl_mtx_mult(&ma, &mb, &mc);
782 zassert_equal(rc, 0, NULL);
783 zassert_equal(mref.data[0], mc.data[0], NULL);
784 zassert_equal(mref.data[1], mc.data[1], NULL);
785 zassert_equal(mref.data[2], mc.data[2], NULL);
786 zassert_equal(mref.data[3], mc.data[3], NULL);
787 zassert_equal(mref.data[4], mc.data[4], NULL);
788 zassert_equal(mref.data[5], mc.data[5], NULL);
789 zassert_equal(mref.data[6], mc.data[6], NULL);
790 zassert_equal(mref.data[7], mc.data[7], NULL);
791 zassert_equal(mref.data[8], mc.data[8], NULL);
792 }
793
794 /**
795 * @brief zsl_mtx_mult unit tests with rectangular matrices.
796 *
797 * This test verifies the zsl_mtx_mult function with rectangular matrices.
798 */
ZTEST(zsl_tests,test_matrix_mult_rect)799 ZTEST(zsl_tests, test_matrix_mult_rect)
800 {
801 int rc = 0;
802
803 ZSL_MATRIX_DEF(mc, 4, 3);
804 ZSL_MATRIX_DEF(merr, 5, 3);
805
806 /* Init matrix mc, merr */
807 zsl_mtx_init(&mc, NULL);
808 zsl_mtx_init(&merr, NULL);
809
810 /* Input matrix a (4x2). */
811 zsl_real_t data_a[8] = { 2.0, 3.0,
812 1.0, 4.0,
813 4.0, 3.0,
814 3.0, 4.0 };
815 struct zsl_mtx ma = {
816 .sz_rows = 4,
817 .sz_cols = 2,
818 .data = data_a
819 };
820
821 /* Input matrix b (2x3). */
822 zsl_real_t data_b[9] = { 3.0, 1.0, 2.0,
823 2.0, 4.0, 2.0 };
824 struct zsl_mtx mb = {
825 .sz_rows = 2,
826 .sz_cols = 3,
827 .data = data_b
828 };
829
830 /* Output reference matrix (4x3). */
831 zsl_real_t data_ref[12] = { 12.0, 14.0, 10.0,
832 11.0, 17.0, 10.0,
833 18.0, 16.0, 14.0,
834 17.0, 19.0, 14.0 };
835 struct zsl_mtx mref = {
836 .sz_rows = 4,
837 .sz_cols = 3,
838 .data = data_ref
839 };
840
841 /* Attempt an invalid 4x2 x 5x3 matrix multiplication. */
842 rc = zsl_mtx_mult(&merr, &mb, &mc);
843 zassert_equal(rc, -EINVAL, NULL);
844
845 /* Perform a valid 3x3 square matrix multiplication. */
846 rc = zsl_mtx_mult(&ma, &mb, &mc);
847 zassert_equal(rc, 0, NULL);
848 zassert_equal(mref.data[0], mc.data[0], NULL);
849 zassert_equal(mref.data[1], mc.data[1], NULL);
850 zassert_equal(mref.data[2], mc.data[2], NULL);
851 zassert_equal(mref.data[3], mc.data[3], NULL);
852 zassert_equal(mref.data[4], mc.data[4], NULL);
853 zassert_equal(mref.data[5], mc.data[5], NULL);
854 zassert_equal(mref.data[6], mc.data[6], NULL);
855 zassert_equal(mref.data[7], mc.data[7], NULL);
856 zassert_equal(mref.data[8], mc.data[8], NULL);
857 zassert_equal(mref.data[9], mc.data[9], NULL);
858 zassert_equal(mref.data[10], mc.data[10], NULL);
859 zassert_equal(mref.data[11], mc.data[11], NULL);
860 }
861
ZTEST(zsl_tests,test_matrix_mult_d)862 ZTEST(zsl_tests, test_matrix_mult_d)
863 {
864 int rc = 0;
865
866 /* Input matrix a. */
867 zsl_real_t data_a[9] = { 1.0, 2.0, 3.0,
868 4.0, 5.0, 6.0,
869 7.0, 8.0, 9.0 };
870 struct zsl_mtx ma = {
871 .sz_rows = 3,
872 .sz_cols = 3,
873 .data = data_a
874 };
875
876 /* Input matrix b. */
877 zsl_real_t data_b[9] = { 10.0, 20.0, 30.0,
878 40.0, 50.0, 60.0,
879 70.0, 80.0, 90.0 };
880 struct zsl_mtx mb = {
881 .sz_rows = 3,
882 .sz_cols = 3,
883 .data = data_b
884 };
885
886 /* Output reference matrix (for comparison). */
887 zsl_real_t data_ref[9] = { 300.0, 360.0, 420.0,
888 660.0, 810.0, 960.0,
889 1020.0, 1260.0, 1500.0 };
890 struct zsl_mtx mref = {
891 .sz_rows = 3,
892 .sz_cols = 3,
893 .data = data_ref
894 };
895
896 /* Perform a valid matrix multiplication. */
897 rc = zsl_mtx_mult_d(&ma, &mb);
898 zassert_equal(rc, 0, NULL);
899 zassert_equal(mref.data[0], ma.data[0], NULL);
900 zassert_equal(mref.data[1], ma.data[1], NULL);
901 zassert_equal(mref.data[2], ma.data[2], NULL);
902 zassert_equal(mref.data[3], ma.data[3], NULL);
903 zassert_equal(mref.data[4], ma.data[4], NULL);
904 zassert_equal(mref.data[5], ma.data[5], NULL);
905 zassert_equal(mref.data[6], ma.data[6], NULL);
906 zassert_equal(mref.data[7], ma.data[7], NULL);
907 zassert_equal(mref.data[8], ma.data[8], NULL);
908
909 /* Perform a invalid matrix multiplications. */
910 ZSL_MATRIX_DEF(mb2, 3, 4);
911 rc = zsl_mtx_mult_d(&ma, &mb2);
912 zassert_equal(rc, -EINVAL, NULL);
913
914 ZSL_MATRIX_DEF(ma2, 1, 5);
915 rc = zsl_mtx_mult_d(&ma2, &mb);
916 zassert_equal(rc, -EINVAL, NULL);
917 }
918
919 /**
920 * @brief zsl_mtx_scalar_mult_d unit tests.
921 *
922 * This test verifies the zsl_mtx_scalar_mult_d function.
923 */
ZTEST(zsl_tests,test_matrix_scalar_mult_d)924 ZTEST(zsl_tests, test_matrix_scalar_mult_d)
925 {
926 int rc = 0;
927 zsl_real_t s = 10.0;
928
929 /* Input matrix. */
930 zsl_real_t data[8] = { 2.0, 3.0,
931 1.0, 4.0,
932 4.0, 3.0,
933 3.0, 4.0 };
934 struct zsl_mtx m = {
935 .sz_rows = 4,
936 .sz_cols = 2,
937 .data = data
938 };
939
940 rc = zsl_mtx_scalar_mult_d(&m, s);
941 zassert_equal(rc, 0, NULL);
942 zassert_true(val_is_equal(m.data[0], 20.0, 1E-5), NULL);
943 zassert_true(val_is_equal(m.data[1], 30.0, 1E-5), NULL);
944 zassert_true(val_is_equal(m.data[2], 10.0, 1E-5), NULL);
945 zassert_true(val_is_equal(m.data[3], 40.0, 1E-5), NULL);
946 zassert_true(val_is_equal(m.data[4], 40.0, 1E-5), NULL);
947 zassert_true(val_is_equal(m.data[5], 30.0, 1E-5), NULL);
948 zassert_true(val_is_equal(m.data[6], 30.0, 1E-5), NULL);
949 zassert_true(val_is_equal(m.data[7], 40.0, 1E-5), NULL);
950 }
951
ZTEST(zsl_tests,test_matrix_scalar_mult_row_d)952 ZTEST(zsl_tests, test_matrix_scalar_mult_row_d)
953 {
954 int rc;
955
956 ZSL_MATRIX_DEF(mcopy, 3, 4);
957
958 zsl_real_t a[12] = { 1.0, 2.0, 4.0, 7.0,
959 0.0, 0.5, 5.4, 6.2,
960 9.0, 0.8, 0.1, 0.4 };
961
962 struct zsl_mtx ma = {
963 .sz_rows = 3,
964 .sz_cols = 4,
965 .data = a
966 };
967
968 /* Copy 'ma' into 'mcopy'. */
969 rc = zsl_mtx_copy(&mcopy, &ma);
970 zassert_true(rc == 0, NULL);
971
972 /* Multiply row 3 by 1.3. */
973 rc = zsl_mtx_scalar_mult_row_d(&ma, 2, 1.3);
974 zassert_true(rc == 0, NULL);
975
976 /* Check the output. */
977 rc = zsl_mtx_set(&mcopy, 2, 0, 11.7);
978 zassert_true(rc == 0, NULL);
979 rc = zsl_mtx_set(&mcopy, 2, 1, 1.04);
980 zassert_true(rc == 0, NULL);
981 rc = zsl_mtx_set(&mcopy, 2, 2, 0.13);
982 zassert_true(rc == 0, NULL);
983 rc = zsl_mtx_set(&mcopy, 2, 3, 0.52);
984 zassert_true(rc == 0, NULL);
985
986 for (size_t i = 0; i < (ma.sz_rows * ma.sz_cols); i++) {
987 zassert_true(val_is_equal(mcopy.data[i], ma.data[i], 1E-6),
988 NULL);
989 }
990
991 /* Multiply row 1 by -0.5. */
992 rc = zsl_mtx_scalar_mult_row_d(&ma, 0, -0.5);
993 zassert_true(rc == 0, NULL);
994
995 /* Check the output. */
996 rc = zsl_mtx_set(&mcopy, 0, 0, -0.5);
997 zassert_true(rc == 0, NULL);
998 rc = zsl_mtx_set(&mcopy, 0, 1, -1.0);
999 zassert_true(rc == 0, NULL);
1000 rc = zsl_mtx_set(&mcopy, 0, 2, -2.0);
1001 zassert_true(rc == 0, NULL);
1002 rc = zsl_mtx_set(&mcopy, 0, 3, -3.5);
1003 zassert_true(rc == 0, NULL);
1004
1005 for (size_t i = 0; i < (ma.sz_rows * ma.sz_cols); i++) {
1006 zassert_true(val_is_equal(mcopy.data[i], ma.data[i], 1E-6),
1007 NULL);
1008 }
1009
1010 /* Multiply row 5 by 3. An error is expected. */
1011 rc = zsl_mtx_scalar_mult_row_d(&ma, 4, 3);
1012 zassert_true(rc == -EINVAL, NULL);
1013 }
1014
1015 /**
1016 * @brief zsl_mtx_scalar_trans unit tests.
1017 *
1018 * This test verifies the zsl_mtx_trans function.
1019 */
ZTEST(zsl_tests,test_matrix_trans)1020 ZTEST(zsl_tests, test_matrix_trans)
1021 {
1022 int rc = 0;
1023
1024 ZSL_MATRIX_DEF(mt, 2, 4);
1025
1026 /* Input matrix. */
1027 zsl_real_t data[8] = { 2.0, 3.0,
1028 1.0, 4.0,
1029 4.0, 3.0,
1030 3.0, 4.0 };
1031
1032 struct zsl_mtx m = {
1033 .sz_rows = 4,
1034 .sz_cols = 2,
1035 .data = data
1036 };
1037
1038 /* Init matrix 'mt'. */
1039 rc = zsl_mtx_init(&mt, NULL);
1040 zassert_equal(rc, 0, NULL);
1041
1042 rc = zsl_mtx_trans(&m, &mt);
1043 zassert_equal(rc, 0, NULL);
1044
1045 /* Check the output. */
1046 zassert_equal(mt.sz_cols, m.sz_rows, NULL);
1047 zassert_equal(mt.sz_rows, m.sz_cols, NULL);
1048 zassert_true(val_is_equal(mt.data[0], 2.0, 1E-5), NULL);
1049 zassert_true(val_is_equal(mt.data[1], 1.0, 1E-5), NULL);
1050 zassert_true(val_is_equal(mt.data[2], 4.0, 1E-5), NULL);
1051 zassert_true(val_is_equal(mt.data[3], 3.0, 1E-5), NULL);
1052 zassert_true(val_is_equal(mt.data[4], 3.0, 1E-5), NULL);
1053 zassert_true(val_is_equal(mt.data[5], 4.0, 1E-5), NULL);
1054 zassert_true(val_is_equal(mt.data[6], 3.0, 1E-5), NULL);
1055 zassert_true(val_is_equal(mt.data[7], 4.0, 1E-5), NULL);
1056 }
1057
ZTEST(zsl_tests,test_matrix_adjoint_3x3)1058 ZTEST(zsl_tests, test_matrix_adjoint_3x3)
1059 {
1060 int rc = 0;
1061
1062 ZSL_MATRIX_DEF(mad, 3, 3);
1063
1064 /* Input matrix. */
1065 zsl_real_t data[9] = { 2.0, -3.0, 1.0,
1066 -4.0, 4.0, 3.0,
1067 3.0, 4.0, -5.0 };
1068
1069 struct zsl_mtx m = {
1070 .sz_rows = 3,
1071 .sz_cols = 3,
1072 .data = data
1073 };
1074
1075 /* Init matrix 'mad'. */
1076 rc = zsl_mtx_init(&mad, NULL);
1077 zassert_equal(rc, 0, NULL);
1078
1079 rc = zsl_mtx_adjoint_3x3(&m, &mad);
1080 zassert_equal(rc, 0, NULL);
1081
1082 /* Check the output. */
1083 zassert_true(val_is_equal(mad.data[0], -32.0, 1E-6), NULL);
1084 zassert_true(val_is_equal(mad.data[1], -11.0, 1E-6), NULL);
1085 zassert_true(val_is_equal(mad.data[2], -13.0, 1E-6), NULL);
1086 zassert_true(val_is_equal(mad.data[3], -11.0, 1E-6), NULL);
1087 zassert_true(val_is_equal(mad.data[4], -13.0, 1E-6), NULL);
1088 zassert_true(val_is_equal(mad.data[5], -10.0, 1E-6), NULL);
1089 zassert_true(val_is_equal(mad.data[6], -28.0, 1E-6), NULL);
1090 zassert_true(val_is_equal(mad.data[7], -17.0, 1E-6), NULL);
1091 zassert_true(val_is_equal(mad.data[8], -4.0, 1E-6), NULL);
1092 }
1093
ZTEST(zsl_tests,test_matrix_adjoint)1094 ZTEST(zsl_tests, test_matrix_adjoint)
1095 {
1096 int rc = 0;
1097
1098 ZSL_MATRIX_DEF(mad, 4, 4);
1099
1100 /* Input matrix. */
1101 zsl_real_t data[16] = { 2.0, -3.0, 1.0, 5.0,
1102 -4.0, 4.0, 3.0, -3.0,
1103 -2.0, 6.0, 1.0, 0.0,
1104 3.0, 4.0, -5.0, -8.0 };
1105
1106 struct zsl_mtx m = {
1107 .sz_rows = 4,
1108 .sz_cols = 4,
1109 .data = data
1110 };
1111
1112 /* Init matrix 'mad'. */
1113 rc = zsl_mtx_init(&mad, NULL);
1114 zassert_equal(rc, 0, NULL);
1115
1116 rc = zsl_mtx_adjoint(&m, &mad);
1117 zassert_equal(rc, 0, NULL);
1118
1119 /* Check the output. */
1120 zassert_true(val_is_equal(mad.data[0], 214.0, 1E-6), NULL);
1121 zassert_true(val_is_equal(mad.data[1], 37.0, 1E-6), NULL);
1122 zassert_true(val_is_equal(mad.data[2], 206.0, 1E-6), NULL);
1123 zassert_true(val_is_equal(mad.data[3], -30.0, 1E-6), NULL);
1124 zassert_true(val_is_equal(mad.data[4], 98.0, 1E-6), NULL);
1125 zassert_true(val_is_equal(mad.data[5], 3.0, 1E-6), NULL);
1126 zassert_true(val_is_equal(mad.data[6], 178.0, 1E-6), NULL);
1127 zassert_true(val_is_equal(mad.data[7], -73.0, 1E-6), NULL);
1128 zassert_true(val_is_equal(mad.data[8], -23.0, 1E-6), NULL);
1129 zassert_true(val_is_equal(mad.data[9], 64.0, 1E-6), NULL);
1130 zassert_true(val_is_equal(mad.data[10], -57.0, 1E-6), NULL);
1131 zassert_true(val_is_equal(mad.data[11], 59.0, 1E-6), NULL);
1132 zassert_true(val_is_equal(mad.data[12], 97.0, 1E-6), NULL);
1133 zassert_true(val_is_equal(mad.data[13], 22.0, 1E-6), NULL);
1134 zassert_true(val_is_equal(mad.data[14], 62.0, 1E-6), NULL);
1135 zassert_true(val_is_equal(mad.data[15], -38.0, 1E-6), NULL);
1136 }
1137
1138 #ifndef CONFIG_ZSL_SINGLE_PRECISION
ZTEST(zsl_tests_double,test_matrix_vector_wedge)1139 ZTEST(zsl_tests_double, test_matrix_vector_wedge)
1140 {
1141 int rc = 0;
1142
1143 ZSL_MATRIX_DEF(m, 5, 6);
1144 ZSL_MATRIX_DEF(m2, 7, 7);
1145 ZSL_VECTOR_DEF(v, 6);
1146 ZSL_VECTOR_DEF(v2, 2);
1147 ZSL_VECTOR_DEF(v3, 9);
1148
1149 zsl_real_t a[30] = {
1150 2.0, 4.0, -5.0, 1.1, 8.3, 9.9,
1151 -0.4, -6.6, 3.4, 1.5, -6.9, 0.1,
1152 0.0, -2.5, -9.8, 1.2, 3.8, -0.9,
1153 6.1, -4.3, 8.8, 7.6, -0.9, 2.9,
1154 5.0, 7.1, 1.0, 0.0, -4.7, 0.2
1155 };
1156
1157 /* Assign array to matrix. */
1158 rc = zsl_mtx_from_arr(&m, a);
1159 zassert_true(rc == 0, NULL);
1160
1161 /* Compute the wedge product. */
1162 rc = zsl_mtx_vec_wedge(&m, &v);
1163 zassert_true(rc == 0, NULL);
1164
1165 /* Check the results. The vector 'v' should be perpendicular to all the
1166 * input vectors, the columns in the matrix 'm', so the dot product. Should
1167 * be zero. */
1168 zsl_real_t d;
1169
1170 ZSL_VECTOR_DEF(w, 6);
1171 for (size_t i = 0; i < 5; i++) {
1172 zsl_mtx_get_row(&m, i, w.data);
1173 zsl_vec_dot(&v, &w, &d);
1174 zassert_true(val_is_equal(d, 0.0, 1E-6), NULL);
1175 }
1176
1177 /* In the following cases, the dimensions of 'm' and/or 'v' are invalid,
1178 * so the function should return an error. */
1179 rc = zsl_mtx_vec_wedge(&m2, &v);
1180 zassert_true(rc == -EINVAL, NULL);
1181 rc = zsl_mtx_vec_wedge(&m, &v2);
1182 zassert_true(rc == -EINVAL, NULL);
1183 rc = zsl_mtx_vec_wedge(&m, &v3);
1184 zassert_true(rc == -EINVAL, NULL);
1185 }
1186 #endif
1187
ZTEST(zsl_tests,test_matrix_reduce)1188 ZTEST(zsl_tests, test_matrix_reduce)
1189 {
1190 int rc = 0;
1191
1192 ZSL_MATRIX_DEF(mred, 3, 3);
1193
1194 /* Input matrix. */
1195 zsl_real_t data[16] = { 2.0, -3.0, 1.0, 5.0,
1196 -4.0, 4.0, 3.0, -3.0,
1197 -2.0, 6.0, 1.0, 0.0,
1198 3.0, 4.0, -5.0, -8.0 };
1199
1200 struct zsl_mtx m = {
1201 .sz_rows = 4,
1202 .sz_cols = 4,
1203 .data = data
1204 };
1205
1206 /* Init matrix 'mred'. */
1207 rc = zsl_mtx_init(&mred, NULL);
1208 zassert_equal(rc, 0, NULL);
1209
1210 rc = zsl_mtx_reduce(&m, &mred, 0, 2);
1211 zassert_equal(rc, 0, NULL);
1212
1213 /* Expected output. */
1214 zsl_real_t data2[9] = { -4.0, 4.0, -3.0,
1215 -2.0, 6.0, 0.0,
1216 3.0, 4.0, -8.0 };
1217
1218 struct zsl_mtx m2 = {
1219 .sz_rows = 3,
1220 .sz_cols = 3,
1221 .data = data2
1222 };
1223
1224 /* Check the output. */
1225 for (size_t i = 0; i < (mred.sz_rows * mred.sz_cols); i++) {
1226 zassert_true(val_is_equal(mred.data[i], m2.data[i], 1E-6),
1227 NULL);
1228 }
1229
1230 rc = zsl_mtx_reduce(&m, &mred, 1, 3);
1231 zassert_equal(rc, 0, NULL);
1232
1233 /* Expected output. */
1234 zsl_real_t data3[9] = { 2.0, -3.0, 1.0,
1235 -2.0, 6.0, 1.0,
1236 3.0, 4.0, -5.0 };
1237
1238 struct zsl_mtx m3 = {
1239 .sz_rows = 3,
1240 .sz_cols = 3,
1241 .data = data3
1242 };
1243
1244 /* Check the output. */
1245 for (size_t i = 0; i < (mred.sz_rows * mred.sz_cols); i++) {
1246 zassert_true(val_is_equal(mred.data[i], m3.data[i], 1E-6),
1247 NULL);
1248 }
1249
1250 rc = zsl_mtx_reduce(&m, &mred, 1, 5);
1251 zassert_equal(rc, -EINVAL, NULL);
1252 }
1253
ZTEST(zsl_tests,test_matrix_reduce_iter)1254 ZTEST(zsl_tests, test_matrix_reduce_iter)
1255 {
1256 int rc = 0;
1257 ZSL_MATRIX_DEF(mred, 3, 3);
1258 ZSL_MATRIX_DEF(mred2, 2, 2);
1259
1260 /* place holder matrices for iteration*/
1261 ZSL_MATRIX_DEF(place1, 4, 4);
1262 ZSL_MATRIX_DEF(place2, 4, 4);
1263
1264
1265 /* Input matrix. */
1266 zsl_real_t data[16] = { 2.0, -3.0, 1.0, 5.0,
1267 -4.0, 4.0, 3.0, -3.0,
1268 -2.0, 6.0, 1.0, 0.0,
1269 3.0, 4.0, -5.0, -8.0 };
1270
1271 struct zsl_mtx m = {
1272 .sz_rows = 4,
1273 .sz_cols = 4,
1274 .data = data
1275 };
1276
1277 /* Init output matrices. */
1278 rc = zsl_mtx_init(&mred, NULL);
1279 zassert_equal(rc, 0, NULL);
1280 rc = zsl_mtx_init(&mred2, NULL);
1281 zassert_equal(rc, 0, NULL);
1282
1283 do{
1284 rc = zsl_mtx_reduce_iter(&m, &mred, &place1, &place2);
1285 } while(rc != 0);
1286 zassert_equal(rc, 0, NULL);
1287
1288 /* Expected output. */
1289 zsl_real_t data2[9] = { 4.0, 3.0, -3.0,
1290 6.0, 1.0, 0.0,
1291 4.0, -5.0, -8.0 };
1292
1293 struct zsl_mtx m2 = {
1294 .sz_rows = 3,
1295 .sz_cols = 3,
1296 .data = data2
1297 };
1298
1299 /* Check the output. */
1300 for (size_t i = 0; i < (mred.sz_rows * mred.sz_cols); i++) {
1301 zassert_true(val_is_equal(mred.data[i], m2.data[i], 1E-6),
1302 NULL);
1303 }
1304
1305 do{
1306 rc = zsl_mtx_reduce_iter(&m, &mred2, &place1, &place2);
1307 } while(rc != 0);
1308 zassert_equal(rc, 0, NULL);
1309
1310 /* Expected output. */
1311 zsl_real_t data3[4] = { 1.0, 0.0,
1312 -5.0, -8.0 };
1313 struct zsl_mtx m3 = {
1314 .sz_rows = 2,
1315 .sz_cols = 2,
1316 .data = data3
1317 };
1318
1319 /* Check the output. */
1320 for (size_t i = 0; i < (mred2.sz_rows * mred2.sz_cols); i++) {
1321 zassert_true(val_is_equal(mred2.data[i], m3.data[i], 1E-6),
1322 NULL);
1323 }
1324 }
1325
ZTEST(zsl_tests,test_matrix_augm_diag)1326 ZTEST(zsl_tests, test_matrix_augm_diag)
1327 {
1328 int rc = 0;
1329
1330 ZSL_MATRIX_DEF(maugm, 3, 3);
1331 ZSL_MATRIX_DEF(maugm2, 4, 4);
1332
1333 /* Input matrix. */
1334 zsl_real_t data[4] = { 1.0, 0.0,
1335 -5.0, -8.0 };
1336
1337 struct zsl_mtx m = {
1338 .sz_rows = 2,
1339 .sz_cols = 2,
1340 .data = data
1341 };
1342
1343 /* Init output matrices. */
1344 rc = zsl_mtx_init(&maugm, NULL);
1345 zassert_equal(rc, 0, NULL);
1346 rc = zsl_mtx_init(&maugm2, NULL);
1347 zassert_equal(rc, 0, NULL);
1348
1349 rc = zsl_mtx_augm_diag(&m, &maugm);
1350 zassert_equal(rc, 0, NULL);
1351
1352 /* Expected output. */
1353 zsl_real_t data2[9] = { 1.0, 0.0, 0.0,
1354 0.0, 1.0, 0.0,
1355 0.0, -5.0, -8.0 };
1356
1357 struct zsl_mtx m2 = {
1358 .sz_rows = 3,
1359 .sz_cols = 3,
1360 .data = data2
1361 };
1362
1363 /* Check the output. */
1364 for (size_t i = 0; i < (maugm.sz_rows * maugm.sz_cols); i++) {
1365 zassert_true(val_is_equal(maugm.data[i], m2.data[i], 1E-6),
1366 NULL);
1367 }
1368
1369 rc = zsl_mtx_augm_diag(&m, &maugm2);
1370 zassert_equal(rc, 0, NULL);
1371
1372 /* Expected output. */
1373 zsl_real_t data3[16] = { 1.0, 0.0, 0.0, 0.0,
1374 0.0, 1.0, 0.0, 0.0,
1375 0.0, 0.0, 1.0, 0.0,
1376 0.0, 0.0, -5.0, -8.0 };
1377
1378 struct zsl_mtx m3 = {
1379 .sz_rows = 4,
1380 .sz_cols = 4,
1381 .data = data3
1382 };
1383
1384 /* Check the output. */
1385 for (size_t i = 0; i < (maugm2.sz_rows * maugm2.sz_cols); i++) {
1386 zassert_true(val_is_equal(maugm2.data[i], m3.data[i], 1E-6),
1387 NULL);
1388 }
1389 }
1390
ZTEST(zsl_tests,test_matrix_deter_3x3)1391 ZTEST(zsl_tests, test_matrix_deter_3x3)
1392 {
1393 int rc = 0;
1394 zsl_real_t x = 0.0;
1395
1396 /* Input matrix. */
1397 zsl_real_t data[9] = { 4.0, 3.0, -3.0,
1398 6.0, 1.0, 0.0,
1399 4.0, -5.0, -8.0 };
1400
1401 struct zsl_mtx m = {
1402 .sz_rows = 3,
1403 .sz_cols = 3,
1404 .data = data
1405 };
1406
1407 rc = zsl_mtx_deter_3x3(&m, &x);
1408 zassert_equal(rc, 0, NULL);
1409
1410 /* Check the output. */
1411 zassert_equal(x, 214.0, NULL);
1412 }
1413
ZTEST(zsl_tests,test_matrix_deter)1414 ZTEST(zsl_tests, test_matrix_deter)
1415 {
1416 int rc = 0;
1417 zsl_real_t x = 0.0;
1418
1419 /* Input matrix. */
1420 zsl_real_t data[25] = { 2.0, -3.0, 1.0, 5.0, 7.0,
1421 -4.0, 4.0, 3.0, -3.0, -4.0,
1422 5.0, 3.0, 0.0, -2.0, -1.0,
1423 -2.0, 6.0, 1.0, 0.0, 8.0,
1424 3.0, 4.0, -5.0, -8.0, -9.0 };
1425 struct zsl_mtx m = {
1426 .sz_rows = 5,
1427 .sz_cols = 5,
1428 .data = data
1429 };
1430
1431 rc = zsl_mtx_deter(&m, &x);
1432 zassert_equal(rc, 0, NULL);
1433
1434 /* Check the output. */
1435 zassert_equal(x, -509.0, NULL);
1436 }
1437
ZTEST(zsl_tests,test_matrix_gauss_elim)1438 ZTEST(zsl_tests, test_matrix_gauss_elim)
1439 {
1440 int rc = 0;
1441
1442 ZSL_MATRIX_DEF(mg, 3, 3);
1443 ZSL_MATRIX_DEF(mi, 3, 3);
1444
1445 /* Input matrix. */
1446 zsl_real_t data[9] = { 4.0, 3.0, 0.0,
1447 2.0, 1.0, -3.0,
1448 -4.0, -5.0, -8.0 };
1449
1450 struct zsl_mtx m = {
1451 .sz_rows = 3,
1452 .sz_cols = 3,
1453 .data = data
1454 };
1455
1456 /* Init the output matrices. */
1457 rc = zsl_mtx_init(&mg, NULL);
1458 zassert_equal(rc, 0, NULL);
1459 rc = zsl_mtx_init(&mi, NULL);
1460 zassert_equal(rc, 0, NULL);
1461
1462 rc = zsl_mtx_gauss_elim(&m, &mg, &mi, 1, 0);
1463 zassert_equal(rc, 0, NULL);
1464
1465 /* Expected output. */
1466 zsl_real_t data2[9] = { 0.0, 1.0, 6.0,
1467 2.0, 1.0, -3.0,
1468 0.0, -3.0, -14.0 };
1469
1470 struct zsl_mtx m2 = {
1471 .sz_rows = 3,
1472 .sz_cols = 3,
1473 .data = data2
1474 };
1475
1476 /* Check the output. */
1477 for (size_t i = 0; i < (mg.sz_rows * mg.sz_cols); i++) {
1478 zassert_true(val_is_equal(mg.data[i], m2.data[i], 1E-6), NULL);
1479 }
1480
1481 rc = zsl_mtx_gauss_elim(&m, &mg, &mi, 0, 2);
1482 zassert_equal(rc, 0, NULL);
1483
1484 /* Check the output. */
1485 for (size_t i = 0; i < (mg.sz_rows * mg.sz_cols); i++) {
1486 zassert_true(val_is_equal(mg.data[i], m.data[i], 1E-6), NULL);
1487 }
1488 }
1489
ZTEST(zsl_tests,test_matrix_gauss_elim_d)1490 ZTEST(zsl_tests, test_matrix_gauss_elim_d)
1491 {
1492 int rc = 0;
1493
1494 ZSL_MATRIX_DEF(mi, 3, 3);
1495 ZSL_MATRIX_DEF(mcopy, 3, 3);
1496
1497 /* Input matrix. */
1498 zsl_real_t data[9] = { 4.0, 3.0, 0.0,
1499 2.0, 1.0, -3.0,
1500 -4.0, -5.0, -8.0 };
1501
1502 struct zsl_mtx m = {
1503 .sz_rows = 3,
1504 .sz_cols = 3,
1505 .data = data
1506 };
1507
1508 /* Init the output matrix. */
1509 rc = zsl_mtx_init(&mi, NULL);
1510 zassert_equal(rc, 0, NULL);
1511
1512 rc = zsl_mtx_gauss_elim_d(&m, &mi, 1, 0);
1513 zassert_equal(rc, 0, NULL);
1514
1515 /* Expected output. */
1516 zsl_real_t data2[9] = { 0.0, 1.0, 6.0,
1517 2.0, 1.0, -3.0,
1518 0.0, -3.0, -14.0 };
1519
1520 struct zsl_mtx m2 = {
1521 .sz_rows = 3,
1522 .sz_cols = 3,
1523 .data = data2
1524 };
1525
1526 /* Check the output. */
1527 for (size_t i = 0; i < (m.sz_rows * m.sz_cols); i++) {
1528 zassert_true(val_is_equal(m.data[i], m2.data[i], 1E-6), NULL);
1529 }
1530
1531 /* Copy 'm' into 'mcopy'. */
1532 rc = zsl_mtx_copy(&mcopy, &m);
1533 zassert_equal(rc, 0, NULL);
1534
1535 rc = zsl_mtx_gauss_elim_d(&m, &mi, 2, 0);
1536 zassert_equal(rc, 0, NULL);
1537
1538 /* Check the output. */
1539 for (size_t i = 0; i < (m.sz_rows * m.sz_cols); i++) {
1540 zassert_true(val_is_equal(m.data[i], mcopy.data[i], 1E-6),
1541 NULL);
1542 }
1543 }
1544
ZTEST(zsl_tests,test_matrix_gauss_reduc)1545 ZTEST(zsl_tests, test_matrix_gauss_reduc)
1546 {
1547 int rc = 0;
1548
1549 ZSL_MATRIX_DEF(va, 3, 3);
1550 ZSL_MATRIX_DEF(vb, 3, 3);
1551
1552 /* Input matrix with range 3. */
1553 zsl_real_t data[9] = { 4.0, 3.0, 0.0,
1554 2.0, 1.0, -3.0,
1555 -4.0, -5.0, -8.0 };
1556
1557 struct zsl_mtx ma = {
1558 .sz_rows = 3,
1559 .sz_cols = 3,
1560 .data = data
1561 };
1562
1563 /* Input matrix with range 2. */
1564 zsl_real_t datb[9] = { 4.0, 2.0, 0.0,
1565 2.0, 1.0, -3.0,
1566 -4.0, -2.0, -8.0 };
1567
1568 struct zsl_mtx mb = {
1569 .sz_rows = 3,
1570 .sz_cols = 3,
1571 .data = datb
1572 };
1573
1574 /* Init the output matrices. */
1575 rc = zsl_mtx_init(&va, NULL);
1576 zassert_equal(rc, 0, NULL);
1577 rc = zsl_mtx_init(&vb, NULL);
1578 zassert_equal(rc, 0, NULL);
1579
1580 rc = zsl_mtx_gauss_reduc(&ma, &vb, &va);
1581 zassert_equal(rc, 0, NULL);
1582
1583 /* Check the output. */
1584 zsl_mtx_init(&vb, zsl_mtx_entry_fn_identity);
1585 for (size_t i = 0; i < (va.sz_rows * va.sz_cols); i++) {
1586 zassert_true(val_is_equal(va.data[i], vb.data[i], 1E-6), NULL);
1587 }
1588
1589 rc = zsl_mtx_gauss_reduc(&mb, &va, &vb);
1590 zassert_equal(rc, 0, NULL);
1591
1592 /* Check the output. */
1593 zsl_mtx_init(&va, zsl_mtx_entry_fn_identity);
1594 zsl_mtx_set(&va, 0, 1, 0.5);
1595 zsl_mtx_set(&va, 1, 1, 0.0);
1596 for (size_t i = 0; i < (vb.sz_rows * vb.sz_cols); i++) {
1597 zassert_true(val_is_equal(va.data[i], vb.data[i], 1E-6), NULL);
1598 }
1599 }
1600
ZTEST(zsl_tests,test_matrix_gram_schmidt_sq)1601 ZTEST(zsl_tests, test_matrix_gram_schmidt_sq)
1602 {
1603 int rc;
1604
1605 ZSL_MATRIX_DEF(mot, 3, 3);
1606
1607 /* Input matrix. */
1608 zsl_real_t data[9] = { 1.0, 5.0, -1.0,
1609 2.0, -4.0, -2.0,
1610 4.0, 3.0, 0.0 };
1611
1612 struct zsl_mtx m = {
1613 .sz_rows = 3,
1614 .sz_cols = 3,
1615 .data = data
1616 };
1617
1618 /* Expected output. */
1619 zsl_real_t dtst[9] = { 1.0, 4.5714285714, -1.2714138287,
1620 2.0, -4.8571428571, -0.9824561404,
1621 4.0, 1.2857142857, 0.8090815273 };
1622
1623 struct zsl_mtx mt = {
1624 .sz_rows = 3,
1625 .sz_cols = 3,
1626 .data = dtst
1627 };
1628
1629 /* Init matrix mot. */
1630 rc = zsl_mtx_init(&mot, NULL);
1631 zassert_equal(rc, 0, NULL);
1632
1633 /* Perform the Gram-Schmidt process. */
1634 rc = zsl_mtx_gram_schmidt(&m, &mot);
1635 zassert_equal(rc, 0, NULL);
1636
1637 /* Check the output. */
1638 for (size_t g = 0; g < (m.sz_rows * m.sz_cols); g++) {
1639 zassert_true(val_is_equal(mot.data[g], mt.data[g], 1E-6), NULL);
1640 }
1641 }
1642
ZTEST(zsl_tests,test_matrix_gram_schmidt_rect)1643 ZTEST(zsl_tests, test_matrix_gram_schmidt_rect)
1644 {
1645 int rc;
1646
1647 ZSL_MATRIX_DEF(mot, 4, 3);
1648
1649 /* Input matrix. */
1650 zsl_real_t data[12] = { 1.0, 5.0, 6.0,
1651 -1.0, 2.0, -2.0,
1652 -4.0, -2.0, 8.0,
1653 4.0, 3.0, 0.0 };
1654
1655 struct zsl_mtx m = {
1656 .sz_rows = 4,
1657 .sz_cols = 3,
1658 .data = data
1659 };
1660
1661 /* Expected output. */
1662 zsl_real_t dtst[12] = { 1.0, 4.3235294118, 2.4160177976,
1663 -1.0, 2.6764705882, -5.3615127920,
1664 -4.0, 0.7058823529, 4.4760845384,
1665 4.0, 0.2941176471, 2.5317018910 };
1666
1667 struct zsl_mtx mt = {
1668 .sz_rows = 4,
1669 .sz_cols = 3,
1670 .data = dtst
1671 };
1672
1673 /* Init matrix mot. */
1674 rc = zsl_mtx_init(&mot, NULL);
1675 zassert_equal(rc, 0, NULL);
1676
1677 /* Perform the Gram-Schmidt process. */
1678 rc = zsl_mtx_gram_schmidt(&m, &mot);
1679 zassert_equal(rc, 0, NULL);
1680
1681 /* Check the output. */
1682 for (size_t g = 0; g < (m.sz_rows * m.sz_cols); g++) {
1683 zassert_true(val_is_equal(mot.data[g], mt.data[g], 1E-6), NULL);
1684 }
1685 }
1686
ZTEST(zsl_tests,test_matrix_cols_norm)1687 ZTEST(zsl_tests, test_matrix_cols_norm)
1688 {
1689 int rc = 0;
1690
1691 zsl_real_t norm = 0.0;
1692
1693 ZSL_MATRIX_DEF(m2, 3, 3);
1694 ZSL_VECTOR_DEF(v, 3);
1695
1696 /* Input matrix. */
1697 zsl_real_t data[9] = { 67.5, 47.0, 31.5,
1698 32.0, 256.5, 94.5,
1699 226.5, 415.0, 302.0 };
1700 struct zsl_mtx m = {
1701 .sz_rows = 3,
1702 .sz_cols = 3,
1703 .data = data
1704 };
1705
1706 /* Init the output matrix. */
1707 rc = zsl_mtx_init(&m2, NULL);
1708 zassert_equal(rc, 0, NULL);
1709
1710 rc = zsl_mtx_cols_norm(&m, &m2);
1711 zassert_equal(rc, 0, NULL);
1712
1713 /* Check the output. */
1714
1715 for (size_t i = 0; i < m.sz_rows; i++) {
1716 zsl_mtx_get_col(&m2, i, v.data);
1717 norm = zsl_vec_norm(&v);
1718 zassert_true(val_is_equal(norm, 1.0, 1E-6), NULL);
1719 }
1720 }
1721
ZTEST(zsl_tests,test_matrix_norm_elem)1722 ZTEST(zsl_tests, test_matrix_norm_elem)
1723 {
1724 int rc = 0;
1725
1726 ZSL_MATRIX_DEF(m2, 3, 3);
1727 ZSL_MATRIX_DEF(m3, 3, 3);
1728
1729 /* Input matrix. */
1730 zsl_real_t data[9] = { 67.5, 40.0, 31.5,
1731 0.0, 256.5, 94.5,
1732 226.5, 415.0, 302.0 };
1733 struct zsl_mtx m = {
1734 .sz_rows = 3,
1735 .sz_cols = 3,
1736 .data = data
1737 };
1738
1739 /* Init the output matrices. */
1740 rc = zsl_mtx_init(&m2, NULL);
1741 zassert_equal(rc, 0, NULL);
1742 rc = zsl_mtx_init(&m3, NULL);
1743 zassert_equal(rc, 0, NULL);
1744
1745 rc = zsl_mtx_norm_elem(&m, &m2, &m3, 0, 1);
1746 zassert_equal(rc, 0, NULL);
1747
1748 /* Check the output. */
1749 zassert_true(val_is_equal(m2.data[0], 1.6875, 1E-6), NULL);
1750 zassert_true(val_is_equal(m2.data[1], 1.0, 1E-6), NULL);
1751 zassert_true(val_is_equal(m2.data[2], 0.7875, 1E-6), NULL);
1752 zassert_true(val_is_equal(m2.data[3], 0.0, 1E-6), NULL);
1753 zassert_true(val_is_equal(m2.data[4], 256.5, 1E-6), NULL);
1754 zassert_true(val_is_equal(m2.data[5], 94.5, 1E-6), NULL);
1755 zassert_true(val_is_equal(m2.data[6], 226.5, 1E-6), NULL);
1756 zassert_true(val_is_equal(m2.data[7], 415.0, 1E-6), NULL);
1757 zassert_true(val_is_equal(m2.data[8], 302.0, 1E-6), NULL);
1758
1759 for (size_t i = 0; i < m.sz_rows; i++) {
1760 zassert_equal(m3.data[i], 0.0, NULL);
1761 }
1762
1763 rc = zsl_mtx_norm_elem(&m, &m2, &m3, 1, 0);
1764 zassert_equal(rc, 0, NULL);
1765
1766 /* Check the output. */
1767 zassert_true(zsl_mtx_is_equal(&m, &m2), NULL);
1768
1769 for (size_t i = 0; i < m.sz_rows; i++) {
1770 zassert_equal(m3.data[i], 0.0, NULL);
1771 }
1772 }
1773
ZTEST(zsl_tests,test_matrix_norm_elem_d)1774 ZTEST(zsl_tests, test_matrix_norm_elem_d)
1775 {
1776 int rc = 0;
1777
1778 ZSL_MATRIX_DEF(m2, 3, 3);
1779
1780 /* Input matrix. */
1781 zsl_real_t data[9] = { 67.5, 47.0, 31.5,
1782 32.0, 256.5, 94.5,
1783 226.5, 415.0, 302.0 };
1784 struct zsl_mtx m = {
1785 .sz_rows = 3,
1786 .sz_cols = 3,
1787 .data = data
1788 };
1789
1790 /* Init the output matrix. */
1791 rc = zsl_mtx_init(&m2, NULL);
1792 zassert_equal(rc, 0, NULL);
1793
1794 rc = zsl_mtx_norm_elem_d(&m, &m2, 1, 0);
1795 zassert_equal(rc, 0, NULL);
1796
1797 /* Check the output. */
1798 zassert_true(val_is_equal(m.data[0], 67.5, 1E-6), NULL);
1799 zassert_true(val_is_equal(m.data[1], 47.0, 1E-6), NULL);
1800 zassert_true(val_is_equal(m.data[2], 31.5, 1E-6), NULL);
1801 zassert_true(val_is_equal(m.data[3], 1.0, 1E-6), NULL);
1802 zassert_true(val_is_equal(m.data[4], 8.015625, 1E-6), NULL);
1803 zassert_true(val_is_equal(m.data[5], 2.953125, 1E-6), NULL);
1804 zassert_true(val_is_equal(m.data[6], 226.5, 1E-6), NULL);
1805 zassert_true(val_is_equal(m.data[7], 415.0, 1E-6), NULL);
1806 zassert_true(val_is_equal(m.data[8], 302.0, 1E-6), NULL);
1807
1808 for (size_t i = 0; i < m.sz_rows; i++) {
1809 zassert_equal(m2.data[i], 0.0, NULL);
1810 }
1811 }
1812
ZTEST(zsl_tests,test_matrix_inv_3x3)1813 ZTEST(zsl_tests, test_matrix_inv_3x3)
1814 {
1815 int rc = 0;
1816
1817 ZSL_MATRIX_DEF(mi, 3, 3);
1818
1819 /* Input matrix. */
1820 zsl_real_t data[9] = { 67.5, 43.0, 31.5,
1821 226.5, 256.5, 94.5,
1822 226.5, 415.0, 302.0 };
1823 struct zsl_mtx m = {
1824 .sz_rows = 3,
1825 .sz_cols = 3,
1826 .data = data
1827 };
1828
1829 /* Init matrix mi. */
1830 rc = zsl_mtx_init(&mi, NULL);
1831 zassert_equal(rc, 0, NULL);
1832
1833 rc = zsl_mtx_inv_3x3(&m, &mi);
1834 zassert_equal(rc, 0, NULL);
1835
1836 /* Check the output. */
1837 zassert_true(val_is_equal(mi.data[0], 0.02261063, 1E-6), NULL);
1838 zassert_true(val_is_equal(mi.data[1], 0.00005114, 1E-6), NULL);
1839 zassert_true(val_is_equal(mi.data[2], -0.00237440, 1E-6), NULL);
1840 zassert_true(val_is_equal(mi.data[3], -0.02778553, 1E-6), NULL);
1841 zassert_true(val_is_equal(mi.data[4], 0.00783351, 1E-6), NULL);
1842 zassert_true(val_is_equal(mi.data[5], 0.00044695, 1E-6), NULL);
1843 zassert_true(val_is_equal(mi.data[6], 0.02122413, 1E-6), NULL);
1844 zassert_true(val_is_equal(mi.data[7], -0.01080295, 1E-6), NULL);
1845 zassert_true(val_is_equal(mi.data[8], 0.00447788, 1E-6), NULL);
1846 }
1847
ZTEST(zsl_tests,test_matrix_inv)1848 ZTEST(zsl_tests, test_matrix_inv)
1849 {
1850 int rc = 0;
1851
1852 ZSL_MATRIX_DEF(mi, 5, 5);
1853
1854 /* Input matrix. */
1855 zsl_real_t data[25] = { 1.0, 1.0, 2.0, 2.0, 1.0,
1856 0.0, 0.0, 0.0, 1.0, 2.0,
1857 0.0, 0.0, 1.0, 2.0, 2.0,
1858 0.0, 0.0, 1.0, 1.0, 2.0,
1859 0.0, 1.0, 1.0, 2.0, 1.0 };
1860 struct zsl_mtx m = {
1861 .sz_rows = 5,
1862 .sz_cols = 5,
1863 .data = data
1864 };
1865
1866 /* The inverse of data for test purposes. */
1867 zsl_real_t dtst[25] = { 1.0, 1.0, 0.0, -1.0, -1.0,
1868 0.0, 0.5, -1.5, 0.5, 1.0,
1869 0.0, -1.0, 0.0, 1.0, 0.0,
1870 -0.0, -0.0, 1.0, -1.0, -0.0,
1871 -0.0, 0.5, -0.5, 0.5, -0.0 };
1872 struct zsl_mtx mtst = {
1873 .sz_rows = 5,
1874 .sz_cols = 5,
1875 .data = dtst
1876 };
1877
1878 /* Init matrix mi. */
1879 rc = zsl_mtx_init(&mi, NULL);
1880 zassert_equal(rc, 0, NULL);
1881
1882 rc = zsl_mtx_inv(&m, &mi);
1883 zassert_equal(rc, 0, NULL);
1884
1885 /* Check the output. */
1886 zassert_true(zsl_mtx_is_equal(&mi, &mtst), NULL);
1887 }
1888
ZTEST(zsl_tests,test_matrix_cholesky)1889 ZTEST(zsl_tests, test_matrix_cholesky)
1890 {
1891 int rc;
1892
1893 ZSL_MATRIX_DEF(mc, 7, 4);
1894 ZSL_MATRIX_DEF(l, 3, 3);
1895 ZSL_MATRIX_DEF(l2, 5, 3);
1896
1897 /* Input symmetric matrix. */
1898 zsl_real_t data[9] = { 4.0, 12.0, -16.0,
1899 12.0, 37.0, -43.0,
1900 -16.0, -43.0, 98.0 };
1901
1902 struct zsl_mtx ma = {
1903 .sz_rows = 3,
1904 .sz_cols = 3,
1905 .data = data
1906 };
1907
1908 /* Input non-symmetric matrix. */
1909 zsl_real_t datb[16] = { 5.1, -3.2, 4.9, -8.1,
1910 2.3, -4.1, -2.8, 0.2,
1911 0.0, -7.7, 2.1, 0.0,
1912 -0.7, 8.1, -5.5, 3.7 };
1913
1914 struct zsl_mtx mb = {
1915 .sz_rows = 4,
1916 .sz_cols = 4,
1917 .data = datb
1918 };
1919
1920 /* Expected output. */
1921 zsl_real_t dt[9] = { 2.0, 0.0, 0.0,
1922 6.0, 1.0, 0.0,
1923 -8.0, 5.0, 3.0 };
1924
1925 struct zsl_mtx lo = {
1926 .sz_rows = 3,
1927 .sz_cols = 3,
1928 .data = dt
1929 };
1930
1931 /* Init the output matrix. */
1932 rc = zsl_mtx_init(&l, NULL);
1933 zassert_equal(rc, 0, NULL);
1934
1935 /* Compute the Cholesky decomposition. */
1936 rc = zsl_mtx_cholesky(&ma, &l);
1937 zassert_equal(rc, 0, NULL);
1938
1939 /* Check the output. */
1940 for (size_t g = 0; g < (ma.sz_rows * ma.sz_cols); g++) {
1941 zassert_true(val_is_equal(l.data[g], lo.data[g], 1E-6), NULL);
1942 }
1943
1944 /* In the following examples, an error is expected due to invalid input
1945 * matrices. */
1946 rc = zsl_mtx_cholesky(&mb, &l);
1947 zassert_equal(rc, -EINVAL, NULL);
1948 rc = zsl_mtx_cholesky(&mc, &l);
1949 zassert_equal(rc, -EINVAL, NULL);
1950 rc = zsl_mtx_cholesky(&ma, &l2);
1951 zassert_equal(rc, -EINVAL, NULL);
1952 }
1953
ZTEST(zsl_tests,test_matrix_balance)1954 ZTEST(zsl_tests, test_matrix_balance)
1955 {
1956 int rc;
1957
1958 ZSL_MATRIX_DEF(moa, 4, 4);
1959 ZSL_MATRIX_DEF(mob, 4, 4);
1960
1961 /* Input non-symmetric matrix. */
1962 zsl_real_t data[16] = { 5.1, -3.2, 4.9, -8.1,
1963 2.3, -4.1, -2.8, 0.2,
1964 0.0, -7.7, 2.1, 0.0,
1965 -0.7, 8.1, -5.5, 3.7 };
1966
1967 struct zsl_mtx ma = {
1968 .sz_rows = 4,
1969 .sz_cols = 4,
1970 .data = data
1971 };
1972
1973 /* Input symmetric matrix. */
1974 zsl_real_t datb[16] = { 5.1, 2.3, 0.0, -8.1,
1975 2.3, -4.1, -2.8, 0.2,
1976 0.0, -2.8, 2.1, -5.5,
1977 -8.1, 0.2, -5.5, 3.7 };
1978
1979 struct zsl_mtx mb = {
1980 .sz_rows = 4,
1981 .sz_cols = 4,
1982 .data = datb
1983 };
1984
1985 /* Expected output. */
1986 zsl_real_t dt[16] = { 5.1, -1.6, 2.45, -8.1,
1987 4.6, -4.1, -2.8, 0.4,
1988 0.0, -7.7, 2.1, 0.0,
1989 -0.7, 4.05, -2.75, 3.7 };
1990
1991 struct zsl_mtx mt = {
1992 .sz_rows = 4,
1993 .sz_cols = 4,
1994 .data = dt
1995 };
1996
1997 /* Init output matrices. */
1998 rc = zsl_mtx_init(&moa, NULL);
1999 zassert_equal(rc, 0, NULL);
2000 rc = zsl_mtx_init(&mob, NULL);
2001 zassert_equal(rc, 0, NULL);
2002
2003 /* Balance the input matrices. */
2004 rc = zsl_mtx_balance(&ma, &moa);
2005 zassert_equal(rc, 0, NULL);
2006 rc = zsl_mtx_balance(&mb, &mob);
2007 zassert_equal(rc, 0, NULL);
2008
2009 /* Check the output. */
2010 for (size_t g = 0; g < (ma.sz_rows * ma.sz_cols); g++) {
2011 zassert_true(val_is_equal(moa.data[g], mt.data[g], 1E-6), NULL);
2012 zassert_true(val_is_equal(mob.data[g], mb.data[g], 1E-6), NULL);
2013 }
2014 }
2015
ZTEST(zsl_tests,test_matrix_householder_sq)2016 ZTEST(zsl_tests, test_matrix_householder_sq)
2017 {
2018 int rc;
2019
2020 ZSL_MATRIX_DEF(h, 3, 3);
2021
2022 /* Input matrix. */
2023 zsl_real_t data[9] = { 0.0, 0.0, 4.0,
2024 2.0, 4.0, -2.0,
2025 0.0, 4.0, 2.0 };
2026
2027 struct zsl_mtx m = {
2028 .sz_rows = 3,
2029 .sz_cols = 3,
2030 .data = data
2031 };
2032
2033 /* Init matrix h. */
2034 rc = zsl_mtx_init(&h, NULL);
2035 zassert_equal(rc, 0, NULL);
2036
2037 /* Compute the Householder matrix. */
2038 rc = zsl_mtx_householder(&m, &h, false);
2039 zassert_equal(rc, 0, NULL);
2040
2041 /* Expected output. */
2042 zsl_real_t dtst[9] = { 0.0, 1.0, 0.0,
2043 1.0, 0.0, 0.0,
2044 0.0, 0.0, 1.0 };
2045
2046 struct zsl_mtx mt = {
2047 .sz_rows = 3,
2048 .sz_cols = 3,
2049 .data = dtst
2050 };
2051
2052 /* Check the output. */
2053 for (size_t g = 0; g < (m.sz_rows * m.sz_cols); g++) {
2054 zassert_true(val_is_equal(h.data[g], mt.data[g], 1E-6), NULL);
2055 }
2056
2057 /* Compute the Hessenberg-Householder matrix. */
2058 rc = zsl_mtx_householder(&m, &h, true);
2059 zassert_equal(rc, 0, NULL);
2060
2061 /* Expected output. */
2062 zsl_real_t dtsa[16] = { 1.0, 0.0, 0.0,
2063 0.0, 1.0, 0.0,
2064 0.0, 0.0, 1.0 };
2065
2066 struct zsl_mtx mt2 = {
2067 .sz_rows = 3,
2068 .sz_cols = 3,
2069 .data = dtsa
2070 };
2071
2072 /* Check the output. */
2073 for (size_t g = 0; g < (h.sz_rows * h.sz_cols); g++) {
2074 zassert_true(val_is_equal(h.data[g], mt2.data[g], 1E-6), NULL);
2075 }
2076 }
2077
ZTEST(zsl_tests,test_matrix_householder_rect)2078 ZTEST(zsl_tests, test_matrix_householder_rect)
2079 {
2080 int rc;
2081
2082 ZSL_MATRIX_DEF(h, 4, 4);
2083
2084 /* Input matrix. */
2085 zsl_real_t data[12] = { 1.0, -1.0, 4.0,
2086 1.0, 4.0, -2.0,
2087 1.0, 4.0, 2.0,
2088 1.0, -1.0, 0.0 };
2089
2090 struct zsl_mtx m = {
2091 .sz_rows = 4,
2092 .sz_cols = 3,
2093 .data = data
2094 };
2095
2096 /* Init matrix h. */
2097 rc = zsl_mtx_init(&h, NULL);
2098 zassert_equal(rc, 0, NULL);
2099
2100 /* Compute the Householder matrix. */
2101 rc = zsl_mtx_householder(&m, &h, false);
2102 zassert_equal(rc, 0, NULL);
2103
2104 /* Expected output. */
2105 zsl_real_t dtst[16] = { 0.5, 0.5, 0.5, 0.5,
2106 0.5, 0.5, -0.5, -0.5,
2107 0.5, -0.5, 0.5, -0.5,
2108 0.5, -0.5, -0.5, 0.5 };
2109
2110 struct zsl_mtx mt = {
2111 .sz_rows = 4,
2112 .sz_cols = 4,
2113 .data = dtst
2114 };
2115
2116 /* Check the output. */
2117 zassert_true(zsl_mtx_is_equal(&h, &mt), NULL);
2118
2119 /* Compute the Hessenberg-Householder matrix. */
2120 rc = zsl_mtx_householder(&m, &h, true);
2121 zassert_equal(rc, 0, NULL);
2122
2123 /* Expected output. */
2124 zsl_real_t dtsa[16] = { 1.0, 0.000000, 0.000000, 0.000000,
2125 0.0, 0.577350, 0.577350, 0.577350,
2126 0.0, 0.577350, 0.211325, -0.788675,
2127 0.0, 0.577350, -0.788675, 0.211325 };
2128
2129 struct zsl_mtx mt2 = {
2130 .sz_rows = 4,
2131 .sz_cols = 4,
2132 .data = dtsa
2133 };
2134
2135 /* Check the output. */
2136 for (size_t g = 0; g < (h.sz_rows * h.sz_cols); g++) {
2137 zassert_true(val_is_equal(h.data[g], mt2.data[g], 1E-6), NULL);
2138 }
2139 }
2140
ZTEST(zsl_tests,test_matrix_qrd)2141 ZTEST(zsl_tests, test_matrix_qrd)
2142 {
2143 int rc;
2144
2145 ZSL_MATRIX_DEF(q, 3, 3);
2146 ZSL_MATRIX_DEF(r, 3, 3);
2147
2148 /* Input matrix. */
2149 zsl_real_t data[9] = { 0.0, 0.0, 4.0,
2150 2.0, 4.0, -2.0,
2151 0.0, 4.0, 2.0 };
2152
2153 struct zsl_mtx m = {
2154 .sz_rows = 3,
2155 .sz_cols = 3,
2156 .data = data
2157 };
2158
2159 /* The expected results for Q and R matrices for test purposes. */
2160 zsl_real_t qdata[9] = { 0.0, 0.0, 1.0,
2161 1.0, 0.0, 0.0,
2162 0.0, 1.0, 0.0 };
2163
2164 struct zsl_mtx q2 = {
2165 .sz_rows = 3,
2166 .sz_cols = 3,
2167 .data = qdata
2168 };
2169
2170 zsl_real_t rdata[9] = { 2.0, 4.0, -2.0,
2171 0.0, 4.0, 2.0,
2172 0.0, 0.0, 4.0 };
2173
2174 struct zsl_mtx r2 = {
2175 .sz_rows = 3,
2176 .sz_cols = 3,
2177 .data = rdata
2178 };
2179
2180
2181 /* Init matrices Q and R. */
2182 rc = zsl_mtx_init(&q, NULL);
2183 zassert_equal(rc, 0, NULL);
2184 rc = zsl_mtx_init(&r, NULL);
2185 zassert_equal(rc, 0, NULL);
2186
2187 /* Calculate the QR decomposition. */
2188 rc = zsl_mtx_qrd(&m, &q, &r, false);
2189 zassert_equal(rc, 0, NULL);
2190
2191 /* Check the output. */
2192 for (size_t g = 0; g < (m.sz_rows * m.sz_cols); g++) {
2193 zassert_true(val_is_equal(q.data[g], q2.data[g], 1E-6), NULL);
2194 zassert_true(val_is_equal(r.data[g], r2.data[g], 1E-6), NULL);
2195 }
2196 }
2197
ZTEST(zsl_tests,test_matrix_qrd_hess)2198 ZTEST(zsl_tests, test_matrix_qrd_hess)
2199 {
2200 int rc;
2201
2202 ZSL_MATRIX_DEF(q, 4, 4);
2203 ZSL_MATRIX_DEF(r, 4, 4);
2204
2205 /* Input matrix. */
2206 zsl_real_t data[16] = { 1.0, 0.0, 4.0, -3.0,
2207 2.0, 4.0, -2.0, 7.0,
2208 -3.0, 4.0, 2.0, 0.0,
2209 5.0, -4.0, 0.0, 6.0 };
2210
2211 struct zsl_mtx m = {
2212 .sz_rows = 4,
2213 .sz_cols = 4,
2214 .data = data
2215 };
2216
2217 /* Init matrices Q and R. */
2218 rc = zsl_mtx_init(&q, NULL);
2219 zassert_equal(rc, 0, NULL);
2220 rc = zsl_mtx_init(&r, NULL);
2221 zassert_equal(rc, 0, NULL);
2222
2223 /* Perform the Hessenberg transformation on the input matrix. */
2224 rc = zsl_mtx_qrd(&m, &q, &r, true);
2225 zassert_equal(rc, 0, NULL);
2226
2227 /* Expected output. */
2228 zsl_real_t hdata[16] = {
2229 1.0000000000, -4.3799783705, -2.0074108339, -1.3364472371,
2230 6.1644140030, 5.3157894737, 4.9566180780, -3.9888797432,
2231 0.0000000000, -6.9114902923, 4.1365576515, 0.8655838518,
2232 -0.0000000000, 0.0000000000, 0.3789195885, 2.5476528748
2233 };
2234
2235 struct zsl_mtx hess = {
2236 .sz_rows = 4,
2237 .sz_cols = 4,
2238 .data = hdata
2239 };
2240
2241
2242 /* Check the output. */
2243 for (size_t g = 0; g < (m.sz_rows * m.sz_cols); g++) {
2244 #ifdef CONFIG_ZSL_SINGLE_PRECISION
2245 zassert_true(val_is_equal(r.data[g], hess.data[g], 1E-4), NULL);
2246 #else
2247 zassert_true(val_is_equal(r.data[g], hess.data[g], 1E-8), NULL);
2248 #endif
2249 }
2250 }
2251
2252 #ifndef CONFIG_ZSL_SINGLE_PRECISION
ZTEST(zsl_tests_double,test_matrix_qrd_iter)2253 ZTEST(zsl_tests_double, test_matrix_qrd_iter)
2254 {
2255 int rc;
2256
2257 ZSL_MATRIX_DEF(m2, 4, 4);
2258 ZSL_VECTOR_DEF(v, 4);
2259 ZSL_VECTOR_DEF(v2, 4);
2260
2261 /* Input matrix. */
2262 zsl_real_t data[16] = { 1.0, 2.0, -1.0, 0.0,
2263 0.0, 3.0, 4.0, -2.0,
2264 4.0, 4.0, -3.0, 0.0,
2265 5.0, 3.0, -5.0, 2.0 };
2266
2267 struct zsl_mtx m = {
2268 .sz_rows = 4,
2269 .sz_cols = 4,
2270 .data = data
2271 };
2272
2273 /* Init the output matrix. */
2274 rc = zsl_mtx_init(&m2, NULL);
2275 zassert_equal(rc, 0, NULL);
2276
2277 /* Perform the QR method 1500 times matrix. */
2278 rc = zsl_mtx_qrd_iter(&m, &m2, 1500);
2279 zassert_equal(rc, 0, NULL);
2280
2281 /* Check if the output matrix is upper triangular and if it is similar
2282 * to the input matrix. */
2283 zassert_true(val_is_equal(m2.data[4], 0.0, 1E-6), NULL);
2284 zassert_true(val_is_equal(m2.data[8], 0.0, 1E-6), NULL);
2285 zassert_true(val_is_equal(m2.data[9], 0.0, 1E-6), NULL);
2286 zassert_true(val_is_equal(m2.data[12], 0.0, 1E-6), NULL);
2287 zassert_true(val_is_equal(m2.data[13], 0.0, 1E-6), NULL);
2288 zassert_true(val_is_equal(m2.data[14], 0.0, 1E-6), NULL);
2289
2290 zsl_mtx_eigenvalues(&m, &v, 500);
2291 zsl_mtx_eigenvalues(&m2, &v2, 500);
2292
2293 zassert_true(zsl_vec_is_equal(&v, &v2, 1E-6), NULL);
2294 }
2295 #endif
2296
2297 #ifndef CONFIG_ZSL_SINGLE_PRECISION
ZTEST(zsl_tests_double,test_matrix_eigenvalues)2298 ZTEST(zsl_tests_double, test_matrix_eigenvalues)
2299 {
2300 int rc;
2301
2302 ZSL_VECTOR_DEF(va, 4);
2303 ZSL_VECTOR_DEF(vb, 4);
2304 ZSL_VECTOR_DEF(vc, 4);
2305
2306 ZSL_VECTOR_DEF(va2, 4);
2307 ZSL_VECTOR_DEF(vb2, 2);
2308 ZSL_VECTOR_DEF(vc2, 4);
2309
2310 /* Input real-eigenvalue matrix. */
2311 zsl_real_t data[16] = { 1.0, 2.0, -1.0, 0.0,
2312 0.0, 3.0, 4.0, -2.0,
2313 4.0, 4.0, -3.0, 0.0,
2314 5.0, 3.0, -5.0, 2.0 };
2315
2316 struct zsl_mtx ma = {
2317 .sz_rows = 4,
2318 .sz_cols = 4,
2319 .data = data
2320 };
2321
2322 /* Input complex-eigenvalue matrix. */
2323 zsl_real_t datb[16] = { 1.0, 2.0, -1.0, 0.0,
2324 0.0, 3.0, 4.0, -2.0,
2325 4.0, 4.0, -3.0, 0.0,
2326 9.0, 3.0, -5.0, 2.0 };
2327
2328 struct zsl_mtx mb = {
2329 .sz_rows = 4,
2330 .sz_cols = 4,
2331 .data = datb
2332 };
2333
2334 /* Input symmetric matrix. */
2335 zsl_real_t datc[16] = { 1.0, 2.0, 4.0, 0.0,
2336 2.0, 3.0, 4.0, -2.0,
2337 4.0, 4.0, -3.0, 5.0,
2338 0.0, -2.0, 5.0, -1.0 };
2339
2340 struct zsl_mtx mc = {
2341 .sz_rows = 4,
2342 .sz_cols = 4,
2343 .data = datc
2344 };
2345
2346 /* Expected output. */
2347 va2.data[0] = 4.8347780554139375;
2348 va2.data[1] = -2.6841592178899276;
2349 va2.data[2] = 1.8493811427083884;
2350 va2.data[3] = -0.9999999802303374;
2351
2352 vb2.data[0] = -3.0925670160610634;
2353 vb2.data[1] = -1.0000000075030784;
2354
2355 vc2.data[0] = -9.2890349032381003;
2356 vc2.data[1] = 7.4199113544017665;
2357 vc2.data[2] = 2.7935849909013921;
2358 vc2.data[3] = -0.9244614420638188;
2359
2360
2361 /* Init the output vectors. */
2362 rc = zsl_vec_init(&va);
2363 zassert_equal(rc, 0, NULL);
2364 rc = zsl_vec_init(&vb);
2365 zassert_equal(rc, 0, NULL);
2366 rc = zsl_vec_init(&vc);
2367 zassert_equal(rc, 0, NULL);
2368
2369 /* Calculate the eigenvalues of 'ma', 'mb' and 'mc'. */
2370 rc = zsl_mtx_eigenvalues(&ma, &va, 150);
2371 zassert_equal(rc, 0, NULL);
2372
2373 rc = zsl_mtx_eigenvalues(&mb, &vb, 150);
2374 zassert_equal(rc, -ECOMPLEXVAL, NULL);
2375
2376 rc = zsl_mtx_eigenvalues(&mc, &vc, 150);
2377 zassert_equal(rc, 0, NULL);
2378
2379 /* Check the output. */
2380 zassert_true(zsl_vec_is_equal(&va, &va2, 1E-6), NULL);
2381 zassert_true(zsl_vec_is_equal(&vb, &vb2, 1E-6), NULL);
2382 zassert_true(zsl_vec_is_equal(&vc, &vc2, 1E-6), NULL);
2383 }
2384 #endif
2385
2386 #ifndef CONFIG_ZSL_SINGLE_PRECISION
ZTEST(zsl_tests_double,test_matrix_eigenvectors)2387 ZTEST(zsl_tests_double, test_matrix_eigenvectors)
2388 {
2389 int rc;
2390
2391 ZSL_MATRIX_DEF(va, 4, 4);
2392 ZSL_MATRIX_DEF(vb, 4, 4);
2393 ZSL_MATRIX_DEF(vc, 4, 4);
2394 ZSL_MATRIX_DEF(vd, 3, 3);
2395
2396 ZSL_MATRIX_DEF(va2, 4, 4);
2397 ZSL_MATRIX_DEF(vb2, 4, 2);
2398 ZSL_MATRIX_DEF(vc2, 4, 2);
2399 ZSL_MATRIX_DEF(vd2, 3, 3);
2400
2401 /* Input real-eigenvalue matrix. */
2402 zsl_real_t data[16] = { 1.0, 2.0, -1.0, 0.0,
2403 0.0, 3.0, 4.0, -2.0,
2404 4.0, 4.0, -3.0, 0.0,
2405 5.0, 3.0, -5.0, 2.0 };
2406
2407 struct zsl_mtx ma = {
2408 .sz_rows = 4,
2409 .sz_cols = 4,
2410 .data = data
2411 };
2412
2413 /* Input complex-eigenvalue matrix. */
2414 zsl_real_t datb[16] = { 1.0, 2.0, -1.0, 0.0,
2415 0.0, 3.0, 4.0, -2.0,
2416 4.0, 4.0, -3.0, 0.0,
2417 9.0, 3.0, -5.0, 2.0 };
2418
2419 struct zsl_mtx mb = {
2420 .sz_rows = 4,
2421 .sz_cols = 4,
2422 .data = datb
2423 };
2424
2425 /* Input real-eigenvalue non-diagonalisable matrix with repeated
2426 * eigenvalues. */
2427 zsl_real_t datc[16] = { 1.0, 2.0, 4.0, 0.0,
2428 0.0, 3.0, 4.0, -2.0,
2429 0.0, 0.0, 3.0, 5.0,
2430 0.0, 0.0, 0.0, 1.0 };
2431
2432 struct zsl_mtx mc = {
2433 .sz_rows = 4,
2434 .sz_cols = 4,
2435 .data = datc
2436 };
2437
2438 /* Input real-eigenvalue diagonalisable matrix with repeated
2439 * eigenvalues. */
2440 zsl_real_t datd[9] = { 5.0, -4.0, 4.0,
2441 12.0, -11.0, 12.0,
2442 4.0, -4.0, 5.0 };
2443
2444 struct zsl_mtx md = {
2445 .sz_rows = 3,
2446 .sz_cols = 3,
2447 .data = datd
2448 };
2449
2450 /* Init the output matrices. */
2451 rc = zsl_mtx_init(&va, NULL);
2452 zassert_equal(rc, 0, NULL);
2453 rc = zsl_mtx_init(&vb, NULL);
2454 zassert_equal(rc, 0, NULL);
2455 rc = zsl_mtx_init(&vc, NULL);
2456 zassert_equal(rc, 0, NULL);
2457 rc = zsl_mtx_init(&vd, NULL);
2458 zassert_equal(rc, 0, NULL);
2459
2460 /* Calculate the eigenvectors of 'ma', 'mb' and 'mc'
2461 * non-orthonormalised. */
2462 rc = zsl_mtx_eigenvectors(&ma, &va, 1500, false);
2463 zassert_equal(rc, 0, NULL);
2464 rc = zsl_mtx_eigenvectors(&mb, &vb, 1500, false);
2465 zassert_equal(rc, -EEIGENSIZE, NULL);
2466 rc = zsl_mtx_eigenvectors(&mc, &vc, 1500, false);
2467 zassert_equal(rc, -EEIGENSIZE, NULL);
2468 rc = zsl_mtx_eigenvectors(&md, &vd, 1500, false);
2469 zassert_equal(rc, 0, NULL);
2470
2471 /* Expected output. */
2472 zsl_real_t a[16] = {
2473 0.7555042357, 0.6223771803, 0.2074844660, 5.5000009316,
2474 2.2040997676, -0.5240911326, 0.2956011625, -3.5000005906,
2475 1.5110084714, 1.2447543606, 0.4149689321, 4.0000005733,
2476 1.0000000000, 1.0000000000, 1.0000000000, 1.0000000000
2477 };
2478
2479 zsl_real_t b[8] = { 1.2304303063, -0.5000000054,
2480 -1.2873789372, 0.5000000045,
2481 2.4608606125, -0.0000000055,
2482 1.0000000000, 1.0000000000 };
2483
2484 zsl_real_t c[8] = { 1.0, 1.0,
2485 0.0, 1.0,
2486 0.0, 0.0,
2487 0.0, 0.0 };
2488
2489 zsl_real_t d[9] = { 1.0, 1.0, -1.0,
2490 3.0, 1.0, 0.0,
2491 1.0, 0.0, 1.0 };
2492
2493 rc = zsl_mtx_from_arr(&va2, a);
2494 zassert_equal(rc, 0, NULL);
2495 rc = zsl_mtx_from_arr(&vb2, b);
2496 zassert_equal(rc, 0, NULL);
2497 rc = zsl_mtx_from_arr(&vc2, c);
2498 zassert_equal(rc, 0, NULL);
2499 rc = zsl_mtx_from_arr(&vd2, d);
2500 zassert_equal(rc, 0, NULL);
2501
2502 /* Check the output. */
2503 for (size_t g = 0; g < (va.sz_rows * va.sz_cols); g++) {
2504 zassert_true(val_is_equal(va.data[g], va2.data[g], 1E-6), NULL);
2505 }
2506
2507 for (size_t g = 0; g < (vb.sz_rows * vb.sz_cols); g++) {
2508 zassert_true(val_is_equal(vb.data[g], vb2.data[g], 1E-6), NULL);
2509 zassert_true(val_is_equal(vc.data[g], vc2.data[g], 1E-6), NULL);
2510 }
2511
2512 for (size_t g = 0; g < (vd.sz_rows * vd.sz_cols); g++) {
2513 zassert_true(val_is_equal(vd.data[g], vd2.data[g], 1E-6), NULL);
2514 }
2515
2516 /* Calculate the eigenvectors of 'ma', 'mb' and 'mc' orthonormalised. */
2517 rc = zsl_mtx_eigenvectors(&ma, &va, 1500, true);
2518 zassert_equal(rc, 0, NULL);
2519 rc = zsl_mtx_eigenvectors(&mb, &vb, 1500, true);
2520 zassert_equal(rc, -EEIGENSIZE, NULL);
2521 rc = zsl_mtx_eigenvectors(&mc, &vc, 1500, true);
2522 zassert_equal(rc, -EEIGENSIZE, NULL);
2523 rc = zsl_mtx_eigenvectors(&md, &vd, 1500, true);
2524 zassert_equal(rc, 0, NULL);
2525
2526 /* Expected output. */
2527 zsl_real_t a2[16] = {
2528 0.2559636199, 0.3472992698, 0.1817921832, 0.7130241030,
2529 0.7467454562, -0.2924536333, 0.2589976094, -0.4537426107,
2530 0.5119272398, 0.6945985397, 0.3635843664, 0.5185629705,
2531 0.3387983916, 0.5580205715, 0.8761724995, 0.1296407240
2532 };
2533
2534
2535 zsl_real_t b2[8] = { 0.3847511767, -0.4082482935,
2536 -0.4025588109, 0.4082482928,
2537 0.7695023535, -0.0000000045,
2538 0.3126964402, 0.8164965782 };
2539
2540 zsl_real_t c2[8] = { 1.0, 0.7071067812,
2541 0.0, 0.7071067812,
2542 0.0, 0.0,
2543 0.0, 0.0 };
2544
2545 zsl_real_t d2[9] = { 0.3015113441, 0.7071067750, -0.4082482533,
2546 0.9045340323, 0.7071067874, 0.4082481887,
2547 0.3015113494, 0.0000000498, 0.8164966504 };
2548
2549 rc = zsl_mtx_from_arr(&va2, a2);
2550 zassert_equal(rc, 0, NULL);
2551 rc = zsl_mtx_from_arr(&vb2, b2);
2552 zassert_equal(rc, 0, NULL);
2553 rc = zsl_mtx_from_arr(&vc2, c2);
2554 zassert_equal(rc, 0, NULL);
2555 rc = zsl_mtx_from_arr(&vd2, d2);
2556 zassert_equal(rc, 0, NULL);
2557
2558 /* Check the output. */
2559 for (size_t g = 0; g < (va.sz_rows * va.sz_cols); g++) {
2560 zassert_true(val_is_equal(va.data[g], va2.data[g], 1E-6), NULL);
2561 }
2562
2563 for (size_t g = 0; g < (vb.sz_rows * vb.sz_cols); g++) {
2564 zassert_true(val_is_equal(vb.data[g], vb2.data[g], 1E-6), NULL);
2565 zassert_true(val_is_equal(vc.data[g], vc2.data[g], 1E-6), NULL);
2566 }
2567
2568 for (size_t g = 0; g < (vd.sz_rows * vd.sz_cols); g++) {
2569 zassert_true(val_is_equal(vd.data[g], vd2.data[g], 1E-6), NULL);
2570 }
2571 }
2572 #endif
2573
2574 #ifndef CONFIG_ZSL_SINGLE_PRECISION
ZTEST(zsl_tests_double,test_matrix_svd)2575 ZTEST(zsl_tests_double, test_matrix_svd)
2576 {
2577 int rc;
2578
2579 ZSL_MATRIX_DEF(u, 3, 3);
2580 ZSL_MATRIX_DEF(e, 3, 4);
2581 ZSL_MATRIX_DEF(v, 4, 4);
2582
2583 ZSL_MATRIX_DEF(u2, 3, 3);
2584 ZSL_MATRIX_DEF(e2, 3, 4);
2585 ZSL_MATRIX_DEF(v2, 4, 4);
2586
2587 /* Input matrix. */
2588 zsl_real_t data[12] = { 1.0, 2.0, -1.0, 0.0,
2589 0.0, 3.0, 4.0, -2.0,
2590 4.0, 4.0, -3.0, 0.0 };
2591
2592 struct zsl_mtx m = {
2593 .sz_rows = 3,
2594 .sz_cols = 4,
2595 .data = data
2596 };
2597
2598 /* Init the output matrices. */
2599 rc = zsl_mtx_init(&u, NULL);
2600 zassert_equal(rc, 0, NULL);
2601 rc = zsl_mtx_init(&e, NULL);
2602 zassert_equal(rc, 0, NULL);
2603 rc = zsl_mtx_init(&v, NULL);
2604 zassert_equal(rc, 0, NULL);
2605
2606 /* Calculate the svd of 'm'. */
2607 rc = zsl_mtx_svd(&m, &u, &e, &v, 1500);
2608 zassert_equal(rc, 0, NULL);
2609
2610 /* Expected output. */
2611 zsl_real_t a[9] = { -0.3481845133, -0.0474852763, 0.9362225661,
2612 -0.0396196056, -0.9970784021, -0.0653065614,
2613 -0.9365884003, 0.0598315021, -0.3452859102 };
2614
2615 zsl_real_t b[12] = { 6.8246886030, 0.0, 0.0, 0.0,
2616 0.0, 5.3940011894, 0.0, 0.0,
2617 0.0, 0.0, 0.5730415692, 0.0 };
2618
2619 zsl_real_t c[16] = { -0.5999596982, 0.0355655710, -0.7764202435,
2620 0.1896181853, -0.6683940777, -0.5277862667, 0.5154631408, 0.0948090926,
2621 0.4395030259, -0.7638713255, -0.2819884104, 0.3792363705, 0.0116106706,
2622 0.3696989923, 0.2279295777, 0.9006863800 };
2623
2624 rc = zsl_mtx_from_arr(&u2, a);
2625 zassert_equal(rc, 0, NULL);
2626 rc = zsl_mtx_from_arr(&e2, b);
2627 zassert_equal(rc, 0, NULL);
2628 rc = zsl_mtx_from_arr(&v2, c);
2629 zassert_equal(rc, 0, NULL);
2630
2631 /* Check the output. */
2632 for (size_t g = 0; g < (u.sz_rows * u.sz_cols); g++) {
2633 zassert_true(val_is_equal(u.data[g], u2.data[g], 1E-8), NULL);
2634 }
2635
2636 for (size_t g = 0; g < (e.sz_rows * e.sz_cols); g++) {
2637 zassert_true(val_is_equal(e.data[g], e2.data[g], 1E-8), NULL);
2638 }
2639
2640 for (size_t g = 0; g < (v.sz_rows * v.sz_cols); g++) {
2641 zassert_true(val_is_equal(v.data[g], v2.data[g], 1E-8), NULL);
2642 }
2643 }
2644 #endif
2645
2646 #ifndef CONFIG_ZSL_SINGLE_PRECISION
ZTEST(zsl_tests_double,test_matrix_pinv)2647 ZTEST(zsl_tests_double, test_matrix_pinv)
2648 {
2649 int rc;
2650
2651 ZSL_MATRIX_DEF(pinv, 4, 3);
2652
2653 ZSL_MATRIX_DEF(pinv2, 4, 3);
2654
2655 /* Input matrix. */
2656 zsl_real_t data[12] = { 1.0, 2.0, -1.0, 0.0,
2657 0.0, 3.0, 4.0, -2.0,
2658 4.0, 4.0, -3.0, 0.0 };
2659
2660 struct zsl_mtx m = {
2661 .sz_rows = 3,
2662 .sz_cols = 4,
2663 .data = data
2664 };
2665
2666 /* Init the output matrix. */
2667 rc = zsl_mtx_init(&pinv, NULL);
2668 zassert_equal(rc, 0, NULL);
2669
2670 /* Calculate the pseudo-inverse of 'm'. */
2671 rc = zsl_mtx_pinv(&m, &pinv, 1500);
2672 zassert_equal(rc, 0, NULL);
2673
2674 /* Expected output. */
2675 zsl_real_t a[12] = {
2676 -1.2382022472, 0.0853932584, 0.5505617978,
2677 0.8808988764, 0.0426966292, -0.2247191011,
2678 -0.4764044944, 0.1707865169, 0.1011235955,
2679 0.3685393258, -0.0943820225, -0.1348314607
2680 };
2681
2682 rc = zsl_mtx_from_arr(&pinv2, a);
2683 zassert_equal(rc, 0, NULL);
2684
2685 /* Check the output. */
2686 for (size_t g = 0; g < (pinv.sz_rows * pinv.sz_cols); g++) {
2687 zassert_true(val_is_equal(pinv.data[g], pinv2.data[g], 1E-8),
2688 NULL);
2689 }
2690 }
2691 #endif
2692
ZTEST(zsl_tests,test_matrix_min)2693 ZTEST(zsl_tests, test_matrix_min)
2694 {
2695 int rc = 0;
2696 zsl_real_t min;
2697
2698 /* Input matrix. */
2699 zsl_real_t data[8] = { 2.0, 3.0,
2700 1.0, 4.0,
2701 4.0, 3.0,
2702 3.0, 4.0 };
2703 struct zsl_mtx m = {
2704 .sz_rows = 4,
2705 .sz_cols = 2,
2706 .data = data
2707 };
2708
2709 rc = zsl_mtx_min(&m, &min);
2710 zassert_equal(rc, 0, NULL);
2711 zassert_equal(min, 1.0, NULL);
2712 }
2713
ZTEST(zsl_tests,test_matrix_max)2714 ZTEST(zsl_tests, test_matrix_max)
2715 {
2716 int rc = 0;
2717 zsl_real_t max;
2718
2719 /* Input matrix. */
2720 zsl_real_t data[8] = { 2.0, 3.0,
2721 1.0, 4.0,
2722 4.0, 3.0,
2723 3.0, 4.0 };
2724 struct zsl_mtx m = {
2725 .sz_rows = 4,
2726 .sz_cols = 2,
2727 .data = data
2728 };
2729
2730 rc = zsl_mtx_max(&m, &max);
2731 zassert_equal(rc, 0, NULL);
2732 zassert_equal(max, 4.0, NULL);
2733 }
2734
ZTEST(zsl_tests,test_matrix_min_idx)2735 ZTEST(zsl_tests, test_matrix_min_idx)
2736 {
2737 int rc = 0;
2738 size_t min_i;
2739 size_t min_j;
2740
2741 /* Input matrix. */
2742 zsl_real_t data[8] = { 2.0, 3.0,
2743 1.0, 4.0,
2744 4.0, 3.0,
2745 3.0, 4.0 };
2746 struct zsl_mtx m = {
2747 .sz_rows = 4,
2748 .sz_cols = 2,
2749 .data = data
2750 };
2751
2752 rc = zsl_mtx_min_idx(&m, &min_i, &min_j);
2753 zassert_equal(rc, 0, NULL);
2754 zassert_equal(min_i, 1, NULL);
2755 zassert_equal(min_j, 0, NULL);
2756 }
2757
ZTEST(zsl_tests,test_matrix_max_idx)2758 ZTEST(zsl_tests, test_matrix_max_idx)
2759 {
2760 int rc = 0;
2761 size_t max_i;
2762 size_t max_j;
2763
2764
2765 /* Input matrix. */
2766 zsl_real_t data[8] = { 2.0, 3.0,
2767 1.0, 4.0,
2768 4.0, 3.0,
2769 3.0, 4.0 };
2770 struct zsl_mtx m = {
2771 .sz_rows = 4,
2772 .sz_cols = 2,
2773 .data = data
2774 };
2775
2776 rc = zsl_mtx_max_idx(&m, &max_i, &max_j);
2777 zassert_equal(rc, 0, NULL);
2778 zassert_equal(max_i, 1, NULL);
2779 zassert_equal(max_j, 1, NULL);
2780 }
2781
ZTEST(zsl_tests,test_matrix_is_equal)2782 ZTEST(zsl_tests, test_matrix_is_equal)
2783 {
2784 bool res;
2785
2786 zsl_real_t data_a[8] = { 2.0, 3.0,
2787 1.0, 4.0,
2788 4.0, 3.0,
2789 3.0, 4.0 };
2790 struct zsl_mtx ma = {
2791 .sz_rows = 4,
2792 .sz_cols = 2,
2793 .data = data_a
2794 };
2795
2796 zsl_real_t data_b[8] = { 2.0, 3.0,
2797 1.0, 4.0,
2798 4.0, 3.0,
2799 3.0, 4.0 };
2800 struct zsl_mtx mb = {
2801 .sz_rows = 4,
2802 .sz_cols = 2,
2803 .data = data_b
2804 };
2805
2806 /* Perform a test of equal elements. */
2807 res = zsl_mtx_is_equal(&ma, &mb);
2808 zassert_equal(res, true, NULL);
2809
2810 /* Perform a test of unequal elements. */
2811 zsl_mtx_set(&mb, 1, 1, 0.5);
2812 res = zsl_mtx_is_equal(&ma, &mb);
2813 zassert_equal(res, false, "");
2814 }
2815
ZTEST(zsl_tests,test_matrix_is_notneg)2816 ZTEST(zsl_tests, test_matrix_is_notneg)
2817 {
2818 bool res;
2819
2820 /* Input matrix. */
2821 zsl_real_t data[8] = { 2.0, 3.0,
2822 1.0, 4.0,
2823 4.0, 3.0,
2824 3.0, 4.0 };
2825 struct zsl_mtx m = {
2826 .sz_rows = 4,
2827 .sz_cols = 2,
2828 .data = data
2829 };
2830
2831 res = zsl_mtx_is_notneg(&m);
2832 zassert_equal(res, true, NULL);
2833
2834 zsl_mtx_set(&m, 1, 1, -0.01);
2835 res = zsl_mtx_is_notneg(&m);
2836 zassert_equal(res, false, NULL);
2837 }
2838
ZTEST(zsl_tests,test_matrix_is_sym)2839 ZTEST(zsl_tests, test_matrix_is_sym)
2840 {
2841 bool res;
2842
2843 /* Input matrixes. */
2844 zsl_real_t a[9] = { 2.0, 3.0, 6.0,
2845 3.0, 4.0, -1.0,
2846 6.0, -1.0, 0.0 };
2847 struct zsl_mtx ma = {
2848 .sz_rows = 3,
2849 .sz_cols = 3,
2850 .data = a
2851 };
2852
2853 zsl_real_t b[9] = { 5.0, 3.0, 4.0,
2854 7.0, -5.0, 0.0,
2855 3.0, -2.0, 3.0 };
2856 struct zsl_mtx mb = {
2857 .sz_rows = 3,
2858 .sz_cols = 3,
2859 .data = b
2860 };
2861
2862 /* Perform a test with a symmetric matrix. */
2863 res = zsl_mtx_is_sym(&ma);
2864 zassert_equal(res, true, NULL);
2865
2866 /* Perform a test with a non-symmetric matrix. */
2867 res = zsl_mtx_is_sym(&mb);
2868 zassert_equal(res, false, NULL);
2869 }
2870