ベクトルや行列の作り方

In [1]:
using LinearAlgebra: I

1次元配列=縦ベクトル=ベクトル

  • コンマは「単に並べる」というニュアンス.
  • セミコロンと改行は「縦に並べる」というニュアンス.

Julia言語では「単に数値を並べただけの1次元配列」は「数値を縦に並べてできる縦ベクトル」とみなされる.

したがって, 以下の3つは全部縦ベクトルになる. 以下では縦ベクトルを単にベクトルと呼ぶ.

In [2]:
v = [1,2,3]
Out[2]:
3-element Array{Int64,1}:
 1
 2
 3
In [3]:
v = [1;2;3]
Out[3]:
3-element Array{Int64,1}:
 1
 2
 3
In [4]:
v = [
    1
    2
    3
]
Out[4]:
3-element Array{Int64,1}:
 1
 2
 3

1×n行列とは異なる双対ベクトルの作り方

  • 空白は「横に並べる」というニュアンス.

次は1×3行列(2次元配列)になる. この節の目標はこれの説明ではない.

In [5]:
f = [2 3 -1]
Out[5]:
1×3 Array{Int64,2}:
 2  3  -1

1×3行列(1×3の2次元配列)と3次元ベクトル(長さ3の1次元配列)の積は1次元ベクトル(長さ1の1次元配列)になる.

In [6]:
f*v
Out[6]:
1-element Array{Int64,1}:
 5

スカラーを得るにはこうする.

In [7]:
(f*v)[1]
Out[7]:
5

これは非常に面倒である. 以下のようにすればこのような手間がいらなくなる.

次は3次元双対ベクトルになる. (双対ベクトルは双対空間の要素=線形汎函数という意味. 教科書ではよく横ベクトル表記される.)

In [8]:
g = transpose([2, 3, -1])
Out[8]:
1×3 LinearAlgebra.Transpose{Int64,Array{Int64,1}}:
 2  3  -1

(双対ベクトル)*(ベクトル)はスカラーになる. 双対空間の概念が実装されているのはJulia言語の大きな特徴である.

In [9]:
g*v
Out[9]:
5

(ベクトル)*(双対ベクトル)は行列になる.

In [10]:
v*g
Out[10]:
3×3 Array{Int64,2}:
 2  3  -1
 4  6  -2
 6  9  -3

以下のようにして双対ベクトルを作ることもできる. こちらの方が書く分量が減る.

In [11]:
h = [2,3,-1]'
Out[11]:
1×3 LinearAlgebra.Adjoint{Int64,Array{Int64,1}}:
 2  3  -1
In [12]:
h*v
Out[12]:
5
In [13]:
v*h
Out[13]:
3×3 Array{Int64,2}:
 2  3  -1
 4  6  -2
 6  9  -3

ただし, ' は単に転置を取るだけではなく共役を取る操作も含まれている.

In [14]:
a = [1+2im, 3+4im]
Out[14]:
2-element Array{Complex{Int64},1}:
 1 + 2im
 3 + 4im
In [15]:
a'
Out[15]:
1×2 LinearAlgebra.Adjoint{Complex{Int64},Array{Complex{Int64},1}}:
 1-2im  3-4im

次のような場合には積を意味する*を省略できる.

In [16]:
a'a
Out[16]:
30 + 0im

単に共役を取るには次のようにする.

In [17]:
conj(a)
Out[17]:
2-element Array{Complex{Int64},1}:
 1 - 2im
 3 - 4im

実部と虚部は次の通り.

In [18]:
real(a)
Out[18]:
2-element Array{Int64,1}:
 1
 3
In [19]:
imag(a)
Out[19]:
2-element Array{Int64,1}:
 2
 4

行列の作り方

  • 空白は「横に並べる」という意味.
  • セミコロンは「縦に並べる」という意味.
  • LinearAlgebra.I は単位行列のように使える.
In [20]:
A = [1 2 3; 4 5 6; 7 8 9]
Out[20]:
3×3 Array{Int64,2}:
 1  2  3
 4  5  6
 7  8  9
In [21]:
A = [
    1 2 3
    4 5 6
    7 8 9
]
Out[21]:
3×3 Array{Int64,2}:
 1  2  3
 4  5  6
 7  8  9
In [22]:
A + 10I
Out[22]:
3×3 Array{Int64,2}:
 11   2   3
  4  15   6
  7   8  19
In [23]:
10I*v
Out[23]:
3-element Array{Int64,1}:
 10
 20
 30

(行列)*(ベクトル)はベクトルになる.

In [24]:
A*v
Out[24]:
3-element Array{Int64,1}:
 14
 32
 50

