본문 바로가기
Engineer/Juila

[Julia] 기본1 - 5. 행렬 가지고 놀기!

by _제이빈_ 2021. 10. 11.

링크의 내용을 공부하며 제멋대로 번역한 내용입니다.

 

일단 수치해석을 하려면 사용하는 언어의 행렬사용법을 찐하게 알고 있어야한다. 효율이 생명인데 행렬(어레이)자체를 비효율적으로 계산하고 있으면 도루묵이기 때문이다.

 

INITIALIZING ARRAYS 행렬정의!

 

직접 정의는 여느 프로그래밍언어와 비슷하다.

A = [1 2 3; 1 2 4; 2 2 2]
A = [1 2 3;
     1 2 4;
     2 2 2]

요런 식이다. 근데 백터랑 행렬이랑 좀 객체 유형이 달라진단다. 아래 예시를 보자

V1 = [4.0, 5, 6] 	# 3-element VECTOR (Float64)
V2 = [4.0; 5; 6]	# 3-element VECTOR (Float64)
M1 = [4.0  5  6]	# 1x3 Matrix(Float64)

콤마나 세미콜론으로 요소를 구분하면 백터 객체가 되고 띄어쓰기로 구분하면 행렬이 된다... 심지어는 스트링과 혼용도 된다.

A = ["Hello", 1, 2, 3]
  4-element Vector{Any}:
  "Hello"
  1
  2
  3

일단 메모링 할당에 있어서는 혼재되어 있으면 비효율적일거 같은데, 메트렙마냥 사용자 편의를 위해 이렇게 했을까... 궁금하다.


DECLARING ARRAYS 어레이 정의

 

직접 값을 입력해도 되지만, 메모리 할당/변수 정의만 하고 싶을 때가 있다. 이때는 각 변수타입에 맞춰 정의가능하다!

n=5
A1 = Array{Float64}(undef,n,n) 	# 5x5 Matrix{Float64}
A2 = Matrix{Float64}(undef,n,n)	# 5x5 Matrix{Float64}

V1 = Array{Float64}(undef,n)	# 5-elemet Vector{Float64}
V1 = Vector{Float64}(undef,n)	# 5-elemet Vector{Float64}

숫자가 아니어도 물론 가능하다! (그런데 이경우 메모리 할당이 어떻게 되는지는 잘 모르겠다... 특히 Any...)

A = Array{String}(undef,n)
A = Array{Any}(undef,n)

아무튼, 미리 메모리를 할당함으로서 프로그램효율을 높일 수 있는건 명확하다.

 


GENERATORS 제너레이터

 

줄리아에도 역시나 초기화와 함께 변수를 만드는 기법이 있다.

A = ones(8,9)
B = zeros(8,9)
C = rand(8,9)

모두 0이나, 1로 만들거ㅏ 랜덤한 값이 나오도록 할 수 있다. 게다가 LinearAlgebra 패키지를 쓰면 아래와 같은 연사도 된다;;;

using LinearAlgebra
M = 5I + rand(2,2)
 
 2x2 Matrix{Float64}
 5.50162	0.46280
 0.49828	5.30439

무려... I가 그냥 계산된다.... -쉣 (그나저나 rand가 정규분폰가;;; 0.5주변만 나오네)

 


ARRAY OPERATIONS 행렬 계산


SIZE

사이즈는 size로 확인가능하고 이를 행렬로 받아 사용할 수 있다. 

A = rand(6)
s = size(A)
print(s)
 >> (6,)
print(s[1])
 >> 6

size는 1차원이라해도 행렬로 입혀서 return된다. 그리고 s[1]로 읽어올 수 있는데, 이때 대괄호를 사용한다는 점과 1부터 시작한다는 점이 눈여겨 볼만 하다.

 

 

행렬간 곱셈 (MULTIPLICATION)

행렬간 곱셈도 매트랩마냥 쉽게 구현되어 있다.

A*B
A*V

행렬의 요소간 곱셈도 매트랩이랑 똑같다.

A .* B

 

 

 

내적(DOT PRODUCT)

내적도 함수로 존재한다.

v= rand(1000)
w= rand(1000)
z = dot(v,w)
z = v'w

이렇게 말이다. 작은따운표로도 가능하다.

 

 

행렬 추출 (EXTRACT / SLICE MATRIX)

어레이를 자르는 것도 쉽다.

