Amro
September 15, 2022, 6:14pm
1
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
lmiq
September 15, 2022, 6:32pm
2
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
Amro
September 15, 2022, 6:57pm
3
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}})
lmiq
September 15, 2022, 7:15pm
4
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.
Edit- I see lmiq gave the view solution already, I missed the second half
I think what you want is a collection of views 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
Amro
September 15, 2022, 9:30pm
7
@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
lmiq
September 15, 2022, 9:45pm
8
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.
Amro
September 15, 2022, 10:13pm
10
@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 views print. You can check sparsity using issparse:
julia> issparse(Asp_r)
true
I recommend looking at the Views section of the Julia manual here
Amro
September 16, 2022, 2:36pm
12
Thanks for your feedback.