Ansel 0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
polar_decomposition.h
Go to the documentation of this file.
1
2/*
3 This file is part of the Ansel project.
4 Copyright (C) 2023 Davide Patria.
5
6 Ansel is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
10
11 Ansel is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
15
16 You should have received a copy of the GNU General Public License
17 along with Ansel. If not, see <http://www.gnu.org/licenses/>.
18*/
19
74// define the type for the variables that were previously TYPE as more precision was not though to be necessary
75// an if so the type can be choosen with a gcc flag but would fallback to this if not defined
76#ifndef TYPE
77#define TYPE double
78#endif
79
80// define which ABS to use based on the chosen type
81#if TYPE == double
82#define ABS(n) fabs(n)
83#define SQRT(n) sqrt(n)
84#elif TYPE == TYPE
85#define ABS(n) fabs(n)
86#define SQRT(n) sqrtf(n)
87#endif
88
89#include <complex.h>
90#include <math.h>
91#include <stdbool.h>
92#include <stdio.h>
93#include <stdlib.h>
94// is it necessary?
95// #include "QR_decomp.h"
96
97// Note : if you review this code using the original Matlab implementation,
98// remember Matlab indexes arrays from 1, while C starts at 0, so every index
99// needs to be shifted by -1.
100
110void swap_rows(TYPE *m, size_t rows, size_t cols, size_t row0, size_t row1);
111
121void swap_cols(TYPE *m, size_t rows, size_t cols, size_t col0, size_t col1);
122
129void abs_matrix(TYPE *matrix_abs, size_t num_el);
130
145void matrix_multiply(const TYPE *A, const TYPE *B, TYPE *RES, int rows_A, int cols_A, int cols_B);
146
154TYPE max_val_matrix(TYPE *matrice, size_t size);
155
162static inline void normalize_array(TYPE *vector, int size);
163
171void stampa_matrice(TYPE *m, size_t rows, size_t cols);
172
185void compute_null_space(TYPE *nullspace, const TYPE a, const TYPE b, const TYPE c);
186
194void copy(TYPE *dest, TYPE *source, size_t num_el);
195
206void orthonormalize_v_with_qr(TYPE *v0, TYPE *v1, const TYPE v00, const TYPE v10, const TYPE v01, const TYPE v11);
207
219void multiply_il_v(TYPE *RES, const TYPE IL01, const TYPE IL02, const TYPE IL03, const TYPE IL12, const TYPE IL13,
220 const TYPE *v);
221
231void multiply_id_v(TYPE *RES, const TYPE ID00, const TYPE ID11, const TYPE *ID, const TYPE *v);
232
244void multiply_v_il(TYPE *RES, const TYPE *v, const TYPE IL01, const TYPE IL02, const TYPE IL03, const TYPE IL12,
245 const TYPE IL13);
246
254
262void multiply_minus_v_d(TYPE *RES, TYPE *v, TYPE *D);
263
272TYPE vector_scalar(const TYPE *a, const TYPE *b, const size_t num_el);
273
288void polar_decomposition(TYPE A[3][3], TYPE Q[3][3], TYPE H[3][3])
289{
290 // Frobenius / L2 norm of the matrice - aka we sum the squares of each
291 // matrice element and take the sqrt
292 const TYPE norm
293 = SQRT(A[0][0] * A[0][0] + A[0][1] * A[0][1] + A[0][2] * A[0][2] + A[1][0] * A[1][0] + A[1][1] * A[1][1]
294 + A[1][2] * A[1][2] + A[2][0] * A[2][0] + A[2][1] * A[2][1] + A[2][2] * A[2][2]);
295
296 // Normalize the matrice A in-place, so A norm is 1
297 for(size_t i = 0; i < 3; i++)
298 for(size_t j = 0; j < 3; j++) A[i][j] /= norm;
299
300 // Compute the conditionning of the matrice
301 TYPE m = A[1][1] * A[2][2] - A[1][2] * A[2][1];
302 TYPE b = m * m;
303
304 m = A[1][0] * A[2][2] - A[1][2] * A[2][0];
305 b += m * m;
306 m = A[1][0] * A[2][1] - A[1][1] * A[2][0];
307 b += m * m;
308
309 m = A[0][0] * A[2][1] - A[0][1] * A[2][0];
310 b += m * m;
311 m = A[0][0] * A[2][2] - A[0][2] * A[2][0];
312 b += m * m;
313 m = A[0][1] * A[2][2] - A[0][2] * A[2][1];
314 b += m * m;
315
316 m = A[0][1] * A[1][2] - A[0][2] * A[1][1];
317 b += m * m;
318 m = A[0][0] * A[1][2] - A[0][2] * A[1][0];
319 b += m * m;
320 m = A[0][0] * A[1][1] - A[0][1] * A[1][0];
321 b += m * m;
322
323 b = -4.0 * b + 1.0;
324
325 bool subspa = false;
326 int quick = 1;
327 TYPE d = 0.0;
328 TYPE dd = 1.0;
329 TYPE nit = 0.0;
330 TYPE U[3] = { 0.0, 0.0, 0.0 };
331 TYPE AA[3][3];
332
333 // copy of A
334 copy(*AA, *A, 9);
335
336 if((b - 1.0 + 1.0e-4) > 0.0)
337 {
338 quick = 0;
339
340 // LU (full).
341 size_t r = 0;
342 size_t c = 0;
343
344 // Search index (r, c) of the max element in matrice
345 if(ABS(A[1][0]) > ABS(A[0][0])) r = 1;
346 if(ABS(A[2][0]) > ABS(A[r][c])) r = 2;
347 if(ABS(A[0][1]) > ABS(A[r][c]))
348 {
349 r = 0;
350 c = 1;
351 }
352 if(ABS(A[1][1]) > ABS(A[r][c]))
353 {
354 r = 1;
355 c = 1;
356 }
357 if(ABS(A[2][1]) > ABS(A[r][c]))
358 {
359 r = 2;
360 c = 1;
361 }
362 if(ABS(A[0][2]) > ABS(A[r][c]))
363 {
364 r = 0;
365 c = 2;
366 }
367 if(ABS(A[1][2]) > ABS(A[r][c]))
368 {
369 r = 1;
370 c = 2;
371 }
372 if(ABS(A[2][2]) > ABS(A[r][c]))
373 {
374 r = 2;
375 c = 2;
376 }
377
378 if(r > 0)
379 {
380 // invert lines 0 and r
381 swap_rows(*AA, 3, 3, 0, r);
382 dd = -1.0;
383 }
384
385 if(c > 0)
386 {
387 swap_cols(*AA, 3, 3, 0, c);
388 dd = -dd;
389 }
390
391 U[0] = AA[0][0];
392
393 const TYPE m0 = AA[0][1] / AA[0][0];
394 const TYPE m1 = AA[0][2] / AA[0][0];
395 TYPE AAA[2][2] = { { AA[1][1] - AA[1][0] * m0, AA[1][2] - AA[1][0] * m1 },
396 { AA[2][1] - AA[2][0] * m0, AA[2][2] - AA[2][0] * m1 } };
397
398 r = 0;
399 c = 0;
400 if(ABS(AAA[1][0]) > ABS(AAA[0][0])) r = 1;
401 if(ABS(AAA[0][1]) > ABS(AAA[r][c]))
402 {
403 r = 0;
404 c = 1;
405 }
406 if(ABS(AAA[1][1]) > ABS(AAA[r][c]))
407 {
408 r = 1;
409 c = 1;
410 }
411
412 if(r == 1) dd = -dd;
413 if(c > 0) dd = -dd;
414
415 U[1] = AAA[r][c];
416
417 // fixed from U(2). needs check
418 if(U[1] == 0)
419 U[2] = 0;
420 else
421 U[2] = AAA[1 - r][1 - c] - AAA[r][1 - c] * AAA[1 - r][c] / U[1];
422
423 d = dd;
424 dd = dd * U[0] * U[1] * U[2];
425
426 if(U[0] < 0) d = -d;
427 if(U[1] < 0) d = -d;
428 if(U[2] < 0) d = -d;
429
430 const TYPE AU = ABS(U[1]);
431 if(AU > 6.607e-8)
432 {
433 nit = 16.8 + 2.0 * log10(AU);
434 nit = ceil(15.0 / nit);
435 }
436 else
437 {
438 subspa = true;
439 }
440 }
441 else
442 {
443 // LU (partial).
444 if(ABS(A[1][0]) > ABS(A[2][0]))
445 {
446 if(ABS(A[0][0]) > ABS(A[1][0]))
447 {
448 copy(*AA, *A, 9);
449 dd = 1.0;
450 }
451 else
452 {
453 copy(AA[0], A[1], 3);
454 copy(AA[1], A[0], 3);
455 copy(AA[2], A[2], 3);
456 dd = -1.0;
457 }
458 }
459 else
460 {
461 if(ABS(A[0][0]) > ABS(A[2][0]))
462 {
463 copy(*AA, *A, 9);
464 dd = 1.0;
465 }
466 else
467 {
468 copy(AA[0], A[2], 3);
469 copy(AA[1], A[1], 3);
470 copy(AA[2], A[0], 3);
471 dd = -1.0;
472 }
473 }
474
475 d = dd;
476 U[0] = AA[0][0];
477 if(U[0] < 0) d = -d;
478
479 const TYPE m0 = AA[0][1] / AA[0][0];
480 const TYPE m1 = AA[0][2] / AA[0][0];
481 TYPE AAA[2][2] = { { AA[1][1] - AA[1][0] * m0, AA[1][2] - AA[1][0] * m1 },
482 { AA[2][1] - AA[2][0] * m0, AA[2][2] - AA[2][0] * m1 } };
483
484 if(ABS(AAA[0][0]) < ABS(AAA[1][0]))
485 {
486 U[1] = AAA[1][0];
487 U[2] = AAA[0][1] - AAA[0][0] * AAA[1][1] / AAA[1][0];
488 dd = -dd;
489 d = -d;
490 if(U[1] < 0) d = -d;
491 if(U[2] < 0) d = -d;
492 }
493 else if(AAA[0][0] == 0)
494 {
495 U[1] = 0;
496 U[2] = 0;
497 }
498 else
499 {
500 U[1] = AAA[0][0];
501 U[2] = AAA[1][1] - AAA[1][0] * AAA[0][1] / AAA[0][0];
502 if(U[1] < 0) d = -d;
503 if(U[2] < 0) d = -d;
504 }
505
506 dd = dd * U[0] * U[1] * U[2];
507 }
508
509 if(d == 0) d = 1.0;
510
511 dd = 8.0 * d * dd;
512
513 const TYPE t = A[0][0] + A[1][1] + A[2][2];
514 TYPE B[4][4] = { { t, A[1][2] - A[2][1], A[2][0] - A[0][2], A[0][1] - A[1][0] },
515 { 0.0, 2.0 * A[0][0] - t, A[0][1] + A[1][0], A[0][2] + A[2][0] },
516 { 0.0, 0.0, 2.0 * A[1][1] - t, A[1][2] + A[2][1] },
517 { 0.0, 0.0, 0.0, 2.0 * A[2][2] - t } };
518
519 for(size_t i = 0; i < 4; i++)
520 for(size_t j = 0; j < 4; j++) B[i][j] *= d;
521
522 B[1][0] = B[0][1];
523 B[2][0] = B[0][2];
524 B[3][0] = B[0][3];
525 B[2][1] = B[1][2];
526 B[3][1] = B[1][3];
527 B[3][2] = B[2][3];
528
529 // Find largest eigenvalue by analytic formula
530 TYPE x = 0.0;
531 if(b >= -0.3332)
532 {
533 const TYPE Delta0 = 1.0 + 3.0 * b;
534 const TYPE Delta1 = -1.0 + (27.0 / 16.0) * dd * dd + 9.0 * b;
535 TYPE phi = Delta1 / Delta0;
536 phi /= SQRT(Delta0);
537 const TYPE SS = (4.0 / 3.0) * (1.0 + cos(acos(phi) / 3.0) * SQRT(Delta0));
538 const TYPE S = SQRT(SS) / 2.0;
539 x = S + 0.5 * SQRT(fmax(0.0, -SS + 4.0 + dd / S));
540 }
541 else
542 {
543 x = SQRT(3.0);
544 TYPE xold = 3.0;
545 while((xold - x) > 1.0e-12)
546 {
547 xold = x;
548 const TYPE px = x * (x * (x * x - 2.0) - dd) + b;
549 const TYPE dpx = x * (4.0 * x * x - 4.0) - dd;
550 x = x - px / dpx;
551 }
552 }
553
554 TYPE v[4] = { 0.0, 0.0, 0.0, 0.0 };
555
556 if(quick)
557 {
558 // LDL
559 TYPE BB[4][4];
560 copy(*BB, *B, 16);
561 for(size_t i = 0; i < 4; i++)
562 {
563 for(size_t j = 0; j < 4; j++) BB[i][j] = -BB[i][j];
564 BB[i][i] += x;
565 }
566
567 size_t p[4] = { 0, 1, 2, 3 };
568 TYPE L[4][4]
569 = { { 1.0, 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 0.0 }, { 0.0, 0.0, 0.0, 1.0 } };
570 TYPE Ddiag[4] = { 0.0, 0.0, 0.0, 0.0 };
571
572 // First step
573 size_t r = 3;
574 if(BB[3][3] < BB[2][2]) r = 2;
575 if(BB[r][r] < BB[1][1]) r = 1;
576 if(BB[r][r] > BB[0][0])
577 {
578 const size_t tmp = p[0];
579 p[0] = p[r];
580 p[r] = tmp;
581 swap_rows(*BB, 4, 4, 0, r);
582 swap_cols(*BB, 4, 4, 0, r);
583 }
584
585 Ddiag[0] = BB[0][0];
586 L[1][0] = BB[1][0] / Ddiag[0];
587 L[2][0] = BB[2][0] / Ddiag[0];
588 L[3][0] = BB[3][0] / Ddiag[0];
589
590 BB[1][1] -= L[1][0] * BB[0][1];
591 BB[2][1] -= L[1][0] * BB[0][2];
592 BB[1][2] = BB[2][1];
593 BB[3][1] -= L[1][0] * BB[0][3];
594 BB[1][3] = BB[3][1];
595 BB[2][2] -= L[2][0] * BB[0][2];
596 BB[3][2] -= L[2][0] * BB[0][3];
597 BB[2][3] = BB[3][2];
598 BB[3][3] -= L[3][0] * BB[0][3];
599
600 // Second step
601 r = 3;
602 if(BB[3][3] < BB[2][2]) r = 2;
603 if(BB[r][r] > BB[1][1])
604 {
605 const size_t tmp = p[1];
606 p[1] = p[r];
607 p[r] = tmp;
608 swap_rows(*BB, 4, 4, 1, r);
609 swap_cols(*BB, 4, 4, 1, r);
610 swap_rows(*L, 4, 4, 1, r);
611 swap_cols(*L, 4, 4, 1, r);
612 }
613
614 Ddiag[1] = BB[1][1];
615 L[2][1] = BB[2][1] / Ddiag[1];
616 L[3][1] = BB[3][1] / Ddiag[1];
617 BB[2][2] -= L[2][1] * BB[1][2];
618 BB[3][2] -= L[2][1] * BB[1][3];
619 BB[2][3] = BB[3][2];
620 BB[3][3] -= L[3][1] * BB[1][3];
621
622 // Third step
623 if(BB[2][2] < BB[3][3])
624 {
625 Ddiag[2] = BB[3][3];
626 swap_rows(*BB, 4, 4, 2, 3);
627 swap_cols(*BB, 4, 4, 2, 3);
628 swap_rows(*L, 4, 4, 2, 3);
629 swap_cols(*L, 4, 4, 2, 3);
630 const size_t tmp = p[2];
631 p[2] = p[3];
632 p[3] = tmp;
633 }
634 else
635 {
636 Ddiag[2] = BB[2][2];
637 }
638
639 L[3][2] = BB[3][2] / Ddiag[2];
640 v[0] = L[1][0] * L[3][1] + L[2][0] * L[3][2] - L[1][0] * L[3][2] * L[2][1] - L[3][0];
641 v[1] = L[3][2] * L[2][1] - L[3][1];
642 v[2] = -L[3][2];
643 v[3] = 1.0;
644 normalize_array(v, 4);
645
646 TYPE temp[4];
647 copy(temp, v, 4);
648 for(size_t i = 0; i < 4; i++) v[p[i]] = temp[i];
649 }
650 else
651 {
652 // LDL
653 TYPE BB[4][4];
654 copy(*BB, *B, 16);
655 for(size_t i = 0; i < 4; i++)
656 {
657 for(size_t j = 0; j < 4; j++) BB[i][j] = -BB[i][j];
658 BB[i][i] += x;
659 }
660
661 size_t p[4] = { 0, 1, 2, 3 };
662 TYPE L[4][4]
663 = { { 1.0, 0.0, 0.0, 0.0 }, { 0.0, 1.0, 0.0, 0.0 }, { 0.0, 0.0, 1.0, 0.0 }, { 0.0, 0.0, 0.0, 1.0 } };
664 TYPE D[4][4]
665 = { { 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0, 0.0 } };
666
667 // First step
668 size_t r = 3;
669 if(BB[3][3] < BB[2][2]) r = 2;
670 if(BB[r][r] < BB[1][1]) r = 1;
671 if(BB[r][r] > BB[0][0])
672 {
673 const size_t tmp = p[0];
674 p[0] = p[r];
675 p[r] = tmp;
676 swap_rows(*BB, 4, 4, 0, r);
677 swap_cols(*BB, 4, 4, 0, r);
678 }
679
680 D[0][0] = BB[0][0];
681 L[1][0] = BB[1][0] / D[0][0];
682 L[2][0] = BB[2][0] / D[0][0];
683 L[3][0] = BB[3][0] / D[0][0];
684 BB[1][1] -= L[1][0] * BB[0][1];
685 BB[2][1] -= L[1][0] * BB[0][2];
686 BB[1][2] = BB[2][1];
687 BB[3][1] -= L[1][0] * BB[0][3];
688 BB[1][3] = BB[3][1];
689 BB[2][2] -= L[2][0] * BB[0][2];
690 BB[3][2] -= L[2][0] * BB[0][3];
691 BB[2][3] = BB[3][2];
692 BB[3][3] -= L[3][0] * BB[0][3];
693
694 // Second step
695 r = 2;
696 if(BB[2][2] < BB[1][1]) r = 1;
697 if(BB[r][r] > BB[0][0])
698 {
699 const size_t tmp = p[1];
700 p[1] = p[r];
701 p[r] = tmp;
702 swap_rows(*BB, 4, 4, 1, r);
703 swap_cols(*BB, 4, 4, 1, r);
704 swap_rows(*L, 4, 4, 1, r);
705 swap_cols(*L, 4, 4, 1, r);
706 }
707
708 D[1][1] = BB[1][1];
709 L[2][1] = BB[2][1] / D[1][1];
710 L[3][1] = BB[3][1] / D[1][1];
711 D[2][2] = BB[2][2] - L[2][1] * BB[1][2];
712 D[3][2] = BB[3][2] - L[2][1] * BB[1][3];
713 D[2][3] = D[3][2];
714 D[3][3] = BB[3][3] - L[3][1] * BB[1][3];
715
716 const TYPE DD = D[2][2] * D[3][3] - D[2][3] * D[2][3];
717 if(DD == 0)
718 {
719 const TYPE max_abs = fmax(fmax(ABS(D[2][2]), ABS(D[2][3])), ABS(D[3][3]));
720 if(max_abs == 0)
721 {
722 v[0] = L[1][0] * L[3][1] - L[3][0];
723 v[1] = -L[3][1];
724 v[2] = 0.0;
725 v[3] = 1.0;
726 }
727 else
728 {
729 TYPE nullspace[2];
730 compute_null_space(nullspace, D[2][2], D[2][3], D[3][3]);
731 v[3] = nullspace[1];
732 v[2] = nullspace[0] - L[3][2] * v[3];
733 v[1] = -L[2][1] * v[2] - L[3][1] * v[3];
734 v[0] = -L[1][0] * v[1] - L[2][0] * v[2] - L[3][0] * v[3];
735 }
736 normalize_array(v, 4);
737 }
738 else
739 {
740 const TYPE ID[2][2] = { { D[3][3], -D[2][3] }, { -D[2][3], D[2][2] } };
741
742 if(subspa)
743 {
744 TYPE vmat[4][2] = { { L[1][0] * L[2][1] - L[2][0], L[1][0] * L[3][1] - L[3][0] },
745 { -L[2][1], -L[3][1] },
746 { 1.0, 0.0 },
747 { 0.0, 1.0 } };
748 TYPE IL[4][4] = { { 1.0, 0.0, 0.0, 0.0 },
749 { -L[1][0], 1.0, 0.0, 0.0 },
750 { vmat[0][0], vmat[1][0], vmat[2][0], vmat[3][0] },
751 { vmat[0][1], vmat[1][1], vmat[2][1], vmat[3][1] } };
752
753 {
754 TYPE col0[4] = { vmat[0][0], vmat[1][0], vmat[2][0], vmat[3][0] };
755 TYPE col1[4] = { vmat[0][1], vmat[1][1], vmat[2][1], vmat[3][1] };
756 normalize_array(col0, 4);
757 const TYPE proj = vector_scalar(col0, col1, 4);
758 for(size_t i = 0; i < 4; i++) col1[i] -= proj * col0[i];
759 normalize_array(col1, 4);
760 for(size_t i = 0; i < 4; i++)
761 {
762 vmat[i][0] = col0[i];
763 vmat[i][1] = col1[i];
764 }
765 }
766
767 for(size_t it = 0; it < 2; it++)
768 {
769 TYPE tmp[4][2] = { { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 } };
770 TYPE tmp2[4][2] = { { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 }, { 0.0, 0.0 } };
771
772 for(size_t i = 0; i < 4; i++)
773 for(size_t j = 0; j < 2; j++)
774 for(size_t k = 0; k < 4; k++) tmp[i][j] += IL[i][k] * vmat[k][j];
775
776 for(size_t j = 0; j < 2; j++)
777 {
778 tmp[0][j] /= D[0][0];
779 tmp[1][j] /= D[1][1];
780 const TYPE t0 = tmp[2][j];
781 const TYPE t1 = tmp[3][j];
782 tmp[2][j] = (ID[0][0] * t0 + ID[0][1] * t1) / DD;
783 tmp[3][j] = (ID[1][0] * t0 + ID[1][1] * t1) / DD;
784 }
785
786 for(size_t i = 0; i < 4; i++)
787 for(size_t j = 0; j < 2; j++)
788 for(size_t k = 0; k < 4; k++) tmp2[i][j] += IL[k][i] * tmp[k][j];
789
790 copy(*vmat, *tmp2, 8);
791 }
792
793 {
794 TYPE col0[4] = { vmat[0][0], vmat[1][0], vmat[2][0], vmat[3][0] };
795 TYPE col1[4] = { vmat[0][1], vmat[1][1], vmat[2][1], vmat[3][1] };
796 normalize_array(col0, 4);
797 const TYPE proj = vector_scalar(col0, col1, 4);
798 for(size_t i = 0; i < 4; i++) col1[i] -= proj * col0[i];
799 normalize_array(col1, 4);
800 for(size_t i = 0; i < 4; i++)
801 {
802 vmat[i][0] = col0[i];
803 vmat[i][1] = col1[i];
804 }
805 }
806
807 TYPE HL[2][4] = { { 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0, 0.0 } };
808 TYPE HD[2][4] = { { 0.0, 0.0, 0.0, 0.0 }, { 0.0, 0.0, 0.0, 0.0 } };
809 TYPE Hsmall[2][2] = { { 0.0, 0.0 }, { 0.0, 0.0 } };
810
811 for(size_t i = 0; i < 2; i++)
812 for(size_t j = 0; j < 4; j++)
813 for(size_t k = 0; k < 4; k++) HL[i][j] += vmat[k][i] * L[k][j];
814
815 for(size_t i = 0; i < 2; i++)
816 for(size_t j = 0; j < 4; j++)
817 for(size_t k = 0; k < 4; k++) HD[i][j] += HL[i][k] * D[k][j];
818
819 for(size_t i = 0; i < 2; i++)
820 for(size_t j = 0; j < 2; j++)
821 for(size_t k = 0; k < 4; k++) Hsmall[i][j] -= HD[i][k] * HL[j][k];
822
823 if(ABS(Hsmall[0][1]) < 1.0e-15)
824 {
825 for(size_t i = 0; i < 4; i++) v[i] = vmat[i][Hsmall[0][0] > Hsmall[0][1] ? 0 : 1];
826 }
827 else
828 {
829 const TYPE ratio = (Hsmall[0][0] - Hsmall[1][1]) / (2.0 * Hsmall[0][1]);
830 const TYPE alpha = ratio + (Hsmall[0][1] < 0 ? -1.0 : 1.0) * SQRT(1.0 + ratio * ratio);
831 for(size_t i = 0; i < 4; i++) v[i] = vmat[i][0] * alpha + vmat[i][1];
832 normalize_array(v, 4);
833 }
834 }
835 else
836 {
837 v[0] = L[1][0] * L[3][1] + L[2][0] * L[3][2] - L[1][0] * L[3][2] * L[2][1] - L[3][0];
838 v[1] = L[3][2] * L[2][1] - L[3][1];
839 v[2] = -L[3][2];
840 v[3] = 1.0;
841
842 TYPE IL[4][4] = { { 1.0, 0.0, 0.0, 0.0 },
843 { -L[1][0], 1.0, 0.0, 0.0 },
844 { L[1][0] * L[2][1] - L[2][0], -L[2][1], 1.0, 0.0 },
845 { v[0], v[1], v[2], v[3] } };
846
847 normalize_array(v, 4);
848
849 for(size_t it = 0; it < (size_t)nit; it++)
850 {
851 TYPE tmp[4] = { 0.0, 0.0, 0.0, 0.0 };
852 TYPE tmp2[4] = { 0.0, 0.0, 0.0, 0.0 };
853
854 for(size_t i = 0; i < 4; i++)
855 for(size_t k = 0; k < 4; k++) tmp[i] += IL[i][k] * v[k];
856
857 tmp[0] /= D[0][0];
858 tmp[1] /= D[1][1];
859 {
860 const TYPE t0 = tmp[2];
861 const TYPE t1 = tmp[3];
862 tmp[2] = (ID[0][0] * t0 + ID[0][1] * t1) / DD;
863 tmp[3] = (ID[1][0] * t0 + ID[1][1] * t1) / DD;
864 }
865
866 for(size_t i = 0; i < 4; i++)
867 for(size_t k = 0; k < 4; k++) tmp2[i] += IL[k][i] * tmp[k];
868
869 copy(v, tmp2, 4);
870 normalize_array(v, 4);
871 }
872 }
873
874 TYPE temp[4];
875 copy(temp, v, 4);
876 for(size_t i = 0; i < 4; i++) v[p[i]] = temp[i];
877 }
878 }
879
880 // Polar factor (up to sign).
881 const TYPE v22 = 2.0 * v[1] * v[1];
882 const TYPE v33 = 2.0 * v[2] * v[2];
883 const TYPE v44 = 2.0 * v[3] * v[3];
884 const TYPE v23 = 2.0 * v[1] * v[2];
885 const TYPE v14 = 2.0 * v[0] * v[3];
886 const TYPE v24 = 2.0 * v[1] * v[3];
887 const TYPE v13 = 2.0 * v[0] * v[2];
888 const TYPE v12 = 2.0 * v[0] * v[1];
889 const TYPE v34 = 2.0 * v[2] * v[3];
890
891 Q[0][0] = 1.0 - v33 - v44;
892 Q[0][1] = v23 + v14;
893 Q[0][2] = v24 - v13;
894 Q[1][0] = v23 - v14;
895 Q[1][1] = 1.0 - v22 - v44;
896 Q[1][2] = v12 + v34;
897 Q[2][0] = v13 + v24;
898 Q[2][1] = v34 - v12;
899 Q[2][2] = 1.0 - v22 - v33;
900
901 if(d == -1) for(size_t i = 0; i < 3; i++) for(size_t j = 0; j < 3; j++) Q[i][j] = -Q[i][j];
902
903 TYPE QT[3][3];
904 for(size_t i = 0; i < 3; i++)
905 for(size_t j = 0; j < 3; j++) QT[j][i] = Q[i][j];
906
907 matrix_multiply(*QT, *A, *H, 3, 3, 3);
908 for(size_t i = 0; i < 9; i++)
909 {
910 (*H)[i] *= norm;
911 (*A)[i] *= norm;
912 }
913}
914
915//==============================================================================
916
917void abs_matrix(TYPE *matrix_abs, size_t num_el)
918{
919 int i, j;
920
921 for(i = 0; i < 2; i++)
922 {
923 matrix_abs[i] = ABS(matrix_abs[i]);
924 // printf("%f\n", matricella[i][j] );
925 }
926 // printf("ok 3\n");
927 printf("\n");
928};
929
930void matrix_multiply(const TYPE *A, const TYPE *B, TYPE *RES, int rows_A, int cols_A, int cols_B)
931{
932 TYPE product;
933
934 // k is the row of A that is being multiplied
935 for(size_t k = 0; k < rows_A; ++k)
936 {
937 // is has to be multiplied to each of the columns of B
938 for(size_t j = 0; j < cols_B; ++j)
939 {
940 // use a separate variable to be sure to start from 0 with the product
941 product = 0;
942 for(size_t i = 0; i < cols_A; ++i)
943 {
944 product += A[cols_A * k + i] * B[j + cols_B * i];
945 }
946 RES[k * cols_B + j] = product;
947 }
948 }
949}
950
951TYPE max_val_matrix(TYPE *matrice, size_t size)
952{
953 TYPE max;
954
955 for(size_t i = 0; i < size; i++)
956 {
957 if(matrice[i] > max)
958 {
959 max = matrice[i];
960 }
961 }
962 return max;
963}
964
965static inline void normalize_array(TYPE *vector, int size)
966{
967 int ii;
968 TYPE norm = 0;
969
970 // computing the square of the norm of v
971 for(ii = 0; ii < 4; ii++)
972 {
973 norm += vector[ii] * vector[ii];
974 }
975 // squared root of the norm of v
976 norm = SQRT(norm);
977
978 // printf("norm is: %f\n", norm);
979
980 // dividing each element of v for the norm
981 for(ii = 0; ii < size; ii++)
982 {
983 vector[ii] /= norm;
984 }
985}
986
987void swap_cols(TYPE *m, size_t rows, size_t cols, size_t col0, size_t col1)
988{
989 // vector with the same size of one row input matrix (that is the number of columns)
990 TYPE *temp = (TYPE *)calloc(cols, sizeof(TYPE));
991
992 for(int i = 0; i < rows; i++)
993 {
994 temp[i] = m[col0 + cols * i];
995 m[col0 + cols * i] = m[col1 + cols * i];
996 m[col1 + cols * i] = temp[i];
997 }
998 free(temp);
999}
1000
1001void swap_rows(TYPE *m, size_t rows, size_t cols, size_t row0, size_t row1)
1002{
1003 // vector with the same size of one row input matrix (that is the number of columns)
1004 TYPE *temp = (TYPE *)calloc(cols, sizeof(TYPE));
1005
1006 for(int i = 0; i < cols; i++)
1007 {
1008 temp[i] = m[cols * row0 + i];
1009 m[cols * row0 + i] = m[cols * row1 + i];
1010 m[cols * row1 + i] = temp[i];
1011 }
1012 free(temp);
1013}
1014
1015void stampa_matrice(TYPE *m, size_t rows, size_t cols)
1016{
1017 int i;
1018
1019 for(i = 0; i < rows * cols; i++)
1020 {
1021 printf("%f ", m[i]);
1022 if(i % cols == cols - 1)
1023 {
1024 printf("\n");
1025 }
1026 }
1027 // un bel a capo prima di chiudere
1028 printf("\n");
1029}
1030
1031void compute_null_space(TYPE *nullspace, const TYPE a, const TYPE b, const TYPE c)
1032{
1033 // chceck that determinant is zero and do something about it
1034 if(a * c - b * b == 0)
1035 {
1036 }
1037
1038 if(a != 0)
1039 {
1040 nullspace[0] = b;
1041 nullspace[1] = -a;
1042 }
1043 else
1044 {
1045 // check on these too
1046 // assert(a == 0);
1047 // assert(b == 0);
1048 // assert(c != 0);
1049 nullspace[0] = c;
1050 nullspace[1] = -b;
1051 }
1052}
1053
1054void copy(TYPE *dest, TYPE *source, size_t num_el)
1055{
1056 for(size_t psi = 0; psi < num_el; psi++)
1057 {
1058 dest[psi] = source[psi];
1059 }
1060}
1061
1062void orthonormalize_v_with_qr(TYPE *v0, TYPE *v1, const TYPE v00, const TYPE v10, const TYPE v01, const TYPE v11)
1063{
1064 v0[0] = v00;
1065 v0[1] = v01;
1066 v0[2] = 1;
1067 v0[3] = 0;
1068 normalize_array(v0, 4);
1069
1070 v1[0] = v10 + v01 * v01 * v10 - v00 * v01 * v11;
1071 v1[1] = v11 - v00 * v01 * v10 + v00 * v00 * v11;
1072 v1[2] = -v00 * v10 - v01 * v11;
1073 v1[3] = v00 * v00 + v01 * v01 + 1;
1074 normalize_array(v1, 4);
1075}
1076
1077void multiply_il_v(TYPE *RES, const TYPE IL01, const TYPE IL02, const TYPE IL03, const TYPE IL12, const TYPE IL13,
1078 const TYPE *v)
1079{
1080 RES[0] = v[0];
1081 RES[1] = v[0] * IL01 + v[1];
1082 RES[2] = v[0] * IL02 + v[1] * IL12 + v[2];
1083 RES[3] = v[0] * IL03 + v[1] * IL13 + v[3];
1084}
1085
1086// ID is 2x2
1087void multiply_id_v(TYPE *RES, const TYPE ID00, const TYPE ID11, const TYPE *ID, const TYPE *v)
1088{
1089 RES[0] = v[0] * ID00;
1090 RES[1] = v[1] * ID11;
1091 RES[2] = v[2] * ID[0] + v[3] * ID[1];
1092 RES[3] = v[2] * ID[2] + v[3] * ID[3];
1093}
1094
1095void multiply_v_il(TYPE *RES, const TYPE *v, const TYPE IL01, const TYPE IL02, const TYPE IL03, const TYPE IL12,
1096 const TYPE IL13)
1097{
1098 RES[0] = v[0] + v[1] * IL01 + v[2] * IL02 + v[3] * IL03;
1099 RES[1] = v[1] + v[2] * IL12 + v[3] * IL13;
1100 RES[2] = v[2];
1101 RES[3] = v[3];
1102}
1103
1105{
1106 // The factorization was obtained symbolically by WolframAlpha
1107 // by running the following query:
1108 //
1109 // QRDecomposition[{{a,e},{b,f},{c,g},{d,h}}]
1110
1111 normalize_array(v0, 4);
1112
1113 // To avoid numerical stability issues when multiplying too big values in the solution,
1114 // we scale down the second vector.
1115 TYPE factor = v1[0];
1116 if(factor < ABS(v1[1])) factor = ABS(v1[1]);
1117 if(factor < ABS(v1[2])) factor = ABS(v1[2]);
1118 if(factor < ABS(v1[3])) factor = ABS(v1[3]);
1119 // TODO: find and equivalent in C
1120 // factor = 1 / (factor + std::numeric_limits<TReal>::min());
1121 factor = 1 / (factor);
1122
1123 const TYPE a = v0[0];
1124 const TYPE b = v0[1];
1125 const TYPE c = v0[2];
1126 const TYPE d = v0[3];
1127 const TYPE e = v1[0] * factor;
1128 const TYPE f = v1[1] * factor;
1129 const TYPE g = v1[2] * factor;
1130 const TYPE h = v1[3] * factor;
1131
1132 // OPTME: We could reuse some of the multiplications.
1133 // ANSME: Is there a more numerically stable way to do this?
1134 v1[0] = b * b * e + c * c * e + d * d * e - a * b * f - a * c * g - a * d * h;
1135 v1[1] = -a * b * e + a * a * f + c * c * f + d * d * f - b * c * g - b * d * h;
1136 v1[2] = -a * c * e - b * c * f + a * a * g + b * b * g + d * d * g - c * d * h;
1137 v1[3] = -a * d * e - b * d * f - c * d * g + a * a * h + b * b * h + c * c * h;
1138 normalize_array(v1, 4);
1139}
1140
1142{
1143 RES[0] = -v[0] * D[0];
1144 RES[1] = -v[1] * D[5];
1145 RES[2] = -v[2] * D[5] - v[3] * D[14];
1146 RES[3] = -v[2] * D[11] - v[3] * D[15];
1147}
1148
1149// scalar product of two vectors
1150TYPE vector_scalar(const TYPE *a, const TYPE *b, const size_t num_el)
1151{
1152 TYPE somma = { 0.0 };
1153 for(size_t jod = 0; jod < num_el; jod++)
1154 {
1155 somma += a[jod] * b[jod];
1156 }
1157 return somma;
1158}
#define RES
Definition atrous.c:91
#define m
Definition basecurve.c:277
static const dt_aligned_pixel_simd_t const dt_adaptation_t const float p
Definition chromatic_adaptation.h:309
#define B(y, x)
Definition colorspaces.c:187
#define A(y, x)
Definition colorspaces.c:186
const float i
Definition colorspaces_inline_conversions.h:440
const float L
Definition colorspaces_inline_conversions.h:493
const float g
Definition colorspaces_inline_conversions.h:674
const dt_aligned_pixel_t f
Definition colorspaces_inline_conversions.h:102
const float d
Definition colorspaces_inline_conversions.h:680
const float max
Definition colorspaces_inline_conversions.h:490
#define S(V, params)
Definition common/histogram.c:36
static const dt_aligned_pixel_simd_t const dt_aligned_pixel_simd_t row1
Definition darktable.h:623
static const dt_aligned_pixel_simd_t row0
Definition darktable.h:622
#define H
Definition diffuse.c:613
static const float x
Definition iop_profile.h:235
const int t
Definition iop_profile.h:225
const float v
Definition iop_profile.h:221
float *const restrict const size_t k
Definition luminance_mask.h:78
size_t size
Definition mipmap_cache.c:3
const float factor
Definition pdf.h:90
#define ABS(n)
Definition polar_decomposition.h:82
void multiply_il_v(double *RES, const double IL01, const double IL02, const double IL03, const double IL12, const double IL13, const double *v)
Multiply a vector by the lower-triangular inverse factor used in the LDL solve.
Definition polar_decomposition.h:1077
double max_val_matrix(double *matrice, size_t size)
Return the maximum entry of a flat matrix buffer.
Definition polar_decomposition.h:951
void swap_rows(double *m, size_t rows, size_t cols, size_t row0, size_t row1)
Swap two rows of a row-major dense matrix in place.
Definition polar_decomposition.h:1001
static void normalize_array(double *vector, int size)
Normalize a vector to unit Euclidean norm.
Definition polar_decomposition.h:965
void multiply_id_v(double *RES, const double ID00, const double ID11, const double *ID, const double *v)
Multiply a vector by the block-diagonal inverse factor used in the LDL solve.
Definition polar_decomposition.h:1087
double vector_scalar(const double *a, const double *b, const size_t num_el)
Compute the scalar product of two vectors.
Definition polar_decomposition.h:1150
void multiply_v_il(double *RES, const double *v, const double IL01, const double IL02, const double IL03, const double IL12, const double IL13)
Multiply a vector by the transpose-side lower-triangular factor used in the LDL solve.
Definition polar_decomposition.h:1095
#define TYPE
Definition polar_decomposition.h:77
void multiply_minus_v_d(double *RES, double *v, double *D)
Apply the negative D factor of the LDL factorization to a vector.
Definition polar_decomposition.h:1141
void abs_matrix(double *matrix_abs, size_t num_el)
Replace each element of a vector with its absolute value.
Definition polar_decomposition.h:917
void matrix_multiply(const double *A, const double *B, double *RES, int rows_A, int cols_A, int cols_B)
Multiply two dense row-major matrices.
Definition polar_decomposition.h:930
#define SQRT(n)
Definition polar_decomposition.h:83
void compute_null_space(double *nullspace, const double a, const double b, const double c)
Compute one non-zero vector in the null space of a symmetric 2x2 matrix.
Definition polar_decomposition.h:1031
void swap_cols(double *m, size_t rows, size_t cols, size_t col0, size_t col1)
Swap two columns of a row-major dense matrix in place.
Definition polar_decomposition.h:987
void polar_decomposition(double A[3][3], double Q[3][3], double H[3][3])
Compute the polar decomposition of a 3x3 matrix.
Definition polar_decomposition.h:288
void copy(double *dest, double *source, size_t num_el)
Copy a flat buffer.
Definition polar_decomposition.h:1054
void orthonormalize_v_with_qr_single(double *v0, double *v1)
Re-orthonormalize two 4D vectors after repeated inverse iteration steps.
Definition polar_decomposition.h:1104
void stampa_matrice(double *m, size_t rows, size_t cols)
Print a row-major matrix for manual debugging.
Definition polar_decomposition.h:1015
void orthonormalize_v_with_qr(double *v0, double *v1, const double v00, const double v10, const double v01, const double v11)
Build two orthonormal candidate eigenvectors from symbolic QR factors.
Definition polar_decomposition.h:1062
const float r
Definition src/develop/noise_generator.h:101