■ 편미분 방정식을 사용해 빗방울을 시뮬레이션하는 방법을 보여준다.
▶ 예제 코드 (PY)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 |
import matplotlib.pyplot as pp import numpy as np import tensorflow as tf # 컨볼루션 커널을 구한다. # sourceList : 이중 리스트 def GetConvolutionKernel(sourceList): ndarray = np.asarray(sourceList) ndarray = ndarray.reshape(list(ndarray.shape) + [1, 1]) return tf.constant(ndarray, dtype = 1) # 단순 2D 컨볼루션 연산을 구한다. def GetSimplified2DConvolutionOperation(xVariable, kTensor): xTensor = tf.expand_dims(tf.expand_dims(xVariable, 0), -1) yTensor = tf.nn.depthwise_conv2d(xTensor, kTensor, [1, 1, 1, 1], padding = "SAME") return yTensor[0, :, :, 0] # 라플라스 변환을 계산한다. def ComputeLaplaceConversion(x): kTensor = GetConvolutionKernel([[0.5, 1.0, 0.5], [1.0, -6., 1.0], [0.5, 1.0, 0.5]]) return GetSimplified2DConvolutionOperation(x, kTensor) sess = tf.InteractiveSession() size = 500 # 초기 조건 -- 빗방울이 연못에 떨어진다. # 모두 0으로 설정한다. ndarray1 = np.zeros([size, size], dtype = np.float32) ndarray2 = np.zeros([size, size], dtype = np.float32) # 빗방울이 연못의 임의 지점에 떨어진다. for n in range(100): y, x = np.random.randint(0, size, 2) ndarray1[y, x] = np.random.uniform() pp.imshow(ndarray1) pp.show() # 매개 변수 : # eps -- 시간 해상도 # damping -- 물결 감쇠 eps = tf.placeholder(tf.float32, shape = ()) damping = tf.placeholder(tf.float32, shape = ()) # 시뮬레이션 상태를 위한 변수를 생성한다. variable1 = tf.Variable(ndarray1) variable2 = tf.Variable(ndarray2) # 이산화 편미분 방정식 업데이트 규칙을 설정한다. tensor1 = variable1 + eps * variable2 tensor2 = variable2 + eps * (ComputeLaplaceConversion(variable1) - damping * variable2) # 상태를 업데이트 하기 위한 연산을 설정한다. stepOperation = tf.group(variable1.assign(tensor1), variable2.assign(tensor2)) # 초기 조건에 대한 상태를 초기화 한다. tf.global_variables_initializer().run() # 편미분 방정식을 1000 단계 실행한다. for i in range(1000): stepOperation.run({ eps : 0.03, damping : 0.04 }) if i % 500 == 0: pp.imshow(variable1.eval()) pp.show() |