单位矩阵¶
在本脚本中,我们将介绍几种创建单元矩阵的方法,并展示如何比较这些矩阵的内存占用情况。
任务描述¶
创建一个矩阵,其主对角线上填满单位(其他元素要么为零,要么缺失)。假设这样的矩阵不仅可以是正方形的,最好还是多维的。
使用循环¶
单位矩阵可以通过循环创建,具体方法如下
In [ ]:
Pkg.add(["LinearAlgebra"])
In [ ]:
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
In [ ]:
gr()
heatmap( eye, yflip=:true, c=:Reds )
Out[0]:
通过一个短循环¶
沿着主对角线放置单元可以在压缩循环中完成。
In [ ]:
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 )
Out[0]:
通过使用函数ndims
,可以将此代码调整为多维情况,该函数返回原始矩阵的维数,我们在其主对角线上填入单位。
In [ ]:
eye3D = zeros(5,4,3)
[eye3D[ repeat( [i], ndims(eye3D) )... ] = 1 for i in 1:minimum( size(eye3D) )];
display( eye3D )
但如果系统需求增加,这种自定义代码很快就会变得难以维护。最好的办法是使用其他库,尤其是这些库也内置于Engee环境中。
线性代数库:对象I
¶
创建此类矩阵最经济的方法是使用I
命令。
In [ ]:
using LinearAlgebra
I
Out[0]:
该对象占用内存极少,行为类似单位矩阵,可被任何对象支配,并可使用Matrix()
命令转换为矩阵。
In [ ]:
Matrix( 5I, 3, 3)
Out[0]:
创建主对角线上有单位的布尔类型矩阵:
In [ ]:
Matrix{Bool}(I, 4, 10)
Out[0]:
创建一个大小为 5 x 5 的单位矩阵进行比较。
In [ ]:
eye_I = Matrix{Bool}(I, 5, 5)
Out[0]:
线性代数库: 命令Diagonal
¶
函数Diagonal
提供了另一种有趣的方法。该函数可用于沿正方形矩阵的主对角线定位矢量。其他元素不存储在内存中,矩阵显示为稀疏数组 (SparseArray
)。
In [ ]:
using LinearAlgebra
eye_Diagonal = Diagonal( repeat([1], 5) )
Out[0]:
线性代数库:函数diagm
¶
另一个函数允许您沿矩阵的任意对角线(而不仅仅是主对角线)定位向量。
In [ ]:
eye_diagm = diagm( 0 => repeat([1], 5) )
Out[0]:
让我们把这个矩阵形象化:
In [ ]:
heatmap( diagm( 0 => repeat([1], 5), 3=>repeat([1], 5) ), yflip=:true, c=:Blues )
Out[0]:
稀疏矩阵库¶
您可以使用SparseArrays
直接构建单位稀疏矩阵,具体方法如下:
In [ ]:
using SparseArrays: spdiagm
eye_spdiagm = spdiagm(0 => repeat([1], 5))
Out[0]:
这样的矩阵也可以被可视化,不会有任何问题。
In [ ]:
heatmap( eye_spdiagm, yflip=:true, c=:Greens )
Out[0]:
但是,正如我们将看到的,它比之前的所有变体占用更多内存。
In [ ]:
varinfo( r"eye_array|eye_I|eye_Diagonal|eye_diagm|eye_spdiagm" )
Out[0]:
结论¶
我们比较了几种创建单位矩阵的方法。使用标准对象创建的矩阵I
。