jieli-matrix/svd_lowrank

Low Rank SVD first implemented by Julia

Opened this issue · 0 comments

用Julia语言实现pytorch中的svd_lowrank算法

实现功能

数据结构

LowRankSVD (点击跳转代码完整实现)
用于返回LowRankSVD对象,对应filed为U, S, Vt对应julia svd的U, S, Vt

struct LowRankSVD{T,Tr,M<:AbstractArray{T}} <: Factorization{T}
    U::M
    S::Vector{Tr}
    Vt::M

待办实现:
矩阵SVD存储矩阵大部分信息,LowRankSVD可在后期实现求逆、求转置、求共轭、左乘或右乘等操作

函数

svd_lowrank
用于求解低秩SVD分解,返回LowRankSVD对象F,通过F.U, F.S, F.Vt获取因子

function svd_lowrank(A::AbstractArray{T}, l::Int64, niter::Int64 = 2, M::Union{AbstractArray{T}, Nothing} = nothing) where T

待办实现:
考虑加入断言,对可能的不恰当情形给出相关警告、错误信息提示

_svd_lowrank
基于算法5.1低秩SVD求解的改动实现
算法5.1关于低秩SVD分解的算法通俗易懂:首先用投影矩阵Q将低秩矩阵A投影到B上,再对B进行SVD求解;
我们知道,关于一个矩阵A的SVD求解需要求解$A^TA$的特征值与特征向量,因而我们希望这个求解规模尽可能小;所以对于低秩SVD问题,我们可以根据Q, A的size参数进行讨论,根据不同情形计算出对应的B,再进行B的SVD分解
具体而言:
设 size(A) = (m,n) size(Q) = (n,l)
当出现以下情形 计算B转置的SVD分解

  • 1 m < n (求解转置SVD使得特征值问题规模缩减)
  • 2 n > l (求解转置SVD使得V的规模缩减)
    其余情形
    计算B的SVD分解,为充分利用Julia的SVD,在进行矩阵计算时仍然计算B的转置Bt(n < l),根据惰性求值将transpose(Bt)传入SVD进行求解

待办实现:已完成基本测试(给定规模输入能够返回符合预期规模的输出),但需要进行更有说服力的测试(例如F.U * DDiagonal(F.S)*F.Vs与A的误差是否可接受?以及应构造低秩的A而非随机矩阵进行测试)

get_approximate_basis
基于算法4.4近似矩阵Q求解的实现
给定矩阵A 其规模为(m,n) 求解矩阵Q 其规模为(m,l) l是一个对A秩的估计,使得Q的张成空间尽可能逼近A的张成空间
这里的实现我有一些疑惑的地方,主要是How thinQR works in Julia
在参考的pytorch版本实现中,torch.linalg.qr默认模式为reduced,因而每一次返回thin QR with size (m,l)
在matlab中,通过qr(*,0)指定为thinQR分解
而Julia中,无论qr还是!qr,返回的Q因子均为QRCompactWY,size为(m,m)的完全正交阵;根据搜索,使用Matrix(F.Q)能够转换为thin QR形式,然而我并不清楚这里是否会存在性能瓶颈,理论而言,thinQR的计算量应更小;但是,如果不做转换,计算结果必然是错误的(因为size都无法match)

以上,所有实现均在dev分支src文件中,因为不涉及过于复杂的内容,所以参考pytorch版本与julia的svd实现,均放在一个文件中;本地对于LowRankSVD类型与所有的函数都进行了基本测试,之后仍需要更鲁棒的测试