cg的视图实现!在矩阵上

时间:2016-08-03 15:54:50

标签: matrix julia

我正在尝试使用cg!来自IterativeSolvers.jl的函数用于求解矩阵 - 矩阵线性系统,即AX = B用于A,X,B适当大小的矩阵。鉴于指数的工作方式,X[:,i]独立于除B[:,i]以外的所有指数,因此实际上归结为n个不同的线性解。在这种情况下,通过\直接求解可以自动工作,但像CG这样的迭代求解器则不然。我可以通过外部循环轻松完成此操作,但我无法使就地操作工作。现在,我的代码如下所示:

for j=1:size(u,2)
  u[freenode,j],ch = cg!(u[freenode,j],lhs,Dinv.*rhs(u,i)[:,j]) # Requires Vector, need to change rhs
end

给出了具有适当左手侧和右手侧的CG。但它不是就地的原因归结为这个抛出错误的简单例子:

using IterativeSolvers
y = view(ones(4,2),:,2)
A=rand(4,4)
cg!(y,A,view(zeros(4,2),:,2))

是:

ERROR: MethodError: no method matching init!
(::IterativeSolvers.KrylovSubspace{Float64,Array{Float64,2}}, ::SubArray{Float64,1,Array{Float64,2},Tuple{Colon,Int64},true})
Closest candidates are:
init!{T}(::IterativeSolvers.KrylovSubspace{T,OpT}, ::Array{T,1}) at C:\Users\Chris\.julia\v0.5\IterativeSolvers\src\krylov.jl:66
in #cg!#23 at C:\Users\Chris\.julia\v0.5\IterativeSolvers\src\cg.jl:7 [inlined]
in cg!(::SubArray{Float64,1,Array{Float64,2},Tuple{Colon,Int64},true}, ::Array{Float64,2}, ::SubArray{Float64,1,Array{Float64,2},Tuple{Colon,Int64},true}, ::Int64) at C:\Users\Chris\.julia\v0.5\IterativeSolvers\src\cg.jl:6 (repeats 2 times)

问题似乎不在于given the results of a previous SE question

2 个答案:

答案 0 :(得分:1)

我怀疑你是否能够避免分配,因为初始化!功能实现为

function init!{T}(K::KrylovSubspace{T}, v::Vector{T})
#    K.v = Vector{T}[all(v.==zero(T)) ? v : v/norm(v)]
    K.v = Vector{T}[copy(v)]
end

因此无论如何都有副本。不过,如果您希望此功能接受视图,则只需将Vector修改为AbstractVector即可。 (该功能非常简单,如果您不想修改包,您可以自己添加更通用的方法。)

答案 1 :(得分:0)

你是对的,它不是"视图"问题本身,问题似乎是init!方法似乎没有以一种可以接受视图的方式定义。 (即SubArray类型)。该错误表明"最接近的候选人是"

init!{T}(::IterativeSolvers.KrylovSubspace{T,OpT}, ::Array{T,1})

(即,没有SubArray的方法定义,仅适用于普通数组,并且它似乎没有可用的通用功能/基本情况)

如果您正在收集'首先是数组,然后按预期工作(大概):

julia> cg!( collect(y), A, view(zeros(4,2),:,2))
([0.0752658,-0.693794,0.330172,0.437474],IterativeSolvers.ConvergenceHistory{Float64,Array{Float64,1}}(false,0.0,5,[0.249856,0.392572,0.401496,0.463142]))

除了显然对你没用,因为你并没有按照预期的方式改变y

如果您打算将y作为一个视图保留到那一点,我唯一能看到它的方法就是暂时“破解”#39;它使用复合语句进入cg!内的正常数组:

cg!((y = collect(y); y),A,view(zeros(4,2),:,2))

但是,显然,此时它已不再是一个视图,因此您必须手动更新原始数组...