Summary

오일러 공식과 복소수에 대한 기본 내용을 복습한다.

오일러 공식: \(e^{2 \pi i} = cos(\theta) + i sin(\theta)\)

library(stats)

# =============================================================
# Euler 공식 확인
# e^(i theta) = cos(theta) + i sin(theta)
# 각도가 45도일 경우
exp(1i * 2*pi / 8)  #  0.7071068+0.7071068i
## [1] 0.7071068+0.7071068i
cos(2*pi / 8) + 1i * sin(2*pi / 8) #  0.7071068+0.7071068i
## [1] 0.7071068+0.7071068i

복소수의 실수부와 허수부 확인

z = 2+3i
Re(z) # 2, 실수부
## [1] 2
Im(z) # 3, 허수부 
## [1] 3

복소수의 절대값 확인

# 복소수의 절대값 = modulus, 확인하는 방법 3가지, Mod, abs, sqrt
Mod(z) # 3.605551
## [1] 3.605551
abs(z) # 3.605551
## [1] 3.605551
sqrt(Re(z)^2 + Im(z)^2) # root(2^2 + 3^2)
## [1] 3.605551

각도 확인

# 각도 
Arg(z) # 0.9827937
## [1] 0.9827937
Arg(z) * 360 / (2*pi) # 56.3도
## [1] 56.30993

컬려복소수 각도 및 그래프 확인

# 켤레 복소수
Conj(z) # 2-3i
## [1] 2-3i
exp(2*pi*1i) # 각도 0도
## [1] 1-0i
exp(2*pi*1i / 8) # 각도 45도 
## [1] 0.7071068+0.7071068i
exp(2*pi*1i / 4) # 각도 90도 = pi/2
## [1] 0+1i
exp(2*pi*1i / 2) # 각도 180도 = pi
## [1] -1+0i
exp(3*pi*1i / 2) # 각도 270도 = pi * 3/2
## [1] 0-1i
# 단위원의 반지름
abs(exp(2*pi*1i / 8)) # 1
## [1] 1
# complex number를 그래프로 그린다.
# e^(2pi i) => 단위원이다.
x <- seq(0, 1, by=0.001)
y <- exp(2*pi*x*1i)
plot(y, col='red')

# 0~1 사이에 10개의 구간을 만든다.
x <- seq(0, 1, length.out = 11)

Fourier Transform 내용을 확인

여기서는 F4 로 구성한다. 즉, W^4 = 1 이 되는 W를 정의하고, 4x4의 푸리에 행렬을 생성한다.

  • 주파수 계수벡터 c, 합성벡터 y 를 설정한다.
# F4 행렬 구성

# W^N 이 1이 되는 숫자 정의
N <- 4  
W <- exp(1i*2*pi / N)

# 컬럼벡터 4개 성분 정의
n <- c(0:(N-1))
n
## [1] 0 1 2 3
# 컬럼 벡터가 올바르게 생성되는지 확인한다.
c1 <- W^(n*0) # 첫번째 컬럼벡터
c1
## [1] 1+0i 1+0i 1+0i 1+0i
# F4 행렬을 생성한다. 모두 동일한 행렬을 생성한다.
# F4 <- matrix(c(1, 1, 1, 1,   1, 1i, -1, -1i,  1, -1, 1, -1,   1, -1i, -1, 1i), nrow=4)
# F4 <- matrix(c(W^(n*0), W^(n*1), W^(n*2), W^(n*3)), nrow=4)

F4 <- matrix(data = c(0), nrow=N, ncol=N)  # 빈 행렬 생성

# 컬럼 벡터를 하나씩 채움
# i: 컬럼 위치
# n: 벡터 연산으로 column 1의 4개 성분을 생성
# i-1 을 통해서 0, 1, 2, 3 거듭제곱을 적용
for(i in 1:N) {
  F4[,i] <- (W^(n*(i-1)))
}
F4
##      [,1]  [,2]  [,3]  [,4]
## [1,] 1+0i  1+0i  1+0i  1+0i
## [2,] 1+0i  0+1i -1+0i  0-1i
## [3,] 1+0i -1+0i  1-0i -1+0i
## [4,] 1+0i  0-1i -1+0i  0+1i
# F4의 켤레화돤 전치행렬을 구한다.
Conj(F4) # conjugate complex matrix
##      [,1]  [,2]  [,3]  [,4]
## [1,] 1+0i  1+0i  1+0i  1+0i
## [2,] 1+0i  0-1i -1-0i  0+1i
## [3,] 1+0i -1-0i  1+0i -1-0i
## [4,] 1+0i  0+1i -1-0i  0-1i
# F4와 F4* 를 곱했을때 단위행렬이 나옴을 확인한다. 여기서는 F4의 컬럼벡터 길이를 정규화하지 않았다.
# 벡터길이로 정규화한다면 4로 나누어준다.
round(1/N * Conj(F4) %*% F4, digits = 2) # check identity
##      [,1] [,2] [,3] [,4]
## [1,] 1+0i 0+0i 0+0i 0+0i
## [2,] 0+0i 1+0i 0+0i 0+0i
## [3,] 0+0i 0+0i 1+0i 0+0i
## [4,] 0+0i 0+0i 0+0i 1+0i

푸리에 행렬을 이용해서 간단하게 주파수 합성벡터와 계수 벡터를 구해보자.

  • F4: 푸리에 행렬
  • c: 주파수 계수 벡터, 여기서는 (1, 2주기의 계수값이 2와 3임)
  • y: 주파수 합성 벡터, 여기서는 소리에 대한 샘플링 진폭값이라고 생각하면 된다.

참고로 Fc 를 하는 것은 Discrete Fourier Transform 을 계산한다라고 표현하고, F’y 를 하는 것은 역변환을 계산한다라고 표현한다. 역변환을 통해서 소리로부터 어떤 주파수의 합성인지를 알 수 있게 된다.

c <- c(0, 2, 3, 0) # c: 푸리에 계수 벡터

# y = F4 * c
y <- as.vector(F4 %*% c) # y: synthesis values vector
y 
## [1]  5+0i -3+2i  1-0i -3-2i
F_ <- 1/N * Conj(F4)
#1/4*Conj(F4) %*% matrix(c(2, 0, -2, 0), nrow=4)
round(F_ %*% y, digits = 2) # F4의 역행렬을 y에 곱했을때 푸리에 계수 c 벡터가 나옴을 확인한다.
##      [,1]
## [1,] 0+0i
## [2,] 2+0i
## [3,] 3+0i
## [4,] 0+0i