# Efficient multiplication between a low-rank matrix approximation and a vector

Dear All,

I am quite new to Julia, and I am searching for a recommendation. Calling `svd(A)`, I obtain a singular-value decomposition object that gives me access to the `U, S, V`, as discussed in the documentation.

I am interested in approximating the matrix-vector product `A*z`, where `z` is a vector, by approximating `A` with its k-rank approximation. A direct way to do this is to do

``````Ak = U[:,1:k] * Diagonal(S[1:k]) * V[:,1:k]'
w = Ak*z
``````

but this does not seem a good idea, because `Ak` has the same size of the original matrix, and this does not buy me anything. A possible alternative is

`w = U[:,1:k] * Diagonal(S[1:k]) * V[:,1:k]' * z`

Of course, one can also write a specific for loop that accomplishes that. I am interested in knowing if there are off-the-shelves solutions for this (that use the SVD object created by `svd`), and if you see ways to write the most efficient

1 Like

Thanks @mohamed82008. I could not find in the documentation of the package LowRankApprox.jl how to quickly perform matrix-vector multiplies (which is separate from factorizing the matrix).

It’s already defined under the hood if you call `*` or `mul!` on the output. LowRankApprox.jl/src/psvd.jl at master · JuliaLinearAlgebra/LowRankApprox.jl · GitHub

2 Likes

Thank you, this was very helpful

This won’t do what you want because `*` is left-associative in Julia: it is equivalent to `((U[:,1:k] * Diagonal(S[1:k])) * V[:,1:k]') * z`, which still forms the full matrix. You want:

``````w = U[:,1:k] * (Diagonal(S[1:k]) * (V[:,1:k]' * z))
``````

or (to avoid allocating slices):

``````@views w = U[:,1:k] * (Diagonal(S[1:k]) * (V[:,1:k]' * z))
``````

or to perform the diagonal multiplication in-place:

``````@views w = U[:,1:k] * lmul!(Diagonal(S[1:k]), V[:,1:k]' * z)
``````
2 Likes

This is great advice, thank you so much!