知っていて当たり前-10　行列

# 知っていて当たり前-10　行列

行列のもっとも簡単な定義法。


```julia
A = [1 2 3;
     4 5 6]
```




    2×3 Matrix{Int64}:
     1  2  3
     4  5  6



## 1.　行列のサイズ


```julia
row, col = size(A) # (行数, 列数) のタプルを返す
```




    (2, 3)



## 2.　各次元のサイズ


```julia
size(A, 1) # 行数
```




    2




```julia
size(A, 2) # 列数
```




    3



## 3.　全要素数


```julia
length(A)
```




    6



## 4.　次元数


```julia
ndims(A)
```




    2



## 5.　零行列


```julia
zeros(2, 3) # 型はデフォルトで Float64
```




    2×3 Matrix{Float64}:
     0.0  0.0  0.0
     0.0  0.0  0.0




```julia
zeros(Int, 2, 3) # 第 1 引数で型を指定できる
```




    2×3 Matrix{Int64}:
     0  0  0
     0  0  0



## 6.　1 行列


```julia
ones(2, 3)
```




    2×3 Matrix{Float64}:
     1.0  1.0  1.0
     1.0  1.0  1.0




```julia
ones(Bool, 2, 3)
```




    2×3 Matrix{Bool}:
     1  1  1
     1  1  1



## 7.　Bool 行列


```julia
trues(2,3)
```




    2×3 BitMatrix:
     1  1  1
     1  1  1




```julia
falses(2, 3)
```




    2×3 BitMatrix:
     0  0  0
     0  0  0



## 8.　すべて§同じ任意の要素を持つ行列 `fill()`


```julia
f0 = fill(5, 2, 3)
```




    2×3 Matrix{Int64}:
     5  5  5
     5  5  5



## 9.　既存の配列と型・次元数が同じ，初期化されていない配列 `similar()`


```julia
f2 = similar(f0) # Python の like
```




    2×3 Matrix{Int64}:
              0  4985017360  4985434720
     4985434720           0  4999865536




```julia
f3 = similar(f0, Float64) # 型を指定することもできる
```




    2×3 Matrix{Float64}:
     0.0           2.46293e-314  2.46313e-314
     2.46313e-314  0.0           2.46293e-314



## 10.　型・次元を指定した初期化されていない配列を定義する


```julia
Array{Float64}(undef, 2, 3)
```




    2×3 Matrix{Float64}:
     2.22963e-314  2.22963e-314  2.22963e-314
     2.22963e-314  2.22963e-314  2.22963e-314



## 11.　乱数配列


```julia
rand(2, 3) # 一様乱数
```




    2×3 Matrix{Float64}:
     0.462003  0.399307  0.421369
     0.152579  0.111431  0.657385




```julia
randn(2, 3) # 標準正規乱数
```




    2×3 Matrix{Float64}:
     -0.877612   0.859351  -1.2645
      1.20194   -0.281498   0.181104



## 12.　単位行列


```julia
using LinearAlgebra
Array{Int}(I, 3, 3)
```




    3×3 Matrix{Int64}:
     1  0  0
     0  1  0
     0  0  1



必ずしも正方行列である必要はない（Array と Matix は同義語）。


```julia
Matrix{Float64}(I, 3, 5)
```




    3×5 Matrix{Float64}:
     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




```julia
Matrix(Diagonal(ones(Int, 3)))
```




    3×3 Matrix{Int64}:
     1  0  0
     0  1  0
     0  0  1



## 13.　対角行列

### 13.1.　任意の要素を持つ対角行列の作成


```julia
using LinearAlgebra
diagm(0 => 1:3)
```




    3×3 Matrix{Int64}:
     1  0  0
     0  2  0
     0  0  3



### 13.2.　対角要素の上に任意の要素を持つ行列の作成


```julia
diagm(1 => 1:3)
```




    4×4 Matrix{Int64}:
     0  1  0  0
     0  0  2  0
     0  0  0  3
     0  0  0  0



