Unit matrix¶
In this script we will describe several ways to create unit matrices and show how to compare these matrices in terms of their memory footprint.
Task description¶
Create a matrix whose main diagonal is filled with units (the other elements are either zero or missing). Assume that such a matrix can be not only square, but ideally also multidimensional.
Using loops¶
A unit matrix can be created using loops as follows.
Pkg.add(["LinearAlgebra"])
n = 14
m = 11
eye = zeros( m, n )
for i in 1:n
if m < n
if i <= m
eye[i,i] = 1
end
else
eye[i,i] = 1
end
end
gr()
heatmap( eye, yflip=:true, c=:Reds )
Through a short cycle¶
Putting units along the main diagonal can be done in a compressed cycle.
eye_array = zeros( 5, 5 );
[eye_array[ i,i ] = 1 for i in 1:minimum( size(eye_array) )];
heatmap( eye_array, yflip=:true, c=:Purples )
This code can be adapted for the multidimensional case by using the function ndims
, which returns the number of dimensions of the original matrix, whose main diagonal we fill with units.
eye3D = zeros(5,4,3)
[eye3D[ repeat( [i], ndims(eye3D) )... ] = 1 for i in 1:minimum( size(eye3D) )];
display( eye3D )
But this custom code will quickly become difficult to maintain if the system requirements grow. It is better to use additional libraries, especially since they are also built into the Engee environment.
LinearAlgebra libraries: object I
¶
The most economical way to create such a matrix is to use the command I
.
using LinearAlgebra
I
This object occupies very little memory, behaves like a unit matrix, can be dominated by any object, and can be converted to a matrix using the Matrix()
command.
Matrix( 5I, 3, 3)
Create a rectangular matrix of Boolean type numbers with units on the main diagonal:
Matrix{Bool}(I, 4, 10)
Create, for comparison, a unit matrix of size 5 by 5.
eye_I = Matrix{Bool}(I, 5, 5)
LinearAlgebra library: command Diagonal
¶
Another interesting way is provided by the function Diagonal
. It can be used to position a vector along the main diagonal of a square matrix. Other elements are not stored in memory, the matrix is displayed as a sparse array (SparseArray
).
using LinearAlgebra
eye_Diagonal = Diagonal( repeat([1], 5) )
LinearAlgebra library: function diagm
¶
Another function allows you to position vectors along any diagonal of a matrix, not just the main diagonal.
eye_diagm = diagm( 0 => repeat([1], 5) )
Let's visualise this matrix:
heatmap( diagm( 0 => repeat([1], 5), 3=>repeat([1], 5) ), yflip=:true, c=:Blues )
SparseArrays Library¶
You can construct a unit sparse matrix directly using the library SparseArrays
as follows:
using SparseArrays: spdiagm
eye_spdiagm = spdiagm(0 => repeat([1], 5))
Such a matrix can also be visualised without any problems.
heatmap( eye_spdiagm, yflip=:true, c=:Greens )
But, as we will see, it occupies more memory than all previous variants.
varinfo( r"eye_array|eye_I|eye_Diagonal|eye_diagm|eye_spdiagm" )
Conclusion¶
We have compared several ways of creating unit matrices. The matrix created using the standard object I
.