Ansel
0.0
A darktable fork - bloat + design vision
Loading...
Searching...
No Matches
QR_decomp.h
Go to the documentation of this file.
1
/*
2
This file is part of the Ansel project.
3
Copyright (C) 2023 Davide Patria.
4
5
Ansel is free software: you can redistribute it and/or modify
6
it under the terms of the GNU General Public License as published by
7
the Free Software Foundation, either version 3 of the License, or
8
(at your option) any later version.
9
10
Ansel is distributed in the hope that it will be useful,
11
but WITHOUT ANY WARRANTY; without even the implied warranty of
12
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13
GNU General Public License for more details.
14
15
You should have received a copy of the GNU General Public License
16
along with Ansel. If not, see <http://www.gnu.org/licenses/>.
17
*/
18
28
#include <
math.h
>
29
#include <stdio.h>
30
45
inline
void
QR_dec
(
double
*
A
,
double
*Q,
double
*
R
,
int
rows,
int
cols)
46
{
47
// The function decomposes the input matrix A into the matrices Q and R: one
48
// simmetric, one orthonormal and one upper triangular, by using the
49
// Gram-Schmidt method. The input matrice A is defined as A[rows][cols], so
50
// are the output matrices Q and R. This function is meant to be used in the
51
// polar decomposition algorithm and has been tested with different sizes of
52
// input matrices. Supposedly the algorithm works with any matrix, as long as
53
// the columns vectors are independent.
54
//
55
// For tests for the standalone function please refer to the original github
56
// repo this has been developed in.
57
// https://github.com/DavidePatria/QR_decomposition_C/blob/main/README.md
58
59
// As already mentioned in the README the matrices orders are: A mxn => Q mxn
60
// , R nxn and rank(A) must be n The matrix A[m x n] = [A_00, A_01, ... A_0n;
61
// ...... ; A_m0, ... , A_mn] can be accessed as a vector that has all its
62
// rows consecutively written in a long vector, even if passed as a *A and
63
// defined as A[m][n].
64
//
65
// If A(mxn) has m<n the function still returs R(mxn) and Q(nxn), but it is
66
// enough to get the submatrices Q(mxm) and R(mxn) as a valid decomposition.
67
// This is what also octave does.
68
69
// vectors for internal coputations
70
double
T[rows];
71
double
S
[rows];
72
double
norm;
73
int
i
, ii, j, jj,
k
, kk;
74
double
r
;
75
76
for
(
i
= 0;
i
< cols;
i
++)
77
{
78
printf(
"\n"
);
79
80
// scrolling a column and copying it
81
for
(ii = 0; ii < rows; ii++)
82
{
83
Q[ii * cols +
i
] =
A
[ii * cols +
i
];
84
}
85
86
for
(j = 0; j <
i
; j++)
87
{
88
89
// copying columns into auxiliary variables
90
for
(jj = 0; jj < rows; jj++)
91
{
92
T[jj] = Q[cols * jj + j];
93
S
[jj] =
A
[cols * jj +
i
];
94
}
95
96
// temporary storing T*K in r
97
r
= 0;
98
for
(
k
= 0;
k
< rows;
k
++)
99
{
100
r
+= T[
k
] *
S
[
k
];
101
}
102
103
// setting R[j][i] to r
104
R
[cols * j +
i
] =
r
;
105
106
for
(kk = 0; kk < rows; kk++)
107
{
108
// multiplying vector T by r
109
T[kk] *=
r
;
110
// subtract T[kk] from i-th column of Q
111
Q[cols * kk +
i
] -= T[kk];
112
}
113
}
114
115
// rezeroing norm at each cycle
116
norm = 0;
117
// norm of the i-th column
118
for
(
k
= 0;
k
< rows;
k
++)
119
{
120
// computing norm^2
121
norm += Q[cols *
k
+
i
] * Q[cols *
k
+
i
];
122
}
123
norm = sqrt(norm);
124
125
// assigning i-th element of R diagonal
126
R
[cols *
i
+
i
] = norm;
127
128
for
(
k
= 0;
k
< rows;
k
++)
129
{
130
Q[cols *
k
+
i
] /=
R
[cols *
i
+
i
];
131
}
132
}
133
}
QR_dec
void QR_dec(double *A, double *Q, double *R, int rows, int cols)
Decompose a dense matrix into an orthonormal basis and an upper-triangular factor.
Definition
QR_decomp.h:45
A
#define A(y, x)
Definition
colorspaces.c:186
i
const float i
Definition
colorspaces_inline_conversions.h:440
S
#define S(V, params)
Definition
common/histogram.c:36
k
float *const restrict const size_t k
Definition
luminance_mask.h:78
R
#define R
math.h
r
const float r
Definition
src/develop/noise_generator.h:101
src
common
svd
QR_decomp.h
Generated by
1.9.8