### 13.3.　対角要素の下に任意の要素を持つ行列の作成


```julia
diagm(-1 => 1:3)
```




    4×4 Matrix{Int64}:
     0  0  0  0
     1  0  0  0
     0  2  0  0
     0  0  3  0



結果を切り詰めることもできる。


```julia
diagm(-1 => 1:3)[2:end, :]
```




    3×4 Matrix{Int64}:
     1  0  0  0
     0  2  0  0
     0  0  3  0



複数指定することができる


```julia
diagm(-1 => 1:3, 1 => [10, 20, 30, 40])
```




    5×5 Matrix{Int64}:
     0  10   0   0   0
     1   0  20   0   0
     0   2   0  30   0
     0   0   3   0  40
     0   0   0   0   0




```julia
Diagonal([1,2,3])
```




    3×3 Diagonal{Int64, Vector{Int64}}:
     1  ⋅  ⋅
     ⋅  2  ⋅
     ⋅  ⋅  3




```julia
Diagonal(ones(3))
```




    3×3 Diagonal{Float64, Vector{Float64}}:
     1.0   ⋅    ⋅ 
      ⋅   1.0   ⋅ 
      ⋅    ⋅   1.0




```julia
Diagonal(ones(Int, 3))
```




    3×3 Diagonal{Int64, Vector{Int64}}:
     1  ⋅  ⋅
     ⋅  1  ⋅
     ⋅  ⋅  1




```julia
### 13.4.　対角要素の取り出し
```


```julia
a = [1 2 3; 4 5 6; 7 8 9]
```




    3×3 Matrix{Int64}:
     1  2  3
     4  5  6
     7  8  9




```julia
using LinearAlgebra
diag(a)
```




    3-element Vector{Int64}:
     1
     5
     9



### 13.5.　対角の一つ上の要素の取り出し


```julia
diag(a, 1)
```




    2-element Vector{Int64}:
     2
     6



### 13.6.　対角の一つ下の要素の取り出し


```julia
diag(a, -1)
```




    2-element Vector{Int64}:
     4
     8



### 13.7.　行列の対角成分に代入


```julia
function diag!(a, b)
    n, m = size(a)
    [a[i, j] = b[i, j] for j=1:n, i=1:n if i == j]
end

a = [1 2 3; 4 5 6; 7 8 9]
b = [10 20 30; 40 50 60; 70 80 90]
diag!(a, b);
```


```julia
a
```




    3×3 Matrix{Int64}:
     10   2   3
      4  50   6
      7   8  90



## 14.　上三角要素，下三角要素の抽出


```julia
A = [3 2 1;
     2 4 1;
     1 1 5]
```




    3×3 Matrix{Int64}:
     3  2  1
     2  4  1
     1  1  5



### 14.1.　対角成分を含む下三角要素をベクトルにして取り出す


```julia
using LinearAlgebra
A[tril(trues(size(A)))]
```




    6-element Vector{Int64}:
     3
     2
     1
     4
     1
     5



### 14.2.　対角成分の k 下の三角要素をベクトルにして取り出す


```julia
tril(trues(size(A)), -1)
```




    3×3 BitMatrix:
     0  0  0
     1  0  0
     1  1  0




```julia
triu(trues(size(A)), 2)
```




    3×3 BitMatrix:
     0  0  1
     0  0  0
     0  0  0




```julia
A[tril(trues(size(A)), -1)]
```




    3-element Vector{Int64}:
     2
     1
     1



### 14.3.　対角成分を含む上三角要素をベクトルにして取り出す


```julia
A[triu(trues(size(A)))]
```




    6-element Vector{Int64}:
     3
     2
     4
     1
     1
     5



### 14.4.　下三角行列


```julia
a = [1 2 3; 4 5 6; 7 8 9]
```




    3×3 Matrix{Int64}:
     1  2  3
     4  5  6
     7  8  9



