[작성자:] snowall

  • 자발적 대칭성 붕괴

    *내일 숙제 내는 사람들 베껴가기 없기.

    자발적 대칭성 붕괴(Spontaneous symmetry breaking)는 자연에서 흔히 일어나는 대칭성 붕괴 과정의 하나이다. 이것이 무엇인지 설명하기 위해서는 우선 대칭성을 이해해야 하고, 그 붕괴가 무엇을 의미하는지 알아야 한다. 그리고 그것이 자발적인 것과 그렇지 않은 것이 어떤 차이가 있는지 알아봐야 할 것이다.

    대칭성이란 일반적으로 변환에 대하여 변하지 않는 성질을 뜻한다. 물리학적으로는, 라그랑지안이나 해밀토니안 등 주어진 물리계를 설명하는 방정식이 변환을 작용하더라도 그 모양이 변하지 않는 것으로 정의한다. 그리고 물리계를 설명하는 라그랑지안에 대칭성이 있다면 그에 대응하는 보존량이 존재한다는 것이 알려져 있다. 실제로, 공간에 대한 이동이 물리 현상을 바꾸지 않는다는 사실(Space uniformity, translation symmetry)로부터 운동량 보존법칙이 성립하고, 보는 방향에 따라 물리 현상이 달라지지 않다는 사실(Rotation symmetry)으로부터 각운동량 보존법칙을 유도할 수 있다.

    대칭성 붕괴는 따라서 다루려는 물리계에 대한 해밀토니안이 변환에 대하여 대칭성을 갖지 못하는 경우에 나타난다. 가령, 수소원자를 설명하는 해밀토니안은 회전 연산자에 대하여 대칭적이다. 따라서 각운동량이 단일한 고유값으로 나타나며, 모든 각운동량에 대해 같은 에너지를 갖는 겹친 상태로 관찰된다. 그러나 수소원자가 강한 자기장 안에 들어가게 되면 해밀토니안이 더이상 회전에 대해 대칭적이지 않게 된다. 왜냐하면, 자기장과 수소원자의 각운동량이 상호작용하게 되는데, 이 상호작용에서 나타나는 에너지가 자기장과 각운동량이 서로 어느 방향을 향하고 있느냐에 따라 달라지기 때문이다. 따라서 이 경우 대칭성이 붕괴되고, 서로 겹쳐져 있던 상태들은 다른 에너지 상태로 분리되어 분광선에 나타나게 된다.

    물리계를 설명하는 해밀토니안이 본질적으로 공간에 대해 대칭성을 갖고 있는 경우더라도, 대칭적인 상태가 바닥상태가 아닐 수 있다. 가령, 강자성체의 경우 각각의 스핀 각운동량이 무작위적으로 배열된 상태보다 어떤 방향을 기준으로 동일하게 정렬된 상태가 더 낮은 에너지를 갖는다. 따라서, 이 경우 바닥상태는 대칭성이 깨진 상태이고 이 물리계는 대칭성이 깨진 상태에서 안정화된다. 이러한 현상은 우리 주변에서 흔히 발견할 수 있는데, 특히 가장 극적인 사례는 물질 입자의 질량을 만들어 내는 힉스 매커니즘이다.

    우리 우주를 기술하는 입자 물리학의 표준모형에서, 표준 모형을 그대로 적용하면 질량을 나타내는 항은 대칭성을 깨트리기 때문에 자연스럽게 도입되지 않는다. 여기에 힉스 입자와의 상호작용을 도입하면, 에너지가 높은 상태에서는 라그랑지안 자체의 대칭성을 깨트리지 않으면서 질량에 해당하는 항을 자연스럽게 유도할 수 있다. 즉, 힉스 입자의 진공기대값이 0이 아닌 유한한 값으로 수렴하면서 힉스 입자와 상호작용하는 모든 입자는 힉스 입자의 진공기대값에 결합상수를 곱한 크기만큼의 질량을 얻게 되는 것이다.


    자발적 대칭성 붕괴의 결과로 골드스톤 입자가 도입된다. 골드스톤 정리에 따르면, 연속 대칭성이 깨지는 경우 깨진 대칭성의 차원에 해당하는 골드스톤 입자가 나타나는데, 이는 대칭성이 깨지면서 해밀토니안이 대칭적이더라도 그 해밀토니안이 기술하는 물리계의 바닥상태가 대칭적이지 않기 때문이다. 대표적인 골드스톤 입자가 양성자와 중성자의 SU(2) 아이소스핀 대칭성의 붕괴에서 나타나는 파이온이다. (원래 골드스톤 입자는 질량이 없지만, 파이온은 질량을 갖고 있는데, 이건 어쨌든 사정이 있다. 이런 경우를 Pseudo-Goldstone boson이라 부른다.)

    이렇듯, 자발적 대칭성 붕괴 현상은 우리 우주의 곳곳에서 찾을 수 있으며, 물리를 이해하는데 매우 중요한 틀이다.

  • 수치해석2 – 상미분방정식

    2번이 왜 이제 올라오느냐도 역시 의미 없는 질문이다.


    # Elementary Numerical analysis 2

    # based on Python

    # (C) 2013. Keehwan Nam, Dept. of physics, KAIST.

    # snowall@gmail.com / snowall@kaist.ac.kr

    # Differential equation

    # 추천 참고자료: http://www.swarthmore.edu/NatSci/echeeve1/Ref/NumericInt/FrameNumInt.html

    # 미분방정식은 미분 변수가 1개인 상미분방정식(Ordinary differential equation:ODE)과 2개 이상인 편미분방정식(Partial differential equation:PDE)으로 나눠진다.

    # 일단 1개인 미방을 어떻게 푸는지 알아보자. 연립 미방은 아직 다루지 않고, 나중에 다룬다.

    # ODE는 선형 미방과 비선형 미방으로 나눠진다. 선형미방은 미방의 해가 두개 이상 있을 때, 두 해의 선형결합도 해가 되는 경우이다.

    # 즉, f1과 f2가 미방의 연산자 L에 대해서 L(f1)=L(f2)=0일 때 L(f1+f2)=0이 만족되는 경우이다. 물론 그 역을 선형 미방이라고 하지는 않는다.

    # 비선형 미방은 풀기 골치아프므로 일단 선형 미방을 어떻게 푸는지 알아보자.

    # 선형 미방은 다시 최대 차수인 도함수에 따라 n차 미방으로 구분된다. 즉, 가령 2차 도함수가 최대차수인 도함수라면 2차 미분방정식이 된다.

    # 1차 이상의 미분을 포함하는 고차 미분방정식은 여러개의 중간 변수를 도입하여 1차 연립 미분 방정식으로 간주할 수 있다. 따라서, 1차 미분방정식을 잘 풀 수 있다면 고차 미분방정식은 손쉽게 풀린다. 그러므로 1차 미방에 집중하자.

    # 1차 미분방정식을 이산화(discretize)하게 되면 차분방정식(difference dquation)이 된다. 차분방정식은 고등학교 때 배우는 계차수열의 한 형태이다.

    # 그럼, 이제 차분방정식을 풀어보자. 가장 간단하게, 오일러 풀이법이 있다.

    # 오일러 풀이법에서는 dy/dt + a*y(t) = f(t) 라는 문제를 풀게 된다. a는 값을 알고 있는 상수이고, f(t)는 이미 알고 있는 함수이다.

    # 오일러 풀이법은 정말 간단하다. 주어진 시간 t로부터 h만큼의 시간이 지난 후의 값인 y(t+h)를 다음과 같이 근사한다.

    # y(t+h)=y(t)+(dy/dt)h

    # 아주 간단한 1차 근사가 되겠다. 그럼, 이제 y(t+h)를 알았으니, 같은 방법으로 한번 더 계산하면 y(t+2h)도 알아낼 수 있다. 이 작업을 반복하면, y(t=t0)를 알고 있을 때 우리는 아주 많은 문제를 풀 수 있게 된다.

    # y(t+h) = y(t)+(dy/dt)h = y(t) + (- a*y(t) + f(t))*h

    # 잘 생각해보면, 이것은 아주 간단한 반복작업이 된다. 이를 위한 파이썬 코드를 쓴다면, 다음과 같을 것이다.

    import numpy as np

    a=2.

    f = lambda x, 3.*np.exp(-4.*x)

    y0 = 0. # t=t0일때의 값이라고 하자.

    h = 0.1 # time slice가 된다. 이 값은 작을수록 더 정확한 답을 얻게 되지만, 계산이 느려진다.

    y = [y0] # 일단 여기서 시작해 보자.

    t = 0.

    tmax = 10. # 얻고싶은 시간의 마지막 순간. 즉, 이 시간 이후에는 관심이 없고 그 전까지만 관심이 있다는 뜻이다.

    while t y.append(y[-1]+(f(t)-a*y[-1])*h)

    t+=h

    # while 안에 있는 코드가 가장 중요하다. 잘 보면, 별거 없다는 사실을 알 수 있을 것이다.

    # 이제 2차 미방을 1차 미방 2개로 쪼개는 기법을 아주 간단히 이해하고 넘어가자.

    # 주어진 2차 미방이 d(dy/dt)/dt + a*dy/dt + b*y(t) = f(t) 라고 하면, 일단 dy/dt = z 라고 하자. 그리고 z를 대입하면

    # dz/dt + a*z + b*y = f(t)

    # dy/dt = z

    # 이렇게 2개의 미분방정식으로 쪼개졌다. 한번 풀어보도록 하자.

    # 일단 y0와 z0=dy/dt(t=0)는 알려져 있다고 하자.

    y = [y0]

    z = z0.

    # z는 우리가 문제를 풀기를 원하는 값이 아니라 중간 저장 변수이므로 그냥 이렇게 두면 된다. 만약 2차 미분방정식인데 1차 미분도 같이 구해야 하는 경우(뉴턴 방정식에서 속도와 위치를 둘 다 구하는 경우, 회로 방정식에서 전하와 전류를 둘 다 구하는 경우) 등등에서는 z를 리스트로 선언해서 써도 된다.

    while t y.append(y[-1]+z*h)

    z+=(-a*z-b*y+f(t))*h

    t+=h

    # 2차 미방이지만 위와 같이 딱 1줄 더 늘어난 아름다운 코드로 만들 수 있다.

    # 오일러 풀이법은 가장 간단하지만 h가 상당히 작아야 정확한 답을 얻을 수 있다. 미분이나 적분을 할 때 함수값의 대칭성을 이용해서 같은 구간 h에 대해서도 보다 정확한 계산을 할 수 있었는데, 여기서도 마찬가지 테크닉을 사용할 수 있다.

    # 룽게-쿠타(Runge-Kutta) 풀이법은 한발 앞서 간 도함수와 평균을 내서 다시 구한다. 즉, 기울기 계산을 두번한다. 말로는 알아듣기 어려울 것이고, 직접 코드를 보는 것이 보다 이해하기 쉬울 것이다.

    # y(t+h) = y(t)+(dy/dt)h = y(t) + (- a*y(t) + f(t))*h

    # dy/dt + a*y(t) = f(t)

    y = [y0]

    while t y1= -a*y[-1]+f(t) # 일단 기울기 계산

    y.append(y1*h+y[-1]) # 일단 값 집어넣고

    y2 = -a*y[-1]+f(t+h) # 한칸 간 곳에서의 기울기 계산

    y[-1] = y[-2]+0.5*(y1+y2)*h # 실제 값은 두 기울기의 평균만큼만 증가하는 것으로.

    t+=h

    # 계산 시간을 아주 조금이라도 더 절약하고 싶으면 0.5*h를 미리 h2같은걸로 정의해놓고 0.5*h대신 h2를 곱하는 것으로 바꾸면 조금 빨라진다.

    # y2를 계산하는 부분은 그 다음줄로 한번에 집어넣을 수도 있지만, 읽기가 힘들어지므로 굳이 그렇게 할 필요는 없다.

    # 2차 룽게-쿠타 방법 뿐만 아니라 더 높은 차수의 룽게-쿠타 방법도 가능하다. 위와 같이 기울기 가중치를 어떻게 주느냐를 잘 생각하면 되는데, 아이디어는 비슷하므로 크게 어려울 것 없다.

    # 조금 더 일반화하면 predictor-corrector 방법이 된다.

    # 미분방정식이 dy/dt+f(y(t), t)=0으로 주어진 경우에 사용하는데, 위의 미분방정식은 f(y, t) = a*y-f(t)로 주어진 하나의 사례에 해당한다.

    # Predictor-corrector 방법은 그럼 RK방법을 그대로 갖고 오면 된다.

    y = [y0]

    while t y1= f(y[-1], t) # 일단 기울기 계산

    y.append(y1*h+y[-1]) # 일단 값 집어넣고

    y2 = f(y[-1], t+h) # 한칸 간 곳에서의 기울기 계산

    y[-1] = y[-2]+0.5*(y1+y2)*h # 실제 값은 두 기울기의 평균만큼만 증가하는 것으로.

    t+=h

    # 물리학에서 풀어야 하는 수많은 미분방정식들은 대체로 운동방정식이다. 운동방정식은 2차 미분방정식이므로, 2차 도함수를 알고 있다는 사실로부터 뭔가를 직접 해결할 수 있다.

    # 그래서 나온 방법이 벌레(Verlet) 방법이다. Verlet은 사람 이름이고, 프랑스 사람이라 t가 묵음이다.

    # 벌레 알고리즘에 대해서는 이 글을 참고해 볼 수 있다.

    # http://www.physics.udel.edu/~bnikolic/teaching/phys660/numerical_ode/node5.html

    # 일단, 테일러 전개로부터 다음과 같은 사실을 알 수 있다.

    # y(t-h) = y(t)-v(t)*h+a(t)*h*h/2

    # 여기서 v=dy/dt, a=dv/dt 이다.

    # -h가 아니라 +h에 대해서 다시 쓰면

    # y(t+h) = y(t)+v(t)*h+a(t)*h*h/2

    # 이렇게 될 것이다.

    # 두개를 더해보자.

    # y(t-h)+y(t+h) = 2y(t)+a(t)*h*h

    # v가 사라졌다!

    # 이제 다음과 같이 y(t+h)를 추정할 수 있다.

    # y(t+h) = 2y(t)-y(t-h)+a(t)*h*h

    # 물리 문제를 해결할 때, 이 공식은 매우 기가막힌 방법이다. 2차 미분방정식을 풀어야 하는데, 속력을 구하지 않고 힘으로부터 곧바로 위치를 얻어내기 때문이다.

    # 또한, 두개를 빼면 속력을 얻을 수 있다.

    # v(t) = (y(t+h)-y(t-h))/2h

    # 이 공식은 미분에서 공부했던 3점 공식과 같다.

    # 이렇게 계산하는 방법을 original Verlet 알고리즘이라고 한다. 그런데, 오리지널 벌레는 문제가 있다. y(t=0)일때를 알고 있어도, y(t+h)를 구하기 위해서는 y(t-h)를 알아야 한다. 즉, 최초 2점을 알아야 한다는 문제가 있다. 그래서 이 방법을 개선하기 위해서 velocity Verlet 알고리즘이 등장한다. 일단 공식부터 보고 시작하자.

    # y(t+h) = y(t)+v(t)*h+0.5*a(t)*h*h

    # v(t+h) = v(t)+0.5*(a(t+h)+a(t))*h

    # 왠지 앞에서 보았던 오일러 풀이법으로 2차 미분방정식을 푸는 것과 비슷해 보이지만, 그보다 더 정확하다. 그리고 이 경우 알지도 못하는 과거인 y(t-h)를 몰라도 문제를 해결할 수 있으므로 고민이 한층 덜어졌다.

    # 이 문제에서 a(t) 가 알려져 있다고 하면, 코드를 다음과 같이 짜볼 수 있을 것이다.

    y=[y0]

    v=v0 # 2차 미방이므로 y0와 v0는 알고 있어야 한다.

    while t y.append(y[-1]+v*h+0.5*a(t)*h*h)

    v+=0.5*(a(t+h)+a(t))*h

    t+=h

    # 이외에도 많은 알고리즘이 있지만 대체로 이런 아이디어들의 변형과 개선을 도모한 방법들이다. 실제로 자신이 풀려고 하는 문제에 적합한 알고리즘을 선정하고, 그 문제에 적합하게 알고리즘을 개조/개선해서 적용하는 것이 좋다.

    # 수치해석적인 방법의 장점은 선형 미분방정식 뿐만 아니라 비선형 미분방정식의 경우에도 적용할 수 있다는 것이다. 사실, 선형 제차 미분방정식의 해는 매우 쉽게 해석적으로 구할 수 있다. 그러나 비제차 미분방정식이나 비선형 미분방정식의 경우 해가 알려진 것이 매우 적으나, 실용적 관점에서 수치해석을 이용하여 문제를 해결할 수 있다.

    # 수치해석으로 비선형 미분방정식을 해결할 때 주의해야 하는 것은 오차의 전파이다. 비선형 효과에 의해 오차가 예상보다 커질 수 있으므로 오차를 줄이기 위해서 기존의 공식을 적절히 변형하는 것이 필요할 수 있다.

  • 산은 편하게 타면 안되나?


    http://news.khan.co.kr/kh_news/khan_art_view.html?artid=201309012128025&code=990100

    강신주 교수님을 싫어하지는 않지만, 칼럼에 동의할 수 없는 부분이 있어서 적어둔다.

    설악산에 케이블카를 설치하는 것이 환경을 파괴한다는 점은 동의한다. 그리고 설악산에 케이블카를 설치하는 것이 얻는 것 보다는 잃는 것이 더 많을 것이라고 생각한다. 또한 나는 설악산에 케이블카를 설치하는 것에도 반대하는 편이다.

    하지만 산을 오르는 것에 자신의 걸음으로만 올라가야 반드시 그 기쁨을 느낄 수 있다는 점에 있어서는 동의할 수 없다. 어떤 사람이 기쁨을 느끼는 행위는 다른 사람의 통제나 지시를 받을 수 없다. 그 자신에게는 자신의 다리로 걸어가는 것이 더 희열을 느낄 수 있을지 모르지만, 또 대다수의 사람들이 그렇게 생각할 수도 있겠지만 그럼에도 불구하고 그런 사람이 많다는 점이 누구나 그래야 한다는 결론을 짓는 근거가 되지는 않는다.

    어떤 사람은 다리가 불편해도 두 팔로 기어서 산의 정상을 정복할 수 있다. 어떤 사람은 다리가 불편하여 다른 사람의 등에 업혀서 정상을 오를 수 있다. 또 누구는 돈이 많아서 다리가 불편하지만 헬리콥터로 정상보다 더 높은 곳을 볼 수 있을지도 모른다. 다리가 멀쩡한 사람들도 이 세가지 사례를 마찬가지로 적용할 수 있다. 그럼 그중 누군가는 ‘진짜 기쁨’을 느끼지 못한채 가짜로 기뻐하고 있는 것일까?

    누구든지 ‘이렇게 해보니까 더 즐겁더라’라고 제안할 수는 있다. 자신이 소중하게 생각하는 어떤 사람에게 그렇게 꼭 해보라고 강력하게 추천할 수도 있다. 자신의 명령을 들어야 하는 하급자에게 굳이 그렇게 해야만 한다고 지시할 수도 있다. 하지만 그렇게 했을 때 너는 반드시 기뻐해야 한다고 강요할 수 없고, 그렇게 하지 않았을 때 진짜 즐거움을 모를 거라고 강요할 수도 없다. 강요된 감정이야말로 진짜 즐거움과 거리가 멀다.

  • 과학에는 쓸데없는 질문이란 없다

    과학을 연구하다가 등장한 질문은 단 하나도 버릴 질문이 없다.

    음…

    다 논문거리다. 이미 논문이 나와 있거나, 아직 논문이 나오지 않았거나 둘 중 하나일 뿐.

  • 전자파 차단의 나쁜예


    http://imnews.imbc.com/replay/nwdesk/article/3329790_5780.html

    도난 경보기에 걸리지 않는 특수가방을 이용해서 도둑질을 하던 부부가 붙잡혔다.



    이 특수가방의 원리는 ‘패러데이의 새장’이라고 부른다. 그런 원리가 있다.


    http://en.wikipedia.org/wiki/Faraday_cage

    도체 안에 완전히 둘러싸여있는 물체는 외부의 전자기장의 영향을 받지 않게 된다는 원리인데, 실생활에서 여기저기 사용되거나 체험할 수 있는 원리이다.

    엘리베이터에서 무선전화가 자주 끊기는 이유라든가, 전자레인지 옆에 있어도 전자파의 영향을 그다지 받지 않는다거나, 전자파 차단 필름도 같은 원리를 사용한다.

    위의 범행에 사용한 특수 가방은 그다지 특별할 것 없이, 은박지 여러겹을 겹쳐서 가방 안에 잘 넣은 것이다. 만들기가 어렵지도 않고, 누구나 간단하게 만들 수 있다. 하지만 이걸 실제로 믿고 사용해도 된다는 사실을 알 정도로 물리학을 열심히 공부한 사람이 이런 나쁜 짓을 하다니 안타깝기 짝이 없는 사건이다.

    도난방지 장치의 원리는 간단한 무선전력송신과 무선통신이다. 매장 입구와 출구 양 옆에 설치된 기둥을 본 적이 있을 것이다. 이 기둥에서는 전자기파가 흘러나오고 있다. 이 전자기파는 사람 몸에는 많이 흡수되지 않겠지만, 적당히 잘 설계된 안테나가 그 근처를 지나가면 그 안테나에 확 빨려들어가서 안테나에 전류를 흐르게 할 수 있다.

    안테나에 흐른 전류는 도난방지장치의 전원을 켜고 작동시킨다. 아주 잠깐동안 켜진 도난방지장치는 자신이 살아있다는 목소리를 전파를 통해서 송신하고, 이 전파는 문에 설치된 기둥에 포함된 다른 안테나에 검출되어서 도난방지장치가 문짝을 지나가고 있다는 사실을 알린다. 그럼 큰 소리가 나면서 경고를 보내고 도둑이 붙잡히는 것이다.

    여기서 이 특수가방은 전자파를 차단시켰으므로 전력의 송신도 안되고 도난방지장치의 전파가 밖으로 빠져나오지도 못한다. 즉, 특수가방은 도난방지장치를 성공적으로 감춰버린 것이다.

    이 문제는 어떻게 해결할 수 있을까?

    간단한 해결 방법으로는 도난방지장치 자체에 배터리를 달아서 외부와 통신을 계속 하고 있다가 통신이 끊기면 그 순간 소리가 나도록 하는 것이다. 소리는 외부에서 통신하고 있던 장비가 ‘어? 조금전까지 살아있던 놈이 왜 연락이 없지?’ 싶은 순간 울리도록 하면 될 것이다.

    하지만 이 방법은 배터리 수명이 있기 때문에 배터리가 다 떨어지면 훔쳐가기가 더 쉬워진다는 문제가 발생한다.

    따라서 앞서 이야기한 무선전력송신을 다시 한번 사용하여 배터리를 대신할 수 있다. 배터리 대신 무선전력송신 안테나를 매장 곳곳에 설치한다. 벽에 붙여서 설치하면 옷이나 다른 물건에 가려서 잘 안보이게 되므로 미관을 해치지 않고 깔끔하게 설치할 수 있다. 그럼, 마찬가지로 도난방지장치는 항상 작동하고 있게 되고, 그러다가 특수가방에 들어가버려서 갑자기 연락이 끊기면 그 순간 경보음을 울리도록 하면 될 것이다.

    이 경우, 내가 도둑이라면 공범을 사용해서 매장 안의 두 곳에서 동시에 시도할 것이다. 두곳에서 동시에 특수가방에 옷을 넣으면 경보는 한번만 울리게 되고 그럼 적어도 둘 중 하나는 성공해서 매장을 빠져나갈 수 있을 테니까.

    그럼, 이런 상황을 방지하기 위한 시나리오는?

    도난방지장치의 위치를 추적해야 하는데, 이때 도난방지장치의 위치는 도난방지장치가 내보내는 신호의 세기로부터 알아낼 수 있다. 무선 신호의 세기는 거리의 제곱에 반비례하므로, 도난방지장치의 출력을 미리 알고 있다면 서너군데의 안테나에서 검출된 신호의 세기를 이용하여 도난방지장치가 매장 내에서 어디에 있는지 위치를 정확히 파악할 수 있다. 그럼 그 신호가 완전히 없어진 순간, 바로 직전에 있던 위치에 경고의 불이 번쩍번쩍 하도록 설치하면, 그리고 여러군데서 동시에 울릴 수도 있도록 설치한다면 이와 같은 특수 가방을 이용한 절도를 차단할 수 있다.

    문제는 비용인데, 아마 이런 설비를 구현하고 설치하려면 매장 전체에 전력 송신 안테나와 위치 수신기를 설치해야 하므로 기존 장비의 열배 정도는 비용을 들여야 할 것이다. 한 벌에 수천만원 정도 하는 명품 옷이나 가방 같은 물건을 파는 매장이라면 고려해 볼 수 있을 것 같다.

  • 수치해석4 – 빠른 푸리에 변환

    이 글은 다음 글을 조금 더 고쳐서 다시 쓴 것이다.


    http://snowall.tistory.com/501

    파이썬 구현 예제는 생각중이다.

    왜 4번이 먼저 올라왔느냐는 중요한 문제가 아니다. 나도 모른다.

    # Elementary Numerical analysis 4

    # based on Python

    # (C) 2013. Keehwan Nam, Dept. of physics, KAIST.

    # snowall@gmail.com / snowall@kaist.ac.kr

    # Fast Fourier Transform

    # 푸리에 변환은 적분변환이다. 다시말해서, 적분을 잘 수행하면 푸리에 변환은 계산된다.

    # 0부터 1까지 구간만 생각해 보자.

    # F1(k) = Integrate f(x)cos(kx)dx from 0 to 1

    # F2(k) = Integrate f(x)sin(kx)dx from 0 to 1

    # 위의 두 수를 k를 정해놓고 적분하면 된다. 하지만 현실은 그렇게 만만하지 않은데, 1개의 k에 대해서만 푸리에 계수를 구하는 것이 아니라, k에 대한 함수를 구해야 하는 사태가 벌어지기 때문이다.

    # 따라서, 다음과 같이 하자. 조금 바꾼다.

    # F = F1+i*F2

    # 여기서 i는 제곱하면 -1이 나오는 허수 단위이다.

    # 이렇게 되면 F는 오일러 공식을 사용해서 다음과 같이 쓸 수 있다.

    # F(k) = Integrate f(x)exp(ikx)dx from 0 to 1

    # 이제, 이 함수를 잘 적분하면 되는데, 우리는 지금 수치해석을 공부하고 있으므로 수치적으로 적분하면 된다.

    # 0부터 1까지를 N등분하면 dx = 1/N이고 k는 k/N로 생각할 수 있다.

    # F(k) = Summation f(x)exp(ikx/N) over integer x from x = 0 to x = N

    # 위의 공식을 이산 푸리에 변환Discrete Fourier Transform이라고 한다.

    # N등분된 구간은 k가 N개 있으므로, N개의 k값에 대한 각각의 함수를 계산하기 위해서 N개의 값을 더해야 한다. 즉, N*N번의 계산이 필요하다.

    # 이제 exp(ikx/N)을 아주 잘 관찰해야 한다.

    # f(x)exp(ikx/N)를 계산할 때, 잘 관찰해보면 같은 값들이 반복되는 것을 알 수 있다. k에 대한 값을 계산한 후 k+1에 대한 값을 계산한다면, f(x)exp(i(k+1)x/N)=f(x)exp(ikx/N)exp(ix/N) 이다.

    # http://snowall.tistory.com/501

    # 이제, 가령 점이 4개만 있다 치고, exp(ikx/N)을 대충 퉁쳐서 w(k*x)라 치고 그냥 대입해보자.

    # F(0)=f(0)w(0)+f(1)w(1*0)+f(2)w(1*0)+f(3)w(1*0)

    # F(1)=f(0)w(0*1)+f(1)w(1*1)+f(2)w(2*1)+f(3)w(3*1)

    # F(2)=f(0)w(0*2)+f(1)w(1*2)+f(2)w(2*2)+f(3)w(3*2)

    # F(3)=f(0)w(0*3)+f(1)w(1*3)+f(2)w(2*3)+f(3)w(3*3)

    # 뭔가 있어 보인다면, 계산을 완성하자.

    # F(0)=f(0)w(0)+f(1)w(0)+f(2)w(0)+f(3)w(0)

    # F(1)=f(0)w(0)+f(1)w(1)+f(2)w(2)+f(3)w(3)

    # F(2)=f(0)w(0)+f(1)w(2)+f(2)w(0)+f(3)w(2)

    # F(3)=f(0)w(0)+f(1)w(3)+f(2)w(2)+f(3)w(1)

    # 잘 보면 반복되는 것들이 보인다는 사실을 알 수 있다.

    # 따라서 반복되는 부분을 미리 계산하고 재활용하면 된다.

    # E1=f(0)w(0)+f(2)w(0)

    # E2=f(0)w(0)+f(2)w(2)

    # E3=f(1)w(0)+f(3)w(0)

    # E4=f(1)w(1)+f(3)w(3)

    # F(0)=E1+E3

    # F(1)=E2+E4

    # F(2)=E1+E3*w(2)

    # F(3)=E2+E4*w(2)

    # 원래는 16번의 곱셈과 12번의 덧셈이 있었는데, 잘 고쳤더니 10번의 곱셈과 8번의 덧셈으로 줄어들었다.

    # 만약 점의 수가 수십만개로 늘어난다면, 아마 그 효율은 매우 좋아질 것이다. 즉 N*N번의 연산이 N*logN번의 연산으로 확 줄어들게 된다.

    # 이 알고리즘은 Cooley-Tukey 알고리즘의 특수한 경우이며, 가우스가 최초에 발견하고 쿨리와 튜키가 나중에 다시 발견했다.

    # http://ko.wikipedia.org/wiki/고속_푸리에_변환

    # 파이썬 구현은 생략한다.

    # http://docs.scipy.org/doc/numpy/reference/routines.fft.html 파이썬에서는 numpy 패키지에서 제공한다.

  • 람다 함수

    파이썬에서 람다 함수는 이름없는 함수이다. 이름이 없기 때문에 한번 쓰면 다시 불러올 수 없다. 즉, 1회용 함수이다.

    왜 쓰냐건, 웃지요.

    바꿔 말해서, 한번쓰고 버릴 함수를 만들기 위해서 쓴다.

    문법은 lambda를 써 주고, 인자를 써주고, 리턴값을 쓰면 된다.

    (lambda x, y, z: x+y+z)(1,2,3)

    이게 전부다. 저러면 6이 나온다.


    http://coreapython.hosting.paran.com/dive/chap04.html#apihelper.lambda

    어쨌든 파이썬의 강력한 기능 중 하나라고 한다.

    한가지 중요한건, 람다 함수로 할 수 있는건 람다 함수를 쓰지 않고도 전부 할 수 있다는 점이다. 반대로, 람다 함수가 아닌 다른 함수로 할 수 있는 일 중에는 람다 함수로 할 수 없는 것도 있다.

    그럼 람다 함수가 뭐가 좋아서 쓰는걸까? 파이썬 사용자들의 말에 의하면 더 우아하고 더 효율적이라고 한다.

    사실 이걸 사용하면 한줄에 다 담을 수 있고, def를 써서 정의하지 않아도 되므로 이름을 붙이는 수고를 덜 수 있고(인간적 관점과 메모리 점유율 관점에서), 함수를 찾아보러 어디 다녀오지 않아도 된다.

    내 경우에는, 어떤 함수를 람다 함수로 정의하기 위해서 코드를 머릿속에서 만드는데 걸리는 시간이 15초 이하라면 써볼만 할 것 같다. 그 이상 걸린다면 그냥 함수를 하던대로 정의해서 쓰는 것이 낫겠다는 생각이 든다.

    이 문제를 어떻게 풀 것인가? 에 관한 고민에서, 어떤 경우는 람다 함수를 사용하면 매우 간단하고 간결한 해법이 나올 수도 있으므로 사용법과 문법은 익혀두는 것이 좋겠다. map, reduce, filter 등의 함수와 함께 쓰면 조금 더 강력해진다.

  • 궁수자리 A*


    http://www.zdnet.co.kr/news/news_view.asp?artice_id=20130902091807&type=xml

    지디넷에서 별을 삼키지 않는 블랙홀을 찾았다고 보도했다. 뭐 좀 이상해 보이는 블랙홀인데, 어쨌든 그 이름을 새지태리어스 A*로 이름을 붙였다고 한다.


    새지태리어스는 궁수자리다.


    http://en.wikipedia.org/wiki/Sagittarius_A*

    그리고 궁수자리 A*는 꽤 오래전에 발견된 블랙홀이다.

    음… 즉, 이번에 새로이 발견된 블랙홀이 아니라, 예전에 발견했던 블랙홀을 계속 관찰해서 새로운 사실을 알아냈다는 뜻이다.




    http://www.sci-news.com/astronomy/science-chandra-gas-supermassive-black-hole-sagittarius-a-01349.html

    이번에 알아낸 것은 다른 영역에서는 꽤 밝은 편인데 엑스선 영역은 왜 어두운지 알아냈다는 것이다.

    외국 언론사의 보도 내용을 갖고 오는건 좋지만, 그래도 뭘 좀 아는 기자가 제대로 보도해준다면 좀 더 흥미로운 소식이 되지 않을까.

  • 수치해석1 – 미분과 적분




    lecture_1.py

    # Elementary Numerical analysis 1

    # based on Python

    # (C) 2013. Keehwan Nam, Dept. of physics, KAIST.

    # snowall@gmail.com / snowall@kaist.ac.kr

    # Differentiation

    # 테일러 정리와 테일러 전개를 적극 사용하면 된다.

    # 수치적으로 미분은 다음과 같이 정의한다

    # df/dx = (f(x+h) – f(x))/h

    # 이 경우 오차가 h의 제곱에 비례한다. 2점 미분공식이다.

    # 오차를 줄이고 싶은 경우 대칭성을 이용해서 오차를 줄일 수 있다.

    # df/dx = (f(x+h)-f(x))/h-(f(x-h)-f(x))/h = (f(x+h)-f(x-h))/2h

    # 이 경우 오차가 h의 세제곱에 비례한다. 3점 미분공식이다.

    # 더 줄이고 싶다면 위의 3점 미분공식을 5점으로 확장할 수 있다.

    # df/dx = (f(x+2h)+f(x+h)-f(x-h)-f(x-2h))/6h

    # 하지만 이래봐야 오차는 그냥 h의 세제곱에 비례하게 된다.

    # 머리를 써 보면 5점 미분공식은 다음과 같다.

    # df/dx = (-f(x+2h)+8f(x+h)-8f(x-h)+f(x-2h))/12h

    # 이렇게 하면 오차가 h의 4제곱에 비례하게 된다.

    # 2차 이상의 미분을 계산해야 한다면, 1차 미분을 반복적으로 계산할 수도 있고, 또는 직접 2차 도함수를 얻을 수도 있다.

    # d2f/dx2 = 2(f(x+h)-2f(x)+f(x-h))/(h*h)

    # 이와 같이 n차 도함수를 직접 계산하는 공식은 테일러 전개에 의하여 손쉽게 얻을 수 있다.

    # 실제 구현은?

    # 파이썬이라면, 수치가 리스트로 주어져 있을 것이다.

    f = numpy.array([x1, x2, x3, x4, x5])

    h = 1.0e-2 # 미분에서 사용한 h값이 된다.

    # 첫번째로, 2점 미분공식을 얻어보자.

    df = (f[1:]-f[:-1])/h

    # 이 공식이 왜 작동하는지는 차근차근 생각해 보면 된다.

    # 마찬가지로, 3점 미분공식도 똑같이 얻을 수 있다.

    df = (f[2:]-f[:-2])/(2*h)

    # 5점 미분공식은 직접 고민해 보자.

    # 하지만, 항상 리스트로만 주어져 있을리가 없다. 화일에서 직접 값을 한줄씩 읽어오면서 계산해야 하는 경우도 있을 것이다.

    # 물론 화일을 리스트에 집어넣고나서 위의 방법을 쓰면 되지만,

    # 화일이 메모리에 안 들어가는, 가령 수십 GB용량의 데이터를 미분해야 한다면 그건 그거대로 막막하리라고 본다.

    data = open(“mydata.txt”, “r”)

    f = [data.readline(), data.readline(), data.readline()]

    df = []

    while data.EoF():

    df.append((f[0]-f[2])/(2.*h))

    f.append(data.readline())

    f=f[1:]

    # data.EoF()는 파일의 끝인지 아닌지 판단하는 함수이다. (구현은 셀프!)

    # 이게 왜 작동하는지는 직접 생각해 보고, 5점 미분공식으로 바꾸려면 어떻게 해야 할지 생각해 보자. 또는 2차도함수 계산이라면?

    # df.append로 리스트에 집어넣는 것이 메모리를 잡아먹을 것 같다면, df를 파일로 열어서 df.writeline함수를 사용해도 된다.

    # 다른 프로그래밍 언어라면 구체적으로는 다르게 구현해야 할 것이다. 자신이 사용하는 언어에서는 어떻게 구현할 수 있을까?

    # 파이썬의 scpiy 모듈에서 미분을 제공하는데, scipy.misc.derivative(func, x0, dx=1.0, n=1, args=(), order=3) 함수를 사용하면 된다.

    # 이 함수는 func로 주어진 함수가 x0위치에서 주어진 dx로 미분한 n차 “미분계수” 값을 알려준다. order는 3점공식인가 5점공식인가 등등이다. ‘당연히’ 홀수만 넣어야 한다.

    # 내가 정의한 함수가 수를 넣으면 수가 나오는 함수라면, 위의 함수로 주어진 점에서의 미분계수를 알아낼 수 있다. 그러나 해석적인 도함수를 알려주지는 않는다.

    # Integration

    # 용어를 먼저 알고 가자.

    # Quadrature 또는 Numerical quadrature는 수치해석에서 말하는 수치 적분을 뜻한다. 1차원 이상의 고차원 수치적분을 포함하기는 하지만, 1차원 수치적분의 뜻이 강하다.

    # Cubature는 1차원 이상의 고차원 수치적분을 대체로 뜻한다.

    # 1차원 적분을 먼저 논의해 보자.

    # 가장 간단하게는 사각형으로 근사할 수 있다. 원래 적분은 연속 함수를 잘게 썰어서 각각의 넓이를 구한 후, 더 많은 조각으로 더 잘게 썰어가며 극한을 구하는 과정이다.

    # 따라서 컴퓨터에게 수치적으로 적분을 계산을 시킨다면, 충분히 많은 조각으로 잘게 썰어서 각각의 넓이를 구한 후 다 더하도록 하면 된다.

    # 가장 간단하게 사각형으로 근사한다면, i번재 함수값을 f[i]라 한다면

    # F = sum(f[i], i=0 to N)*(b-a)/N

    # 물론 각 조각은 N등분했다고 가정했다. 조각의 길이가 구간마다 다른 경우라면 골치아파지므로 그러지 말자.

    # 위의 코드는 파이썬으로 간단히 구현할 수 있다.

    f = [f1, f2, f3, f4, ,f5] # f는 함수값들을 수치적으로 저장하고 있는 리스트이다.

    F=0

    for i in f:

    F+=i

    F/=h # h는 구간의 길이이다. h=(b-a)/N 정도로 정의하면 될 듯.

    # 대충 이렇게 쓰면 될 것이다. 만약 조금 더 짧게 쓰고 싶다면 reduce와 lambda를 쓸 수 있다. 이 두 구문이 뭔지에 대해서는 자습해보자.

    F = reduce(lambda x, y:x+y, f)*h

    # 위의 구문이 적분식이다. 이걸 midpoint rule 이라고 한다.

    # 사각형으로 적분하는 것보다, 아무래도 사다리꼴로 나누는 것이 조금 더 정확하지 않을까? 하는 마음에 만든 공식이 사다리꼴 규칙이다. Trapezoidal rule (trapezium rule)

    F = reduce(lambda x, y:x+y, f)*h – 0.5*(f[0]+f[-1])*h

    # 위의 구문이 사다리꼴 적분에 해당한다. 별 차이 없어 보이는데 아주 조금 더 정확하다. 왜그런지는 어렵지 않으니 직접 생각해 보자.

    # 이 경우 오차는 대략 구간의 크기인 h의 제곱에 비례한다.

    # 보다 정확한 근사식은 Simpson’s rule이 제공한다. 사다리꼴 규칙에서 심슨 규칙으로 진화하는 것은 미분에서 2점 공식을 3점 공식으로 바꾸는 과정과 유사하다.

    # 즉, 사다리꼴 규칙은 2점을 이용해서 그 사이의 면적을 근사했지만, 심슨 규칙은 3점을 이용해서 그 사이의 면적을 근사한다.

    # 즉, 3점으로 이루어진 2차곡선이 원래 주어진 곡선보다 위인 구간과 아래인 구간이 있게 되는데, 넘치는 부분과 모자라는 부분이 상쇄되어 보다 정확한 근사값을 얻는다. 곡선의 근사는 틀리게 되지만, 적분값은 정확해진다는 것이다.

    # 심슨 규칙은 다음과 같다.

    # F=(f(a)+4f((a+b)/2)+f(b))*(b-a)/6

    # 딱 3점, 즉 a, b, (a+b)/2의 3군데 값을 알고 있을 때 그 사이의 면적은 위와 같이 근사된다. 이 경우 오차는 구간의 크기인 b-a의 5제곱에 비례한다.

    # 파이썬으로 구현한다면 어떻게 될까?

    # 가장 간단하게 구현한다면 다음과 같을 것이다.

    f = [f1, f2, f3]

    F = (f[0]+4*f[1]+f[2])*h/6

    # 하지만 이런 경우는 점이 정말 3개밖에 없는 경우이다. 만약 그보다 많다면? 일단 정확히 홀수개 있다고 하자.

    f = [f1, f2, f3, f4, f5] # 리스트는 더 길어질 수도 있다.

    F = (2.*reduce(lambda x, y: x+y, map(lambda x:x[0]+x[1]+x[1],f[:-1].reshape(len(f)/2,2)))-f[0]+f[-1])*h/6



    # 이 코드는 간단해 보여도 자그마치 3개의 파이썬 기능이 합쳐진 콤비네이션이다.



    # 홀수개만큼 있을 때는 위의 코드를 쓰면 된다. 왜 되는지는 다시 잘 생각해 보도록 하자. 파이썬 공부 겸 아이큐테스트라고 하자. (나도 테스트 안해봄.)

    # 짝수개일 때는 어떻게 될까? 짜투리 부분의 오차를 어떻게 정리할 수 있을지는 각자 생각해 보자.

    # 파이썬에서 구현된 적분은 scipy에서 제공한다.

    # scipy.integrate(f, a, b)는 주어진 함수 f를 a에서 b까지 적분해준다. 다중적분도 다룰 수 있다.

    # 1차원 적분의 경우 위의 코드로만 적분하더라도 해볼만하다. 문제는 다차원 적분은 적분 구간을 (a, b)처럼 쉽게 쪼개줄 수 없다는 것이다.

    # 물론 잘 쪼개서 다중 반복문을 돌리면 된다. 당연히 된다. 만약 함수가 수치적으로, 즉 모든 위치에서의 함수값이 ‘진짜 값’으로 주어져 있다면 다중반복문을 돌려서 적분해야 할 것이다.

    # 하지만, 만약 고차원에서 정의된 매우 이상한 함수가 있는데, 이 함수의 함수값은 구할 수 있지만 함수값이 다 주어진게 아니라 그냥 함수만 주어져 있다면? 그리고 그 해석적인 적분은 구할 수 없는 경우라면?

    # 이때는 확률적 방법을 통해서 구할 수 있는데 그것이 바로 Monte-carlo integration이다.

    # 다차원 다중적분 및 MC는 다른 기회에 설명하도록 하겠다.

    Quadratic은 “사각형의”라는 뜻을 담고 있는데, 그래서 “제곱”이라는 뜻도 있다. 일반적으로 사각형은 2차원 평면에서 정의된 도형이고, 1차원에서 1차원으로 가는 함수는 보통 직사각형으로 근사해서 적분하게 되므로 quadrature는 2차원 적분의 뜻이 강하다. Cube는 정육면체를 뜻하고, Cubic은 그래서 세제곱이라는 뜻이 있다. 거기서 나온 Cubature는 3차원 적분의 뜻이 강하다. 3차원 이상에도 각 차원마다 라틴어 어원을 갖는 형용사들이 있겠지만 그냥 Cubature라고 부르는 듯. Curvature는 “곡률”이라는 뜻으로 cubature와는 아무 관련 없다.