A = rand(6,6)
>> 6×6 Matrix{Float64}: 
    0.52847   0.535908  0.480901   0.703078  0.368307   0.708693
    0.741406  0.272582  0.267023   0.570897  0.0053561  0.706605
    0.330002  0.185206  0.888953   0.11902   0.823877   0.747914
    0.686446  0.844786  0.857149   0.150496  0.378809   0.881996
    0.17372   0.963315  0.0669024  0.675752  0.488583   0.547338
    0.845284  0.155113  0.318695   0.150062  0.975404   0.555914
B = A[1:2:5,1:2:5]
>> 3×3 Matrix{Float64}:
    0.52847   0.480901   0.368307
    0.330002  0.888953   0.823877
    0.17372   0.0669024  0.488583

 

 

 

조건문으로 행렬 요소 뽑기 (LOGICAL INDEXING MATRIX)

불릿으로 인댁싱도 삽가능이다.

A = rand(6,6)
>> 6×6 Matrix{Float64}:
 0.858254  0.278916  0.22538   0.32892    0.477034  0.0383857
 0.720428  0.118352  0.345263  0.574909   0.404657  0.355226
 0.676294  0.374673  0.961371  0.0420078  0.644658  0.113941
 0.686696  0.182449  0.531876  0.572907   0.583949  0.477301
 0.67323   0.771258  0.860786  0.700091   0.53593   0.969439
 0.400889  0.929566  0.583907  0.769207   0.210993  0.867416

A[ A .< 0.5 ] .= 0
>>6×6 Matrix{Float64}:
 0.858254  0.0       0.0       0.0       0.0       0.0
 0.720428  0.0       0.0       0.574909  0.0       0.0
 0.676294  0.0       0.961371  0.0       0.644658  0.0
 0.686696  0.0       0.531876  0.572907  0.583949  0.0
 0.67323   0.771258  0.860786  0.700091  0.53593   0.969439
 0.0       0.929566  0.583907  0.769207  0.0       0.867416

 

 

 

역행렬(Inverse Matrix)

역행렬? 매트랩 저리가라다... (무슨 기법으로 얼마나 효율적으로 구하는진 모르겠다.) 정사각형 메트릭스같은 경우에는 선형방정식을 푸는거고 least sqarues solution을 찾는단다.

b1= [4.0, 5, 6]
b2= [4.0; 5; 6]
v1= [4.0 5 6]

x=A/b1
x=A/b2
x=A/m1  # Error occur

마지막에서야 백터랑 매트릭스 차이가 한번 힌트를 주는데... 백터만 여기엔 사용가능하단다;;; (왜이렇게 해놧을까?) 굳이? 백터라는 형식이 행렬1xN보다 더 효율적으로 만들어 졌나?)

 

 

행렬 요소 붙이기 때기 (MATRIX APPEND)

어레이는 크기가 줄었다 늘렸다 할 수 있다. 음 사용자 측면에서는 아주 좋다. Push 랑 Pop을 쓰면된단다.

A = Float64[] 	# A= Array{Float64}(undef,0) 과 같은 구문
push!(A, 4)		# 4라는 값을 A행렬 맨뒤에 추가
push!(A, 3) 	# 3이라는 값을 A행렬 맨뒤에 추가
v = pop!(A) 	# 마지막 수인 3을 A행렬에서 빼와 return시키고 A에서 3을 없앰

왜 이런 구문들이 생겼을까... pushfirst! popfirst!같이 앞에 추가하거나 없애는 구문도 있다. splice(A,i)나 deleteat(A,i)같이 특정 위치에서 수행하는 구문도 있다...

 

 

 

행렬이어붙이기는 cat / vcat / hcat 이 있다. 세로로, 가로로, 혹은 어떤 차원에서 이어 붙일지 정하면 된다.

A = [4 5 6]
B = [6 7 8]

M1 = vcat(A,B) 	# same with cat(A,B,dims=1)
>> 2×3 Matrix{Int64}:
 4  5  6
 6  7  8
 
M2 = hcat(A,B)	# same with cat(A,B,dims=2)
>> 1×6 Matrix{Int64}:
 4  5  6  6  7  8
 
M3 = cat(A,B,dims=3)
>> 1×3×2 Array{Int64, 3}:
[:, :, 1] =
 4  5  6

[:, :, 2] =
 6  7  8
반응형

댓글