### 14.5.　下三角行列を取り出す


```julia
using LinearAlgebra
LowerTriangular(a)　# using LinearAlgebra
```




    3×3 LowerTriangular{Int64, Matrix{Int64}}:
     1  ⋅  ⋅
     4  5  ⋅
     7  8  9



### 14.6.　下三角行列へ代入


```julia
function lowertri!(a, b)
    n, m = size(a)
    [a[i, j] = b[i, j] for j=1:n, i=1:n if i > j]
end
```




    lowertri! (generic function with 1 method)




```julia
a = [1 2 3; 4 5 6; 7 8 9]
b = [11 12 13; 14 15 16; 17 18 19]
lowertri!(a, b)
```




    3-element Vector{Int64}:
     14
     17
     18




```julia
a
```




    3×3 Matrix{Int64}:
      1   2  3
     14   5  6
     17  18  9



## 15.　転置


```julia
a = [1 2 3; 4 5 6; 7 8 9]
```




    3×3 Matrix{Int64}:
     1  2  3
     4  5  6
     7  8  9




```julia
a'
```




    3×3 adjoint(::Matrix{Int64}) with eltype Int64:
     1  4  7
     2  5  8
     3  6  9




```julia
transpose(a)
```




    3×3 transpose(::Matrix{Int64}) with eltype Int64:
     1  4  7
     2  5  8
     3  6  9



## 16.　回転 `rotr90()`, `rotl90()`


```julia
a = [1 2 3; 4 5 6]
```




    2×3 Matrix{Int64}:
     1  2  3
     4  5  6




```julia
rotr90(a)
```




    3×2 Matrix{Int64}:
     4  1
     5  2
     6  3




```julia
rotr90(rotr90(a))
```




    2×3 Matrix{Int64}:
     6  5  4
     3  2  1




```julia
rotr90(rotr90(rotr90(a)))
```




    3×2 Matrix{Int64}:
     3  6
     2  5
     1  4




```julia
rotr90(a, 3)
```




    3×2 Matrix{Int64}:
     3  6
     2  5
     1  4




```julia
rotl90(a)
```




    3×2 Matrix{Int64}:
     3  6
     2  5
     1  4



## 17.　回転シフト


```julia
a = [1 2 3; 4 5 6; 7 8 9];
circshift(a, (0, 1))
```




    3×3 Matrix{Int64}:
     3  1  2
     6  4  5
     9  7  8




```julia
circshift(a, 1)
```




    3×3 Matrix{Int64}:
     7  8  9
     1  2  3
     4  5  6



## 18.　ランク `rank()`


```julia
a = [1 2 3; 4 5 6; 7 8 9]
using LinearAlgebra
rank(a)
```




    2



## 19.　行列式 `det()`


```julia
using LinearAlgebra
det(a)
```




    0.0



トレース `tr()`


```julia
using LinearAlgebra
tr(a)
```




    15



クロネッカー積 `cron()`


```julia
a = [1 2 3
    4 5 6]
```




    2×3 Matrix{Int64}:
     1  2  3
     4  5  6




```julia
b = [1 2
     3 6
     7 11]
```




    3×2 Matrix{Int64}:
     1   2
     3   6
     7  11




```julia
kron(a, b)
```




    6×6 Matrix{Int64}:
      1   2   2   4   3   6
      3   6   6  12   9  18
      7  11  14  22  21  33
      4   8   5  10   6  12
     12  24  15  30  18  36
     28  44  35  55  42  66



## 20.　逆行列 `inv()`

逆行列を明示的に使うのは避けるべし。


```julia
a = [1.0 3.0 5.0; 6.0 8.0 3.0; 3.0 4.0 2.0]
```




    3×3 Matrix{Float64}:
     1.0  3.0  5.0
     6.0  8.0  3.0
     3.0  4.0  2.0




