유한 한 차이를 가진 근사한 야 코비안이 뉴턴 방법에서 불안정성을 야기 할 수 있습니까?


13

파이썬 3에서 numpy를 사용하여 Back-Euler 솔버를 구현했습니다. 나 자신의 편의와 운동을 위해 그래디언트의 유한 차분 근사값을 계산하는 작은 함수를 작성하여 항상 야곱을 분석적으로 결정할 필요가 없도록했습니다.

Ascher와 Petzold 1998에 제공된 설명을 사용하여 주어진 지점 x에서 기울기를 결정하는이 함수를 작성했습니다.

def jacobian(f,x,d=4):
    '''computes the gradient (Jacobian) at a point for a multivariate function.

    f: function for which the gradient is to be computed
    x: position vector of the point for which the gradient is to be computed
    d: parameter to determine perturbation value eps, where eps = 10^(-d).
        See Ascher und Petzold 1998 p.54'''

    x = x.astype(np.float64,copy=False)
    n = np.size(x)
    t = 1 # Placeholder for the time step
    jac = np.zeros([n,n])
    eps = 10**(-d)
    for j in np.arange(0,n):
        yhat = x.copy()
        ytilde = x.copy()
        yhat[j] = yhat[j]+eps
        ytilde[j] = ytilde[j]-eps
        jac[:,j] = 1/(2*eps)*(f(t,yhat)-f(t,ytilde))
    return jac

나는 진자에 대한 다변량 함수를 취하고 상징적 인 Jacobian을 점의 범위에 대해 수치 적으로 결정된 기울기와 비교 하여이 기능을 테스트했습니다. 테스트 결과에 만족했으며 오류는 1e-10 정도였습니다. 근사한 Jacobian을 사용하여 진자의 ODE를 풀었을 때 매우 효과적이었습니다. 둘 사이의 차이를 감지 할 수 없었습니다.

그런 다음 다음 PDE (1D의 피셔 방정식)로 테스트 해 보았습니다.

tu=x(kxu)+λ(u(Cu))

유한 차이 이산화를 사용합니다.

이제 Newton의 방법이 첫 번째 단계에서 폭발합니다.

/home/sfbosch/Fisher-Equation.py:40: RuntimeWarning: overflow encountered in multiply
  du = (k/(h**2))*np.dot(K,u) + lmbda*(u*(C-u))
./newton.py:31: RuntimeWarning: invalid value encountered in subtract
  jac[:,j] = 1/(2*eps)*(f(t,yhut)-f(t,yschlange))
Traceback (most recent call last):
  File "/home/sfbosch/Fisher-Equation.py", line 104, in <module>
    fisher1d(ts,dt,h,L,k,C,lmbda)
  File "/home/sfbosch/Fisher-Equation.py", line 64, in fisher1d
    t,xl = euler.implizit(fisherode,ts,u0,dt)
  File "./euler.py", line 47, in implizit
    yi = nt.newton(g,y,maxiter,tol,Jg)
  File "./newton.py", line 54, in newton
    dx = la.solve(A,b)
  File "/usr/lib64/python3.3/site-packages/scipy/linalg/basic.py", line 73, in solve
    a1, b1 = map(np.asarray_chkfinite,(a,b))
  File "/usr/lib64/python3.3/site-packages/numpy/lib/function_base.py", line 613, in asarray_chkfinite
    "array must not contain infs or NaNs")
ValueError: array must not contain infs or NaNs

이것은 다양한 eps 값에 대해 발생하지만, 이상하게도 Courant-Friedrichs–Lewy 조건이 충족되지 않도록 PDE 공간 단계 크기 및 시간 단계 크기가 설정된 경우에만 발생합니다. 그렇지 않으면 작동합니다. (이것은 앞으로 Euler로 해결하면 기대되는 행동입니다!)

완성도를 높이기 위해 다음은 Newton Method의 기능입니다.

def newton(f,x0,maxiter=160,tol=1e-4,jac=jacobian):
    '''Newton's Method.

    f: function to be evaluated
    x0: initial value for the iteration
    maxiter: maximum number of iterations (default 160)
    tol: error tolerance (default 1e-4)
    jac: the gradient function (Jacobian) where jac(fun,x)'''

    x = x0
    err = tol + 1
    k = 0
    t = 1 # Placeholder for the time step
    while err > tol and k < maxiter:
        A = jac(f,x)
        b = -f(t,x)
        dx = la.solve(A,b)
        x = x + dx
        k = k + 1
        err = np.linalg.norm(dx)
    if k >= maxiter:
        print("Maxiter reached. Result may be inaccurate.")
        print("k = %d" % k)
    return x

la.solve 함수는 scipy.linalg.solve입니다.

Jacobian의 함수를 사용하여 테스트하고 안정적인 결과를 얻었으므로 이전 Euler 구현이 순서대로 작동한다고 확신합니다.

디버거에서 newton ()이 오류가 발생하기 전에 35 개의 반복을 관리한다는 것을 알 수 있습니다. 이 숫자는 내가 시도한 모든 eps에 대해 동일하게 유지됩니다.

추가 관찰 : FDA로 그라디언트와 초기 조건을 입력으로 사용하여 함수를 계산하고 엡실론의 크기를 변경하면서 두 가지를 비교하면 엡실론이 줄어들면 오류가 커집니다. 엡실론이 줄어들면 처음에는 커질 것으로 예상하고 작아지고 다시 커집니다. 따라서 Jacobian을 구현할 때 발생하는 오류는 합리적인 가정이지만 그럴 경우 미묘하기 때문에 볼 수 없습니다. 편집 : 중심 차이 대신 앞으로 사용하도록 jacobian ()을 수정했으며 이제 예상되는 오류가 발생하는 것을 관찰했습니다. 그러나 newton ()은 여전히 ​​수렴하지 않습니다. 뉴턴 반복에서 dx를 관찰하면, 나는 그것이 자라고, 변동조차도 없다는 것을 알 수 있습니다. 매 단계마다 거의 두 배가 (요인 1.9), 요인이 점차 커집니다.

