In this below code there is a weird error message:
joja = [1 2 3; 4 5 6; 7 8 9]
joja[2:3,2:3] = [1 2; 3 4 ] # ok
joja2 = reshape(1:9,3,3)
joja2[2:3,2:3] = [1 2; 3 4 ] # error (reshaped array)
joja3 = copy(joja2)
joja3[2:3,2:3] = [1 2; 3 4 ] # ok
I know that reshaped array
is a different animal, but why it happens?
Please report the exact error by copying and pasting an actual Julia session.
Thanks for your feedback
The two lines that generates an error (in the middle) was
Julia >joja2 = reshape(1:9,3,3)
3×3 Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}:
1 4 7
2 5 8
3 6 9
Julia>joja2[2:3,2:3] = [1 2; 3 4 ]
ERROR: indexed assignment fails for a reshaped range; consider calling collect
Stacktrace:
[1] macro expansion at .\multidimensional.jl:558 [inlined]
[2] macro expansion at .\cartesian.jl:64 [inlined]
[3] macro expansion at .\multidimensional.jl:556 [inlined]
[4] _unsafe_setindex!(::IndexLinear, ::Base.ReshapedArray{Int64,2,UnitRange{Int
64},Tuple{}}, ::Array{Int64,2}, ::UnitRange{Int64}, ::UnitRange{Int64}) at .\mul
tidimensional.jl:549
[5] macro expansion at .\multidimensional.jl:541 [inlined]
[6] _setindex! at .\multidimensional.jl:537 [inlined]
[7] setindex!(::Base.ReshapedArray{Int64,2,UnitRange{Int64},Tuple{}}, ::Array{I
nt64,2}, ::UnitRange{Int64}, ::UnitRange{Int64}) at .\abstractarray.jl:968
A simular approach it’s ok, but uses pure array
instead reshaped array
Julia>joja = [1 2 3; 4 5 6; 7 8 9]
3×3 Array{Int64,2}:
1 2 3
4 5 6
7 8 9
Julia>joja[2:3,2:3] = [1 2; 3 4 ]
2×2 Array{Int64,2}:
1 2
3 4
There is no setindex! for ranges. The error suggests you to collect it as a regular array first then assign values.
@tomaklutfu, in that case is not a range, is a real array, because reshape
function get a range and convert it to an array in any shape.
However, it’s a little bit different from a declared array in the second piece of code. It’s a reshaped array (ReshapedArray
in the error message) so it generates an error, but it lacks logic!
Notice that there is no 3D ranges, but reshape
function produces 3D arrays:
vet = reshape(1:24,2,3,4)
println(vet[1,2,3]) # shows 15.
A reshaped range is not the same as a reshaped Array
. Ranges (even reshaped ones) are read-only. This is intentional language behavior. As the previous response suggests, you can first convert the range to a Vector
via a call to theVector
constructor or to collect
.
@Stephen_Vavasis, you are right! This reshaped range is read-only. I’ve got it. copy()
or collect()
do the job. Thanks for your explanation.
It’s pretty amazing so much power in a programming language.
The below code works!
Vals = [30 60; 45 30]
Dest = collect(reshape(1.:9.,3,3))
Dest[2:3,2:3] = sind.(Vals) .* cosd.(Vals)
Before submatrix assignment:
Julia> Dest
3×3 Array{Float64,2}:
1.0 4.0 7.0
2.0 5.0 8.0
3.0 6.0 9.0
After:
Julia> Dest
3×3 Array{Float64,2}:
1.0 4.0 7.0
2.0 0.433013 0.433013
3.0 0.5 0.433013