```julia
inv(a)
```




    3×3 Matrix{Float64}:
     -0.8  -2.8   6.2
      0.6   2.6  -5.4
      0.0  -1.0   2.0




```julia
inv(a) * a
```




    3×3 Matrix{Float64}:
     1.0  0.0  0.0
     0.0  1.0  0.0
     0.0  0.0  1.0



## 21.　連立一次方程式 A x = b


```julia
a = [1.0 3.0 5.0; 6.0 8.0 3.0; 3.0 4.0 2.0]
```




    3×3 Matrix{Float64}:
     1.0  3.0  5.0
     6.0  8.0  3.0
     3.0  4.0  2.0




```julia
b = [3.0, 4.0, 6.0]
```




    3-element Vector{Float64}:
     3.0
     4.0
     6.0




```julia
x = inv(a) * b
```




    3-element Vector{Float64}:
      23.599999999999994
     -20.2
       8.0




```julia
a * x # ==> b # 誤差が大きい
```




    3-element Vector{Float64}:
     3.0
     3.9999999999999716
     5.999999999999986




```julia
a \ b # ==> x = inv(a) * b
```




    3-element Vector{Float64}:
      23.599999999999998
     -20.2
       8.0




```julia
a * (a \ b) # 誤差が小さい（ない）
```




    3-element Vector{Float64}:
     3.0
     4.0
     6.0



## 22.　固有値 `eigen()`, `eigvals()`, `eigvecs()`


```julia
using LinearAlgebra
a = [3 1 5; 2 4 7; 4 2 9]
```




    3×3 Matrix{Int64}:
     3  1  5
     2  4  7
     4  2  9




```julia
F = eigen(a)
```




    Eigen{Float64, Float64, Matrix{Float64}, Vector{Float64}}
    values:
    3-element Vector{Float64}:
      0.5159445156361262
      2.3635607609987486
     13.120494723365105
    vectors:
    3×3 Matrix{Float64}:
     -0.723466   0.205599  -0.398121
     -0.512966  -0.964335  -0.611863
      0.462019   0.166697  -0.683464




```julia
F.values
```




    3-element Vector{Float64}:
      0.5159445156361262
      2.3635607609987486
     13.120494723365105




```julia
F.vectors
```




    3×3 Matrix{Float64}:
     -0.723466   0.205599  -0.398121
     -0.512966  -0.964335  -0.611863
      0.462019   0.166697  -0.683464




```julia
eigvals(a)
```




    3-element Vector{Float64}:
      0.5159445156361262
      2.3635607609987486
     13.120494723365105




```julia
eigvecs(a)
```




    3×3 Matrix{Float64}:
     -0.723466   0.205599  -0.398121
     -0.512966  -0.964335  -0.611863
      0.462019   0.166697  -0.683464



### 22.1.　固有値の大きい順に並べ替え `eigen(..., sortby=x-> -x)`


```julia
values, vectors = eigen(a, sortby=x-> -x)
```




    Eigen{Float64, Float64, Matrix{Float64}, Vector{Float64}}
    values:
    3-element Vector{Float64}:
     13.120494723365105
      2.3635607609987486
      0.5159445156361262
    vectors:
    3×3 Matrix{Float64}:
     -0.398121   0.205599  -0.723466
     -0.611863  -0.964335  -0.512966
     -0.683464   0.166697   0.462019



## 23.　ファクトライゼーション

### 23.1.　一般的な行列の場合の LU 分解 `factorize()`


```julia
a = [3 1; 2 4;]
F = factorize(a)
```




    LU{Float64, Tridiagonal{Float64, Vector{Float64}}}
    L factor:
    2×2 Matrix{Float64}:
     1.0       0.0
     0.666667  1.0
    U factor:
    2×2 Matrix{Float64}:
     3.0  1.0
     0.0  3.33333




```julia
F.L
```




    2×2 Matrix{Float64}:
     1.0       0.0
     0.666667  1.0




```julia
F.U
```




    2×2 Matrix{Float64}:
     3.0  1.0
     0.0  3.33333



### 23.2.　対称行列の場合


```julia
B = [1.5 2 -4; 2 -1 -3; -4 -3 5]
F = factorize(B)
```




    BunchKaufman{Float64, Matrix{Float64}}
    D factor:
    3×3 Tridiagonal{Float64, Vector{Float64}}:
     -1.64286   0.0   ⋅ 
      0.0      -2.8  0.0
       ⋅        0.0  5.0
    U factor:
    3×3 UnitUpperTriangular{Float64, Matrix{Float64}}:
     1.0  0.142857  -0.8
      ⋅   1.0       -0.6
      ⋅    ⋅         1.0
    permutation:
    3-element Vector{Int64}:
     1
     2
     3



### 23.3.　SVD 特異値分解 `svd()`


```julia
A = randn(3, 3)

using LinearAlgebra
U, S, V = svd(A)
```




    SVD{Float64, Float64, Matrix{Float64}}
    U factor:
    3×3 Matrix{Float64}:
     -0.859406  0.251244    0.445306
      0.462956  0.0127275   0.88629
      0.217007  0.96784    -0.127253
    singular values:
    3-element Vector{Float64}:
     1.9222248484987037
     1.4673307044588406
     0.1384747325066215
    Vt factor:
    3×3 Matrix{Float64}:
     -0.758379  -0.0276825   0.651225
     -0.629671   0.289311   -0.720981
      0.168448   0.956835    0.236839



### 23.4.　QR 分解 `qr()`


```julia
a = [3 1
     2 4]
qr(a)
```




    LinearAlgebra.QRCompactWY{Float64, Matrix{Float64}}
    Q factor:
    2×2 LinearAlgebra.QRCompactWYQ{Float64, Matrix{Float64}}:
     -0.83205  -0.5547
     -0.5547    0.83205
    R factor:
    2×2 Matrix{Float64}:
     -3.60555  -3.05085
      0.0       2.7735



### 23.5.　コレスキー分解 `cholesky()`


```julia
r = [1.000000  0.108015  0.227651
     0.108015  1.000000  0.232754
     0.227651  0.232754  1.000000];
cholesky(r)
```




    Cholesky{Float64, Matrix{Float64}}
    U factor:
    3×3 UpperTriangular{Float64, Matrix{Float64}}:
     1.0  0.108015  0.227651
      ⋅   0.994149  0.209389
      ⋅    ⋅        0.950963



## 24.　ベクトル・配列の連結 `cat()`, `vcat()`, `hcat()`


```julia
a = [1,2,3]
b = [10,20,30]
[a; b]
```




    6-element Vector{Int64}:
      1
      2
      3
     10
     20
     30




```julia
vcat(a, b)
```




    6-element Vector{Int64}:
      1
      2
      3
     10
     20
     30




```julia
cat(a, b, dims=1)
```




    6-element Vector{Int64}:
      1
      2
      3
     10
     20
     30




```julia
hcat(a, b)
```




    3×2 Matrix{Int64}:
     1  10
     2  20
     3  30




```julia
cat(a, b, dims=2)
```




    3×2 Matrix{Int64}:
     1  10
     2  20
     3  30




```julia
x = [1 2 3]
y = [4 5 6 7]
cat(x, y, dims=2)
```




    1×7 Matrix{Int64}:
     1  2  3  4  5  6  7



## 25.　ブロードキャストとベクトル化 `broadcast()`, `.`, `@.`


```julia
A = [1, 2, 3, 4, 5]
```




    5-element Vector{Int64}:
     1
     2
     3
     4
     5




```julia
B = [1 2; 3 4; 5 6; 7 8; 9 10]
```




    5×2 Matrix{Int64}:
     1   2
     3   4
     5   6
     7   8
     9  10




```julia
broadcast(+, A, B)
```




    5×2 Matrix{Int64}:
      2   3
      5   6
      8   9
     11  12
     14  15




