# Similar identity matrix

What is the idiomatic way to construct a full m×m or n×n identity matrix similar to a given m×n matrix A (static or not)?

`one(A*A')` or `one(A'*A)` does the trick but is of course not what I want.

Do you really need one? Can’t you just sidestep the question with `LinearAlgebra.I`?

Yes, it is the initial value of a matrix-valued ODE and should be of the same type as later values.

One way is

``````julia> using LinearAlgebra

julia> A = rand(4,5);

julia> diagm(0=>fill(1., size(A,1)))
4×4 Array{Float64,2}:
1.0  0.0  0.0  0.0
0.0  1.0  0.0  0.0
0.0  0.0  1.0  0.0
0.0  0.0  0.0  1.0

julia> diagm(0=>fill(1., size(A,2)))
5×5 Array{Float64,2}:
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
0.0  0.0  0.0  0.0  1.0
``````

or even `diagm(0=>fill(one(eltype(A)), size(A,1)))`.

Note that in Julia 0.6 you could do

``````julia> eye(size(A,1))
4×4 Array{Float64,2}:
1.0  0.0  0.0  0.0
0.0  1.0  0.0  0.0
0.0  0.0  1.0  0.0
0.0  0.0  0.0  1.0

julia> eye(size(A,2))
5×5 Array{Float64,2}:
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
0.0  0.0  0.0  0.0  1.0
``````

Another way would be `Matrix(one(eltype(A))I, size(A,1), size(A,1))` I guess.

Thank you, that’s it (almost)!

``````julia> A
5×4 Array{Float64,2}:
0.896177   0.0597406  0.611605   0.231433
0.119473   0.998269   0.0299731  0.947813
0.0465002  0.431471   0.321885   0.20422
0.641878   0.0221313  0.0604966  0.517904
0.958566   0.675325   0.0570553  0.603291

julia> typeof(A)(one(eltype(A))I, size(A,1), size(A,1))
5×5 Array{Float64,2}:
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
0.0  0.0  0.0  0.0  1.0
``````

Oh, I see.

For static arrays it is unfortunately slightly different

``````julia> similar_type(B, Size(size(B,1),size(B,1)))(I)
5×5 SArray{Tuple{5,5},Float64,2,25}:
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
0.0  0.0  0.0  0.0  1.0
``````
``````julia> using LinearAlgebra

julia> A = rand(5,4);

julia> copyto!(similar(A, size(A,1), size(A,1)), I)
5×5 Array{Float64,2}:
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
0.0  0.0  0.0  0.0  1.0
``````
1 Like

I don’t think this works for static matrixes:

``````julia> using LinearAlgebra, StaticArrays
julia> A = @SMatrix rand(5,4);
julia> typeof(copyto!(similar(A, size(A,1), size(A,1)), I))
Array{Float64,2}
``````

because the generic `copyto!` is used.

This is could be a bug in `StaticArrays`, but at the same time I suspect that the design of the library which needs this could be improved, well-designed Julia code should either not require tricks like this, or provide helper functions for it.

For this use-case it would be nice provide a second argument like `Val(:Left)` to `one` which allows to specify to take the left or a right multiplicative unit if they are not equal.

1 Like