File tree Expand file tree Collapse file tree 4 files changed +124
-4
lines changed Expand file tree Collapse file tree 4 files changed +124
-4
lines changed Original file line number Diff line number Diff line change 116
116
117
117
kernel (prob:: EigenProblemMixin ) = Eigen. kernel (prob)
118
118
export Eigen
119
+
120
+ struct SingularValueDecompositionProblem <: ProblemMixin
121
+ a:: AbstractMatrix
122
+ tol:: Real
123
+ end
124
+
125
+ struct SingularValueDecompositionSolution <: SolutionMixin
126
+ u:: AbstractMatrix
127
+ s:: AbstractMatrix
128
+ v:: AbstractMatrix
129
+
130
+ function SingularValueDecompositionSolution (u, s, v)
131
+ s = Diagonal (s)
132
+ @assert isapprox (I, u' * u) " u must be orthogonal"
133
+ @assert isapprox (I, v' * v) " v must be orthogonal"
134
+
135
+ soln = new (u, s, v)
136
+ return soln
137
+ end
138
+ end
139
+
140
+ # we cheat by importing eigen and qr from LinearAlgebra
141
+ import LinearAlgebra: eigen, qr
142
+ function kernel (prob:: SingularValueDecompositionProblem )
143
+ a = prob. a
144
+ tol = prob. tol
145
+
146
+ n = size (a, 1 )
147
+ e, c = eigen (a' * a)
148
+ q, r = qr (a * c) |> (x -> (x. Q, x. R))
149
+
150
+ s = zeros (n)
151
+ rs = zeros (n, n)
152
+
153
+ for (i, ei) in enumerate (e)
154
+ @assert ei >= (tol * tol) " s2 must be non-negative"
155
+ s[i] = sqrt (ei)
156
+ rs[:, i] = r[:, i] / s[i]
157
+ end
158
+
159
+ u = Matrix (q)
160
+ v = c * rs
161
+
162
+ soln = SingularValueDecompositionSolution (u, s, v)
163
+ return soln
164
+ end
165
+
166
+ SingularValueDecomposition = SingularValueDecompositionProblem
167
+ export SingularValueDecomposition
Original file line number Diff line number Diff line change @@ -152,3 +152,43 @@ kernel(prob::LUFactorizationProblemMixin) = LU.kernel(prob)
152
152
153
153
LUFactorization = LU. GaussianEliminationV2
154
154
export LUFactorization
155
+
156
+ struct CholeskyFactorizationProblem <: ProblemMixin
157
+ a:: AbstractMatrix
158
+ tol:: Real
159
+ function CholeskyFactorizationProblem (a, tol= 1e-10 )
160
+ prob = new (a, tol)
161
+ return prob
162
+ end
163
+ end
164
+
165
+ struct CholeskyFactorizationSolution <: SolutionMixin
166
+ l:: AbstractMatrix
167
+ function CholeskyFactorizationSolution (l)
168
+ @assert istril (l) " matrix must be lower triangular"
169
+ soln = new (l)
170
+ return soln
171
+ end
172
+ end
173
+
174
+ function kernel (prob:: CholeskyFactorizationProblem )
175
+ tol = prob. tol
176
+ l = copy (prob. a)
177
+ n = size (l, 1 )
178
+
179
+ for i in 1 : n
180
+ @assert l[i, i] > tol " Cholesky factorization failed"
181
+ l[i, i] = sqrt (l[i, i])
182
+ l[i+ 1 : n, i] /= l[i, i]
183
+
184
+ li = l[i+ 1 : n, i]
185
+ l[i+ 1 : n, i+ 1 : n] -= li * li'
186
+ end
187
+
188
+ soln = CholeskyFactorizationSolution (tril (l))
189
+ return soln
190
+ end
191
+
192
+ CholeskyFactorization = CholeskyFactorizationProblem
193
+ CholeskyDecomposition = CholeskyFactorization
194
+ export CholeskyFactorization, CholeskyDecomposition
Original file line number Diff line number Diff line change @@ -7,8 +7,8 @@ import SimpleLinearAlgebra.Eigen
7
7
# Make the first eigenvalue significantly larger
8
8
a = a * a' # Create a symmetric positive-definite matrix
9
9
10
- prob = Eigen. PowerMethod (a, 1000 , 1e-8 )
11
- tol = sqrt (prob. tol * n)
10
+ prob = Eigen. PowerMethod (a, 1000 , 1e-10 )
11
+ tol = sqrt (prob. tol) * n
12
12
13
13
soln = kernel (prob)
14
14
e = soln. e[1 ]
24
24
# Make the first eigenvalue significantly larger
25
25
a = a * a' # Create a symmetric positive-definite matrix
26
26
27
- prob = Eigen. RayleighQuotient (a, 1000 , 1e-8 )
28
- tol = sqrt (prob. tol * n)
27
+ prob = Eigen. RayleighQuotient (a, 1000 , 1e-10 )
28
+ tol = sqrt (prob. tol) * n
29
29
30
30
soln = kernel (prob)
31
31
e = soln. e[1 ]
32
32
c = soln. c[:, 1 ]
33
33
34
34
@test isapprox (a * c, e * c, atol= tol)
35
35
end
36
+
37
+ @testset " Singular Value Decomposition" begin
38
+ n = 4
39
+ a = randn (n, n)
40
+ a = a * a' # Create a symmetric positive-definite matrix
41
+
42
+ prob = SingularValueDecomposition (a, 1e-8 )
43
+ tol = prob. tol
44
+
45
+ soln = kernel (prob)
46
+ u = soln. u
47
+ s = soln. s
48
+ v = soln. v
49
+
50
+ @test isapprox (a, u * s * v' , atol= tol)
51
+ end
Original file line number Diff line number Diff line change 78
78
@test isapprox (pa, l * u, atol= tol) # Verify PA = LU
79
79
@test isapprox (p * a, l * u, atol= tol)
80
80
end
81
+
82
+ @testset " Cholesky factorization" begin
83
+ n = 10
84
+ q, r = rand (n, n) |> qr
85
+ a = q * Diagonal (rand (n)) * q'
86
+
87
+ prob = CholeskyFactorization (a)
88
+ tol = prob. tol
89
+
90
+ soln = kernel (prob)
91
+ l = soln. l
92
+
93
+ @test istril (l)
94
+ @test isapprox (a, l * l' , atol= tol)
95
+ end
You can’t perform that action at this time.
0 commit comments