```julia
A .+ B
```




    5×2 Matrix{Int64}:
      2   3
      5   6
      8   9
     11  12
     14  15




```julia
sqrt.(B)
```




    5×2 Matrix{Float64}:
     1.0      1.41421
     1.73205  2.0
     2.23607  2.44949
     2.64575  2.82843
     3.0      3.16228




```julia
@. sqrt(B) + A - 1.5
```




    5×2 Matrix{Float64}:
     0.5      0.914214
     2.23205  2.5
     3.73607  3.94949
     5.14575  5.32843
     6.5      6.66228




```julia
sqrt.(B) .+ A .- 1.5
```




    5×2 Matrix{Float64}:
     0.5      0.914214
     2.23205  2.5
     3.73607  3.94949
     5.14575  5.32843
     6.5      6.66228




```julia
## 26.　変換 `map()`
```


```julia
A = [1,2,3]
```




    3-element Vector{Int64}:
     1
     2
     3




```julia
map(x -> x^2, A)
```




    3-element Vector{Int64}:
     1
     4
     9




```julia
map(A) do x
    x^2
end
```




    3-element Vector{Int64}:
     1
     4
     9



## 27.　配列の要素を集約 `reduce()`


```julia
A = [1,2,3]
reduce(+, A)
```




    6




```julia
vars = rand(2, 3, 4)
reduce(+, vars, dims=3) # 3次元配列 n x n x k
```




    2×3×1 Array{Float64, 3}:
    [:, :, 1] =
     1.685    1.01614  1.66267
     1.01937  2.13548  2.28805



## 28.　フィルタリング `filter()`


```julia
A = [1, 2, 3, 4, 5]
```




    5-element Vector{Int64}:
     1
     2
     3
     4
     5




```julia
filter(x -> x >= 3, A) # 3 以上の要素を抽出(フィルタリング)
```




    3-element Vector{Int64}:
     3
     4
     5




```julia
A[A .>= 3]
```




    3-element Vector{Int64}:
     3
     4
     5




```julia
filter(isodd, A) # 奇数要素を抽出
```




    3-element Vector{Int64}:
     1
     3
     5




```julia
deleteat!(a, findall(isequal(4), a))
```




    3-element Vector{Int64}:
     1
     2
     3




```julia
filter!(x -> x != 4, a)
```




    3-element Vector{Int64}:
     1
     2
     3



## 29.　ベクトルを配列に `reshape()`


```julia
vec1 = collect(1:6);
```


```julia
reshape(vec1, 2, 3)
```




    2×3 Matrix{Int64}:
     1  3  5
     2  4  6




```julia
reshape(vec1, (2, 3))
```




    2×3 Matrix{Int64}:
     1  3  5
     2  4  6




```julia
reshape(vec1, 2, :)
```




    2×3 Matrix{Int64}:
     1  3  5
     2  4  6




```julia
reshape(vec1, 6, :)
```




    6×1 Matrix{Int64}:
     1
     2
     3
     4
     5
     6




```julia
println(vec1)
```

    [1, 2, 3, 4, 5, 6]


## 30.　行列をベクトルに `vec()`


```julia
A = rand(3, 3)
```




    3×3 Matrix{Float64}:
     0.960627    0.688843  0.763275
     0.00694129  0.208644  0.441623
     0.173624    0.105914  0.337504




```julia
vec(A)
```




    9-element Vector{Float64}:
     0.9606269419001202
     0.006941291910149472
     0.17362388161403652
     0.6888432524798611
     0.20864371904746726
     0.10591422370536252
     0.7632754965796475
     0.4416234649065267
     0.33750371867325635




```julia
A[:]
```




    9-element Vector{Float64}:
     0.9606269419001202
     0.006941291910149472
     0.17362388161403652
     0.6888432524798611
     0.20864371904746726
     0.10591422370536252
     0.7632754965796475
     0.4416234649065267
     0.33750371867325635