Ascher와 Petzold는 Jacobian의 차이 근사치가 항상 제대로 작동하지는 않는다고 언급합니다. 유한 한 차이가있는 근사한 야 코비안이 뉴턴의 방법에서 불안정성을 야기 할 수 있습니까? 아니면 원인이 다른 곳입니까? 이 문제에 어떻게 접근 할 수 있습니까?


1
"나는 야곱 인을위한 함수를 사용하여 테스트했고 안정적인 결과를 얻었 기 때문에, 이전의 Euler 구현은 순서대로 진행되고 있다고 확신한다." 명확히하십시오. 정확한 Jacobian으로 동일한 문제를 실행하고 솔루션이 PDE의 정확한 솔루션으로 수렴한다고 말하고 있습니까? 중요한 정보입니다.
David Ketcheson

@DavidKetcheson 그래, 내가 말하는거야. 내 용어가 잘못되었거나 불완전한 경우 사과드립니다. (나는 "나는 안정적이고 예상 결과를 얻을 수 있습니다."나는 또한 말했다해야 가정)
스티븐 보쉬에게

답변:


3

다른 것보다 긴 의견이 많습니다.

Ascher와 Petzold 1998에 제공된 설명을 사용하여 주어진 지점 x에서 기울기를 결정하는이 함수를 작성했습니다.

구현에서 수행해야 할 작업에 대한 더 나은 아이디어를 얻으려면 SUNDIALS의 차이 몫 근사에 대한 코드를 살펴보십시오. Ascher와 Petzold는 시작하기에 좋은 책이지만 SUNDIALS는 실제로 생산 작업에 사용되므로 더 나은 테스트를 거쳤습니다. 또한 SUNDIALS는 Petzold가 작업 한 DASPK와 관련이 있습니다.

Ascher와 Petzold는 Jacobian의 차이 근사치가 항상 제대로 작동하지는 않는다고 언급합니다. 유한 한 차이가있는 근사한 야 코비안이 뉴턴의 방법에서 불안정성을 야기 할 수 있습니까?

경험적으로, 대략적인 야곱은 뉴턴의 방법에서 수렴 실패를 일으킬 수 있습니다. 나는 그것들을 "불안정성"으로 특징 지을 것임을 모른다; 경우에 따라 종료 기준에서 원하는 오차 허용 오차를 달성 할 수없는 경우도 있습니다. 다른 경우에는 불안정성으로 나타날 수 있습니다. Higham의 수치 분석법 책 또는 Hairer and Wanner의 W- 방법에 대한 논의 에서이 현상에 대해 더 많은 양의 결과가 있음을 거의 확신합니다.

아니면 원인이 다른 곳입니까? 이 문제에 어떻게 접근 할 수 있습니까?

오류가 발생한 위치에 따라 다릅니다. 뒤로 Euler 구현에 대해 확신이 있다면 거기서 시작하지 않을 것입니다. 경험을 통해 수치 방법을 구현할 때 편집증을 일으켰습니다. 따라서 실제로는 몇 가지 기본 테스트 문제 (비 강성 및 강성 선형 문제, 중심의 유한 차분 근사를 갖는 열 방정식, 나는 솔루션이 무엇인지, 내가 비교해야 할 것을 알기 위해 제조 된 솔루션의 방법을 사용합니다.

그러나 이미 그 중 일부를 수행했습니다.

Jacobian의 함수를 사용하여 테스트하고 안정적인 결과를 얻었으므로 이전 Euler 구현이 순서대로 작동한다고 확신합니다.

그것은 다음에 테스트 할 것입니다 : 분석적인 야 코비안을 사용하십시오. 그 후, 당신은 당신이 유한 Euler의 불안정한 지역에있을 가능성에 대한 유한 차이 Jacobian의 극한 고유 값을 볼 수도 있습니다. 분석 기준 인 야 코비안의 극한 고유 값을 비교 기준으로 보면 약간의 통찰력을 얻을 수 있습니다. 모두 체크 아웃한다고 가정하면 문제는 아마도 뉴턴 해결에 있습니다.


신중한 분석 (SUNDIALS 힌트 및 대체 소스 포함)에 감사드립니다. 교수님은 PDE의 FDA가 선형이된다고 주장하면서 lambda = 0을 설정할 것을 제안했습니다. 따라서 FDA Jacobian은 분석적인 Jacobian과 동일 할 것으로 기대합니다. 이 작업을 수행하면 세 번의 타임 스텝을 관리합니다. newton ()은 매번 maxiter를 때리며 마지막으로 이전과 같이 폭파합니다.
Stephen Bosch

또한 PDE를 해결하기 위해 대략적인 야곱 인을 사용하는 것은 일반적인 관행이 아니라고 설명했습니다. 아마 사소한 것이 아니라는 것을 알 수 있습니다).
Stephen Bosch

1
Knoll and Keyes의 유명한 리뷰와 같은 주제에 관한 문헌의 양을 감안할 때 교수의 진술은 다소 놀랍습니다 . 참고 문헌의 출처가 문제를 진단하는 데 도움이 될 수 있기 때문에 아마도이 백서를 내 대답에 인용했을 것입니다.
제프 옥스 베리
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.