# Submatrix replacement error in a matrix

#1

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?

#2

Please report the exact error by copying and pasting an actual Julia session.

#3

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
``````

#4

There is no setindex! for ranges. The error suggests you to collect it as a regular array first then assign values.

#5

@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.
``````

#6

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 the`Vector` constructor or to `collect`.

#7

@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