# How to mutate values of matrix which by mutating its sub-matrix?

In the below, I building matrix `A` which consists of for sub-matrices `Y,A1,A2,A3`.I want the mutation on `A3` be applied automatically on `A` as well. How can I do that please?

``````
using BenchmarkTools, StaticArrays, LinearAlgebra, SparseArrays, .Threads

Y  = [1 2;3 4];
A1 = [5 6;7 8];
A2 = [11 22;33 44];
A3 = [0 0;0 0];

A = [Y A1; A2 A3]

A3 .= [1 1; 1 1];  # I want the change also be applied on A

A
``````

You either want a vector of matrices, i. e.:

``````julia> A3 = [0 0;0 0];

julia> A = [Y,A1,A2,A3];

julia> A3 .= [1 1; 1 1];  # I want the change also be applied on A

julia> A
4-element Vector{Matrix{Int64}}:
[1 2; 3 4]
[5 6; 7 8]
[11 22; 33 44]
[1 1; 1 1]
``````

Or you want to define the matrix and then its slices:

``````julia> A
4×4 Matrix{Int64}:
1   2  5  6
3   4  7  8
11  22  0  0
33  44  0  0

julia> A3 = @view(A[3:4,3:4])
2×2 view(::Matrix{Int64}, 3:4, 3:4) with eltype Int64:
0  0
0  0

julia> A3 .= 1
2×2 view(::Matrix{Int64}, 3:4, 3:4) with eltype Int64:
1  1
1  1

julia> A
4×4 Matrix{Int64}:
1   2  5  6
3   4  7  8
11  22  1  1
33  44  1  1
``````
3 Likes

Thank you very much!
If the first method is used, and I want to solve `x=A\b` I get the below error. Is there a way to solve it or just work with the second method you proposed?
where,

``````Y  = [1 2;3 4];
A1 = [5 6;7 8];
A2 = [11 22;33 44];
A3 = [5 5;5 5];
A = [Y,A1,A2,A3];
4-element Vector{Matrix{Int64}}:
[1 2; 3 4]
[5 6; 7 8]
[11 22; 33 44]
[5 5; 5 5]

julia> b=[1;1;1;1]
4-element Vector{Int64}:
1
1
1
1

julia> A\b
ERROR: MethodError: no method matching zero(::Type{Matrix{Int64}})

``````

Oh, yes, in the first one `A` is not a regular matrix, it is a vector of matrices, so `A\b` won’t work. I think you need something in the lines of the second case.

1 Like

Edit- I see lmiq gave the `view` solution already, I missed the second half

I think what you want is a collection of `view`s into `A`.

Once you combine `Y, A1, A2, A3` into `A`, `A` is now an entirely new `Matrix` without the references to `Y, A1, A2, A3`.

``````_Y = [1 2; 3 4];
_A1 = [5 6; 7 8];
_A2 = [11 22; 33 44];
_A3 = [0 0; 0 0];

A = [_Y _A1; _A2 _A3]
# 4×4 Matrix{Int64}:
#  1   2  5  6
#  3   4  7  8
# 11  22  0  0
# 33  44  0  0

Y = view(A, 1:2, 1:2)
A1 = view(A, 1:2, 3:4)
A2 = view(A, 3:4, 1:2)
A3 = view(A, 3:4, 3:4)

A3 .= 1

A
# 4x4 Matrix{Int64}:
#  1   2  5  6
#  3   4  7  8
# 11  22  1  1
# 33  44  1  1
``````
2 Likes

@lmiq @sbuercklin
Thank you very much!

I tried to implement your feedbacks on building a left-shifted matrix `A_shiftl` of `A`. So, when I mutate `A`, the `A_shiftl` will be mutated as well. However, I could not do that. Any help please here?
I have and I have which it elements

``````A = [1.0 5 0 0 0;0 1 0 0 0;0 0 1 0 0 ;0 0 0 1 0;0 0 0 0 1];
A_shiftl = [@view(A[:,2:end]) zeros(size(A,1))]
A[3,3] =5;
julia> A
5×5 Matrix{Float64}:
1.0  5.0  0.0  0.0  0.0
0.0  1.0  0.0  0.0  0.0
0.0  0.0  5.0  0.0  0.0
0.0  0.0  0.0  1.0  0.0
0.0  0.0  0.0  0.0  1.0

julia> A_shiftl  # It did not follow the change in A
5×5 Matrix{Float64}:
5.0  0.0  0.0  0.0  0.0
1.0  0.0  0.0  0.0  0.0
0.0  1.0  0.0  0.0  0.0
0.0  0.0  1.0  0.0  0.0
0.0  0.0  0.0  1.0  0.0
``````

No, that won’t work like that in general. It is better of you write functions that operate on the matrices as you want, given ranges and values.

1 Like

@lmiq @sbuercklin
When I am using @view with sparsematrix, the resulting one is not sparse like `Asp_r ` below. Any way to keep it sparse?

``````Asp = spzeros(5,6);
Asp[1,1] = 1.0;
Asp[1,2] = 5.0;
Asp[2,2] = 1.0;
Asp[3,3] = 1.0;
Asp[4,4] = 1.0;
Asp[5,5] = 1.0;
julia> Asp_r =@view(Asp[:,1:end-1])
5×5 view(::SparseMatrixCSC{Float64, Int64}, :, 1:5) with eltype Float64:
1.0  5.0  0.0  0.0  0.0
0.0  1.0  0.0  0.0  0.0
0.0  0.0  1.0  0.0  0.0
0.0  0.0  0.0  1.0  0.0
0.0  0.0  0.0  0.0  1.0
``````

It looks sparse to me, it just prints a `0.0` instead of `.` for the empty entries because of how `view`s print. You can check sparsity using `issparse`:

``````julia> issparse(Asp_r)
true
``````

I recommend looking at the `Views` section of the Julia manual here

1 Like

Thanks for your feedback.