2017-01-21 1 views
1

줄리아에서 행렬 크기를 조정하는 효과적인 방법을 생각해 내고 있습니다. 이 행렬은 일부 메소드 내부의 Jacobian에 대한 내부 캐시로 사용되기 때문에 값을 임의의 순서로 유지할 필요가 없습니다 (즉시 덮어 쓰게됩니다). 나는 직접적으로 벡터를 생성하고 그 벡터의 reshape'd 뷰인 행렬로 작업하는 것에 대해 생각하고 있었다. 그러나 줄리아는 resize!에서 블록 나 벡터 보내고 :행렬 크기 조정

Jvec = zeros(9) 
J = reshape(Jvec,3,3)) 
resize!(Jvec,16) 


cannot resize array with shared data 
in resize!(::Array{Float64,1}, ::Int64) at ./array.jl:512 
in include_string(::String, ::String) at ./loading.jl:441 
in eval(::Module, ::Any) at ./boot.jl:234 
in (::Atom.##67#70)() at /home/crackauc/.julia/v0.5/Atom/src/eval.jl:40 
in withpath(::Atom.##67#70, ::Void) at /home/crackauc/.julia/v0.5/CodeTools/src/utils.jl:30 
in withpath(::Function, ::Void) at /home/crackauc/.julia/v0.5/Atom/src/eval.jl:46 
in macro expansion at /home/crackauc/.julia/v0.5/Atom/src/eval.jl:109 [inlined] 
in (::Atom.##66#69)() at ./task.jl:60 

을도 (단지 이후에 새로운 뷰를 작성하는 희망) 사라 볼 수있는 벡터 나에게 resize! 못하게 :

J = 0 
resize!(Jvec,16) 

cannot resize array with shared data 
in resize!(::Array{Float64,1}, ::Int64) at ./array.jl:512 
in include_string(::String, ::String) at ./loading.jl:441 
in eval(::Module, ::Any) at ./boot.jl:234 
in (::Atom.##67#70)() at /home/crackauc/.julia/v0.5/Atom/src/eval.jl:40 
in withpath(::Atom.##67#70, ::Void) at /home/crackauc/.julia/v0.5/CodeTools/src/utils.jl:30 
in withpath(::Function, ::Void) at /home/crackauc/.julia/v0.5/Atom/src/eval.jl:46 
in macro expansion at /home/crackauc/.julia/v0.5/Atom/src/eval.jl:109 [inlined] 
in (::Atom.##66#69)() at ./task.jl:60 

매번 매트릭스를 완전히 다시 할당하지 않고이를 수행하는 방법에 대한 통찰력이 도움이됩니다. 미리 감사드립니다.

+0

왜 새 매트릭스를 할당 할 수 없습니까? 크기를 조정하면 무엇을 얻을 수 있습니까? –

+0

작은 매트릭스로 크기를 조정하면 다시 할당 할 필요가 없습니다. 크기를 조정하면 벡터처럼 상각되어야합니다. 그것은 반복적으로 그렇게한다면 훨씬 더 빨라질 것입니다. –

+0

조금 더 자세하게 설명하면,'ForwardDiff.jacobian! '을 통해로드 된 다음 \ 조작에 사용됩니다. 그게 전부 야. 나는 [소스의이 페이지에서] (https://github.com/JuliaDiff/ForwardDiff.jl/blob/master/src/jacobian.jl) 효율적으로 색인을 생성 할 필요가 있다는 것을 알 수있다. 비록 잘 작동하는지에 대해서는 잘 모르겠다. –

답변

5

당신은 다소 위험 지역 (즉, 경고 이유가있다)에 속하고, 대신 reshape(Jvec, 3, 3)를 호출하면

J = Base.ReshapedArray(Jvec,(3,3),()) 

을 할 경우 희망대로 그것은 작동 할 수 있습니다.

+0

작동하는 것처럼 보입니다. "너는 다소 위험한 지역을 밟고있다." 위험은 흥미로운 것 같습니다. –

3
julia> J = rand(3,3); 

julia> Jvec = vec(J); 

julia> resize!(Jvec, 4*4); 

julia> J = reshape(Jvec, (4,4)); 

julia> Jvec = vec(J); 

julia> resize!(Jvec, 5*5); 

julia> J = reshape(Jvec, (5,5)) 

등이 작동합니다.

+0

새로운'J'를 생성하기 전에'Jvec'의 값을 변경하면 새로운 벡터가 생성 된 것을 볼 수 있습니다. 값을 복사했기 때문에 그랬던 것처럼 보이지만'J'와'Jvec' 사이의 링크가 깨져서 아마도 내 솔루션에서 문제를 막을 수있을 것입니다. –

관련 문제