Picking the first k
eigen values picked the smallest k
, which you can fix by sorting them in reverse order. Here’s working code:
import TestImages
import Images
import ImageInTerminal
import LinearAlgebra
function compressed_svd(X::AbstractMatrix, k::Int, p::Int = 10)
m, n = size(X)
l = k + p
Φ = rand(l, m)
Y = Φ * X
B = Y * Y'
B = 0.5 * (B + B')
D, T = LinearAlgebra.eigen(B; sortby = λ -> -λ)
D, T = D[1:k], T[:, 1:k]
S̃⁻¹ = LinearAlgebra.Diagonal(1 ./ sqrt.(D))
Ṽ = Y' * T * S̃⁻¹
Ũ = X * Ṽ
F = LinearAlgebra.svd(Ũ)
V = Ṽ * F.V
return F.U, LinearAlgebra.Diagonal(F.S), V
end
image = TestImages.testimage("mandrill")
gray_image = Images.Gray.(image);
image_matrix = Images.channelview(gray_image);
U, S, V = compressed_svd(image_matrix, 20);
M = Images.clamp01!(U * S * V');
Images.colorview(Images.Gray, M)