(双対ベクトル)*(行列)は双対ベクトルになる.

In [25]:
g*A
Out[25]:
1×3 LinearAlgebra.Transpose{Int64,Array{Int64,1}}:
 7  11  15
In [26]:
h*A
Out[26]:
1×3 LinearAlgebra.Adjoint{Int64,Array{Int64,1}}:
 7  11  15

(双対ベクトル)*(行列)*(ベクトル)はスカラーになる. (1×1行列になったりしない)

In [27]:
g*A*v
Out[27]:
74
In [28]:
h*A*v
Out[28]:
74

dot-syntaxで行列を作る方法

In [29]:
x = 1:4
Out[29]:
1:4
In [30]:
y = 1:3
Out[30]:
1:3

(縦ベクトル) .+ (横(双対)ベクトル) の形式で行列を作ることもできる.

In [31]:
x .+ im*y'
Out[31]:
4×3 Array{Complex{Int64},2}:
 1+1im  1+2im  1+3im
 2+1im  2+2im  2+3im
 3+1im  3+2im  3+3im
 4+1im  4+2im  4+3im

より一般に φ.(x, y') の形式で行列を作ることができる.

In [32]:
φ(x, y) = x^2 + im*y
φ.(x, y')
Out[32]:
4×3 Array{Complex{Int64},2}:
  1+1im   1+2im   1+3im
  4+1im   4+2im   4+3im
  9+1im   9+2im   9+3im
 16+1im  16+2im  16+3im

行列の連結

  • 空白は「横に並べる」という意味
  • セミコロンと改行は「縦に並べる」という意味
In [33]:
[
    A v
    g 0
]
Out[33]:
4×4 Array{Int64,2}:
 1  2   3  1
 4  5   6  2
 7  8   9  3
 2  3  -1  0
In [34]:
P = [11 12; 13 14]
Out[34]:
2×2 Array{Int64,2}:
 11  12
 13  14
In [35]:
Q = [21 22; 23 24]
Out[35]:
2×2 Array{Int64,2}:
 21  22
 23  24
In [36]:
R = [31 32; 33 34]
Out[36]:
2×2 Array{Int64,2}:
 31  32
 33  34
In [37]:
S = [41 42; 43 44]
Out[37]:
2×2 Array{Int64,2}:
 41  42
 43  44
In [38]:
T = [P Q; R S]
Out[38]:
4×4 Array{Int64,2}:
 11  12  21  22
 13  14  23  24
 31  32  41  42
 33  34  43  44

セミコロンのcollectとしての使い方

1:3 はベクトル=1次元配列にはならない.

In [39]:
1:3
Out[39]:
1:3
In [40]:
typeof(1:3)
Out[40]:
UnitRange{Int64}

1次元配列に変換するには以下のような方法がある.

In [41]:
Array(1:3)
Out[41]:
3-element Array{Int64,1}:
 1
 2
 3
In [42]:
Vector(1:3)
Out[42]:
3-element Array{Int64,1}:
 1
 2
 3
In [43]:
collect(1:3)
Out[43]:
3-element Array{Int64,1}:
 1
 2
 3
In [44]:
[1:3;]
Out[44]:
3-element Array{Int64,1}:
 1
 2
 3

セミコロンは次のような使い方もできる. (時間を逆戻しする動画を作るときに使われる.)

In [45]:
[1:5; 4:-1:1]
Out[45]:
9-element Array{Int64,1}:
 1
 2
 3
 4
 5
 4
 3
 2
 1

meshgrid

Julia言語の文化圏ではメモリ効率が悪いmeshgridは好かれていない.

どうしてもmeshgridを使いたければ以下のようにする.

In [46]:
x = range(1, 3, length=3)
Out[46]:
1.0:1.0:3.0
In [47]:
y = range(1, 4, length=4)
Out[47]:
1.0:1.0:4.0

repeatを使う方法

In [48]:
x_grid = repeat(x', length(y))
Out[48]:
4×3 Array{Float64,2}:
 1.0  2.0  3.0
 1.0  2.0  3.0
 1.0  2.0  3.0
 1.0  2.0  3.0
In [49]:
y_grid = repeat(y, 1, length(x))
Out[49]:
4×3 Array{Float64,2}:
 1.0  1.0  1.0
 2.0  2.0  2.0
 3.0  3.0  3.0
 4.0  4.0  4.0

複素数を経由する方法

In [50]:
z = @.(x' + im*y)
Out[50]:
4×3 Array{Complex{Float64},2}:
 1.0+1.0im  2.0+1.0im  3.0+1.0im
 1.0+2.0im  2.0+2.0im  3.0+2.0im
 1.0+3.0im  2.0+3.0im  3.0+3.0im
 1.0+4.0im  2.0+4.0im  3.0+4.0im
In [51]:
x_grid = real(z)
Out[51]:
4×3 Array{Float64,2}:
 1.0  2.0  3.0
 1.0  2.0  3.0
 1.0  2.0  3.0
 1.0  2.0  3.0
In [52]:
y_grid = imag(z)
Out[52]:
4×3 Array{Float64,2}:
 1.0  1.0  1.0
 2.0  2.0  2.0
 3.0  3.0  3.0
 4.0  4.0  4.0

meshgridは効率が悪い

In [53]:
ψ(x,y) = x^2 - y^2
Out[53]:
ψ (generic function with 1 method)

以下の2つの結果は同じになる. x_grid, y_gridを使っている側は無駄にコードを長くしていてかつ無駄にメモリを消費している.

In [54]:
ψ.(x_grid, y_grid)
Out[54]:
4×3 Array{Float64,2}:
   0.0    3.0   8.0
  -3.0    0.0   5.0
  -8.0   -5.0   0.0
 -15.0  -12.0  -7.0
In [55]:
ψ.(x', y)
Out[55]:
4×3 Array{Float64,2}:
   0.0    3.0   8.0
  -3.0    0.0   5.0
  -8.0   -5.0   0.0
 -15.0  -12.0  -7.0

初期化されたもしくはされていないベクトルや行列の作り方

初期化された配列の作り方

0を並べる.

In [56]:
O = zeros(2, 3)
Out[56]:
2×3 Array{Float64,2}:
 0.0  0.0  0.0
 0.0  0.0  0.0
In [57]:
O_int = zeros(Int, 2, 3)
Out[57]:
2×3 Array{Int64,2}:
 0  0  0
 0  0  0

1を並べる.

In [58]:
K = ones(2, 3)
Out[58]:
2×3 Array{Float64,2}:
 1.0  1.0  1.0
 1.0  1.0  1.0
In [59]:
K_int = ones(Int, 2, 3)
Out[59]:
2×3 Array{Int64,2}:
 1  1  1
 1  1  1

対角成分に1を並べ, 他は0にする.

In [60]:
E = Matrix{Int}(I, 3, 4)
Out[60]:
3×4 Array{Int64,2}:
 1  0  0  0
 0  1  0  0
 0  0  1  0

乱数で初期化.

In [61]:
r = rand(3) # 0~1の一様分布
Out[61]:
3-element Array{Float64,1}:
 0.13125773388044792
 0.25280252772597267
 0.577204341724449  
In [62]:
R = randn(3,3) # 標準正規分布乱数
Out[62]:
3×3 Array{Float64,2}:
 -0.571556  -0.0732707   1.83136  
 -0.300118  -1.54188    -0.0802414
 -0.295303  -0.998139    0.0670566

既存の行列と同じ型・同じサイズの零行列と単位行列.

In [63]:
zero(K)
Out[63]:
2×3 Array{Float64,2}:
 0.0  0.0  0.0
 0.0  0.0  0.0
In [64]:
one(R)
Out[64]:
3×3 Array{Float64,2}:
 1.0  0.0  0.0
 0.0  1.0  0.0
 0.0  0.0  1.0

初期化されていない配列の作り方

In [65]:
u = Array{Float64, 1}(undef, 3)
Out[65]:
3-element Array{Float64,1}:
 1.0736794302e-313
 3.0988588e-316   
 3.1004738e-316   
In [66]:
u = Vector{Float64}(undef, 3)
Out[66]:
3-element Array{Float64,1}:
 1.0737161768e-313 
 1.07371617365e-313
 3.0989157e-316    
In [67]:
X = Array{Float64, 2}(undef, 3, 4)
Out[67]:
3×4 Array{Float64,2}:
 3.58943e-316  3.58946e-316  0.0  0.0
 3.58943e-316  3.58949e-316  0.0  0.0
 3.58946e-316  3.58234e-316  0.0  0.0
In [68]:
X = Matrix{Float64}(undef, 3, 4)
Out[68]:
3×4 Array{Float64,2}:
 3.46142e-316  3.57871e-316  0.0  0.0
 1.07063e-313  3.46147e-316  0.0  0.0
 3.46142e-316  3.46135e-316  0.0  0.0

既存の配列と同じ型・同じサイズの初期化されていない入れる.

In [69]:
S = similar(K)
Out[69]:
2×3 Array{Float64,2}:
 5.55738e-316  3.09868e-316  5.54975e-316
 5.55743e-316  3.09886e-316  0.0         
In [ ]: