반응형

줄리아 Julia의 브로드캐스팅(broadcasting)에 대해 다룹니다. 

 

2023. 12. 09  최초 작성




다음 사이트를 참고하고 ChatGPT의 도움을 받았습니다. 

https://techytok.com/lesson-working-with-arrays/



Julia 개발 환경 구축은 다음 포스트를 참고하세요. 

 

Visual Studio Code 사용한 Julia 개발 환경만들기(Windows / Ubuntu / Macbook M1)

https://webnautes.tistory.com/2216 



Julia 강좌를 진행하고 있습니다.

 

Julia 강좌 1 - 변수와 데이터 타입

https://webnautes.tistory.com/2218 

 

Julia 강좌 2 - 함수, void function,  Optional positional arguments, Keyword arguments

https://webnautes.tistory.com/2220 

 

Julia 강좌 3 - 배열, 튜플, 딕셔너리

https://webnautes.tistory.com/2229 

 

Julia 강좌 4 - 제어문 if ... else, for, break, continue, while, enumerate

https://webnautes.tistory.com/2235 

 

Julia 강좌 5 - 브로드캐스팅(broadcasting)

https://webnautes.tistory.com/2240

 

Julia 강좌 6 - 변수 유효 범위( Variable Scope ) : 전역(global), 로컬(local)

https://webnautes.tistory.com/2247

 

Julia 강좌 7 - 모듈(module)

https://webnautes.tistory.com/2253 


Julia 강좌 8 - 타입(type)

https://webnautes.tistory.com/2260

 

Julia 강좌 9 - 패키지(package)

https://webnautes.tistory.com/2268 



줄리아는 루프가 C의 속도만큼 빠르기 때문에 벡터화된 코드를 작성할 필요가 없습니다. 인터프리터가 코드를 최적화된 기계어 코드로 직접 컴파일하여 컴퓨터에서 최대한 빠르게 실행됩니다. Julia 프로그래밍 언어에서는, 함수들이 컴파일되는 것 외에는, 모든 과정이 사용자에게 명확하게 보이도록 설계되어 있습니다.  C의 모든 함수가 C로 작성되는 것과 마찬가지로 Julia의 거의 모든 함수는 Julia로 작성됩니다.



배열을 사용한 연산

 

Julia는 기본적으로 수학에서 하는 것처럼 배열과 행렬에 대한 연산을 처리합니다.

 

두 배열의 크기가 올바르게 일치하지 않는 한 두 배열을 함께 곱할 수 없습니다.  예를 들어 한 배열이 행벡터라면 다른 배열은 같은 크기의 열벡터야 합니다. 이 경우 곱셈 순서에 따라 배열의 곱셈의 결과는 스칼라 또는 행렬이 됩니다.



Julia에서 열벡터(column vector)와 행벡터(row vector)를 다음처럼 정의합니다.

 

a = [1,2,3] # 열벡터

println(a)
# [1, 2, 3]
display(a)
# 3-element Vector{Int64}:
#  1
#  2
#  3
println()


b = [1 2 3] # 행벡터

println(b)
# [1 2 3]
display(b)
# 1×3 Matrix{Int64}:
#  1  2  3



열벡터끼리 곱할 수 없어 에러가 발생합니다. 

 

a = [1,2,3] # 열벡터
b = [4,5,6] # 열벡터

c = a*b

println(c)
display(c)

 

ERROR: LoadError: MethodError: no method matching *(::Vector{Int64}, ::Vector{Int64})

 

Closest candidates are:

  *(::Any, ::Any, !Matched::Any, !Matched::Any...)

   @ Base operators.jl:578

  *(!Matched::StridedMatrix{T}, ::StridedVector{S}) where {T<:Union{Float32, Float64, ComplexF32, ComplexF64}, S<:Real}

   @ LinearAlgebra /Applications/Julia-1.9.app/Contents/Resources/julia/share/julia/stdlib/v1.9/LinearAlgebra/src/matmul.jl:49

  *(::StridedVecOrMat, !Matched::LinearAlgebra.Adjoint{<:Any, <:LinearAlgebra.LQPackedQ})

   @ LinearAlgebra /Applications/Julia-1.9.app/Contents/Resources/julia/share/julia/stdlib/v1.9/LinearAlgebra/src/lq.jl:269

  ...

 

Stacktrace:

 [1] top-level scope

   @ ~/julia/hello.jl:4

in expression starting at /Users/webnautes/julia/hello.jl:4




열벡터와 같은 크기의 행벡터가 주어져야 배열간의 곱셈이 가능합니다. 이때 배열의 순서에 따라 배열의 곱셈의 결과 값이 달라집니다.  수학에서 사용하는 행렬의 곱셈과 동일하게 계산됩니다.

 

a = [1,2,3] # 열벡터
b = [4 5 6] # 행벡터

display(a)
# 3-element Vector{Int64}:
#  1
#  2
#  3
display(b)
# 1×3 Matrix{Int64}:
#  4  5  6
println()


c = a*b
println(c)
# [4 5 6; 8 10 12; 12 15 18]
display(c)
# 3×3 Matrix{Int64}:
#   4   5   6
#   8  10  12
#  12  15  18

println()


d = b*a
println(d)
# [32]
display(d)
# 1-element Vector{Int64}:
#  32




브로드캐스팅(Broadcasting)

브로드캐스팅이란 배열이나 행렬에 있는 각 요소에 대해 함수나 연산을 개별적으로 적용하는 과정을 말합니다. 즉, 이는 하나의 함수나 연산을 전체 배열이나 행렬의 모든 요소에 동시에 적용하는 것을 의미합니다. 



연산자에 대한 브로드캐스팅 표기법은 연산자 앞에 점 을 추가하는 방식으로 구성됩니다

 

  • 모든 요소에 2 더하기:  배열 A가 있을 때, A .+ 2는 배열 A의 모든 요소에 2를 더합니다.
  • 모든 요소에 특정 함수 적용하기: 제곱근 함수 sqrt가 주어졌을 때, sqrt.(A)는 sqrt 함수를 배열 A의 모든 요소에 적용합니다.



배열 A와 상수 b간에 더하는 예제 코드입니다.

 

A = [1, 2, 3]
b = 3

c = A.+b

println(c)
display(c)
# [4, 5, 6]
# 3-element Vector{Int64}:
#  4
#  5
#  6
#
# 배열 A의 모든 원소에 3을 더합니다.

println()


d = b.+A

println(d)
display(d)
# [4, 5, 6]
# 3-element Vector{Int64}:
#  4
#  5
#  6
#
# 곱하는 순서가 바뀌어도 결과는 동일합니다. 




배열 A의 모든 원소에 제곱근을 적용하는 예제코드입니다.

A = [1, 2, 3]

c = sqrt.(A)

println(c)
display(c)
# [1.0, 1.4142135623730951, 1.7320508075688772]
# 3-element Vector{Float64}:
#  1.0
#  1.4142135623730951
#  1.7320508075688772




1 x 3 크기의 행벡터와 3 x 3 크기의 행렬을 더하는 코드입니다. 배열의 크기가 다르기 때문에 브로드캐스팅으로 1 x 3 크기의 행벡터가  3 x 3 크기의 행렬로 변환된후 행렬의 덧셈이 계산됩니다.  

 

A = [1 1 1# 행백터
display(A)
# 1×3 Matrix{Int64}:
#  1  1  1


B = [1 1 1; 2 2 2; 3 3 3]
display(B)
# 3×3 Matrix{Int64}:
#  1  1  1
#  2  2  2
#  3  3  3


C = A .+ B
display(C)
# 3×3 Matrix{Int64}:
#  2  2  2
#  3  3  3
#  4  4  4




브로드캐스팅을 사용해 n차원 배열에 함수를 매핑할 수 있습니다. 이렇게 하면 for 루프를 작성하는 것과 똑같기 때문에 속도가 빨라지지는 않지만, 간결하다는 점이 유용합니다. 

 

배열에 sin 함수를 적용하는 예제코드입니다. 

 

A = [1 1 1; 2 2 2; 3 3 3]
display(A)
# 3×3 Matrix{Int64}:
#  1  1  1
#  2  2  2
#  3  3  3


C = sin.(A)
display(C)
# 3×3 Matrix{Float64}:
#  0.841471  0.841471  0.841471
#  0.909297  0.909297  0.909297
#  0.14112   0.14112   0.14112







반응형

문제 발생시 지나치지 마시고 댓글 남겨주시면 가능한 빨리 답장드립니다.

도움이 되셨다면 토스아이디로 후원해주세요.
https://toss.me/momo2024


제가 쓴 책도 한번 검토해보세요 ^^

+ Recent posts