Main Content

ode23s

경직성(Stiff) 미분방정식 풀기 — 저차수법(Low order method)

설명

[t,y] = ode23s(odefun,tspan,y0)입니다. 여기서 tspan = [t0 tf]t0에서 tf까지의 구간에서 초기 조건 y0을 사용하여 연립미분방정식 y'=f(t,y)를 적분합니다. 해 배열 y의 각 행은 열 벡터 t에 반환된 값에 대응합니다.

모든 MATLAB® ODE 솔버는 y'=f(t,y) 형식의 연립방정식이나 질량 행렬이 있는 문제 M(t,y)y'=f(t,y)를 풀 수 있습니다. 솔버는 모두 유사한 구문을 사용합니다. ode23s 솔버는 상수 질량 행렬을 갖는 문제만 풀 수 있습니다. ode15sode23t는 특이 질량 행렬을 포함하는 문제(즉, 미분대수 방정식(DAE))를 풀 수 있습니다. odesetMass 옵션을 사용하여 질량 행렬을 지정합니다.

예제

[t,y] = ode23s(odefun,tspan,y0,options)odeset 함수를 사용하여 생성된 인수인 options로 정의된 적분 설정도 사용합니다. 예를 들어, 절대 허용오차와 상대 허용오차를 지정하려면 AbsTol 옵션과 RelTol 옵션을 사용하고 질량 행렬을 제공하려면 Mass 옵션을 사용하십시오.

예제

[t,y,te,ye,ie] = ode23s(odefun,tspan,y0,options)는 이벤트 함수라고 하는 (t,y)의 함수가 0인 위치를 추가로 찾습니다. 출력값에서 te는 이벤트 발생 시간이고, ye는 이벤트 발생 시 계산된 해이며, ie는 트리거된 이벤트의 인덱스입니다.

각 이벤트 함수에 대해, 0에서 적분을 종료할지 여부와 영점교차의 방향을 고려할지 여부를 지정합니다. 이를 수행하려면 'Events' 속성을 함수(예: myEventFcn 또는 @myEventFcn)로 설정하고 대응 함수 [value,isterminal,direction] = myEventFcn(t,y)를 생성합니다. 자세한 내용은 ODE 이벤트 위치 항목을 참조하십시오.

sol = ode23s(___)deval과 함께 사용하여 구간 [t0 tf] 내의 임의의 점에서 해를 계산할 수 있는 구조체를 반환합니다. 위에 열거된 구문에 나와 있는 입력 인수를 원하는 대로 조합하여 사용할 수 있습니다.

예제

모두 축소

단일 해 성분을 갖는 단순한 ODE는 솔버 호출 시 익명 함수로 지정할 수 있습니다. 익명 함수는 입력값 중 하나가 함수에 사용되지 않는 경우에도 두 입력값 (t,y)를 모두 받아야 합니다.

다음 ODE를 풉니다.

y=-10t.

시간 구간 [0 2]와 초기 조건 y0 = 1을 지정합니다.

tspan = [0 2];
y0 = 1;
[t,y] = ode23s(@(t,y) -10*t, tspan, y0);

해를 플로팅합니다.

plot(t,y,'-o')

Figure contains an axes object. The axes object contains an object of type line.

경직성 연립방정식의 한 예로는, 이완 진동의 반데르폴 방정식(van der Pol equation)을 들 수 있습니다. 극한 주기 궤도(limit cycle)에서는 해 성분의 변화가 느리면서 문제의 경직성이 강한(Stiff) 영역과, 해 성분의 변화가 매우 급격하면서 문제의 경직성이 약한(Nonstiff) 영역이 번갈아가며 나타납니다.

연립방정식은 다음과 같습니다.

$$\begin{array}{cl} y_1' &= y_2\\y_2' &= 1000(1-y_1^2)y_2-y_1\end{array}$$

초기 조건은 $y_1(0)=2$$y_2(0)=0$입니다. 함수 vdp1000은 MATLAB®과 함께 제공되는 함수로, 이 방정식을 담고 있습니다.

function dydt = vdp1000(t,y)
%VDP1000  Evaluate the van der Pol ODEs for mu = 1000.
%
%   See also ODE15S, ODE23S, ODE23T, ODE23TB.

%   Jacek Kierzenka and Lawrence F. Shampine
%   Copyright 1984-2014 The MathWorks, Inc.

dydt = [y(2); 1000*(1-y(1)^2)*y(2)-y(1)];

디폴트 상대 허용오차와 절대 허용오차(각각 1e-31e-6)와 함께 ode45를 사용하여 이 시스템을 푸는 경우 해를 구하고 플로팅하는 데 몇 분이 걸릴 정도로 매우 느립니다. 허용오차를 충족하기가 쉽지 않은 경직성이 강한 영역으로 인해 ode45가 적분을 완료하려면 수백만 개의 시간 스텝이 필요합니다.

다음은 계산하는 데 시간이 오래 걸리는 ode45로 구한 해에 대한 플롯입니다. 경직성이 강한 영역을 통과하는 데 필요한 시간 스텝의 수가 엄청나다는 것을 알 수 있습니다.

ode23s 솔버를 사용하여 경직성 시스템을 풀고, 시간 지점 t에 대해 해 y의 첫 번째 열을 플로팅합니다. ode23s 솔버는 ode45보다 훨씬 적은 수의 스텝으로 경직성이 강한 영역을 통과합니다.

[t,y] = ode23s(@vdp1000,[0 3000],[2 0]);
plot(t,y(:,1),'-o')

ode23s는 두 개의 입력 인수 ty를 사용하는 함수에만 동작합니다. 하지만, 함수 외부에 추가 파라미터를 정의하고 함수 핸들을 지정할 때 이를 전달하는 방식으로 추가 파라미터를 전달할 수 있습니다.

다음 ODE를 풉니다.

$$y'' = \frac{A}{B} t y.$$

방정식을 1계 시스템으로 다시 작성하면 다음 결과가 생성됩니다.

$$\begin{array}{cl} y'_1 &= y_2\\ y'_2 &= \frac{A}{B} t y_1.
\end{array}$$

odefcn.m은 이 연립방정식을 4개의 입력 인수 t, y, A, B를 받는 함수로 나타냅니다.

function dydt = odefcn(t,y,A,B)
dydt = zeros(2,1);
dydt(1) = y(2);
dydt(2) = (A/B)*t.*y(1);

ode23s를 사용하여 ODE를 풉니다. AB의 미리 정의된 값을 odefcn에 전달하도록 함수 핸들을 지정합니다.

A = 1;
B = 2;
tspan = [0 5];
y0 = [0 0.01];
[t,y] = ode23s(@(t,y) odefcn(t,y,A,B), tspan, y0);

결과를 플로팅합니다.

plot(t,y(:,1),'-o',t,y(:,2),'-.')

ode15s 솔버는 대부분의 경직성 문제에서 최우선적으로 선택할 수 있는 솔버입니다. 하지만, 특정 문제 유형에 대해서는 다른 경직성 솔버가 더욱 효율적일 수도 있습니다. 이 예제에서는 네 가지 경직성 ODE 솔버를 모두 사용하여 경직성 테스트 방정식을 풉니다.

다음과 같은 테스트 방정식이 있다고 가정해 보겠습니다.

y=-λy.

λ의 크기가 증가함에 따라 방정식의 경직성도 커집니다. 시간 구간 [0 0.5]에서 λ=1×109과 초기 조건 y(0)=1을 사용합니다. 이들 값을 사용하는 경우 ode45ode23으로 방정식을 적분하는 것이 쉽지 않을 만큼 문제의 경직성이 강합니다. 또한, odeset을 사용하여 상수 야코비 행렬 J=fy=-λ를 전달하고 솔버 통계량 표시를 설정합니다.

lambda = 1e9;
y0 = 1;
tspan = [0 0.5];
opts = odeset('Jacobian',-lambda,'Stats','on');

ode15s, ode23s, ode23t, ode23tb를 사용하여 방정식을 풉니다. 비교를 위해 서브플롯을 만듭니다.

subplot(2,2,1)
tic, ode15s(@(t,y) -lambda*y, tspan, y0, opts), toc
104 successful steps
1 failed attempts
212 function evaluations
0 partial derivatives
21 LU decompositions
210 solutions of linear systems
Elapsed time is 1.016343 seconds.
title('ode15s')
subplot(2,2,2)
tic, ode23s(@(t,y) -lambda*y, tspan, y0, opts), toc
63 successful steps
0 failed attempts
191 function evaluations
0 partial derivatives
63 LU decompositions
189 solutions of linear systems
Elapsed time is 0.183604 seconds.
title('ode23s')
subplot(2,2,3)
tic, ode23t(@(t,y) -lambda*y, tspan, y0, opts), toc
95 successful steps
0 failed attempts
125 function evaluations
0 partial derivatives
28 LU decompositions
123 solutions of linear systems
Elapsed time is 0.192325 seconds.
title('ode23t')
subplot(2,2,4)
tic, ode23tb(@(t,y) -lambda*y, tspan, y0, opts), toc
71 successful steps
0 failed attempts
167 function evaluations
0 partial derivatives
23 LU decompositions
236 solutions of linear systems
Elapsed time is 0.268061 seconds.
title('ode23tb')

Figure contains 4 axes objects. Axes object 1 with title ode15s contains 2 objects of type line. Axes object 2 with title ode23s contains 2 objects of type line. Axes object 3 with title ode23t contains 2 objects of type line. Axes object 4 with title ode23tb contains 2 objects of type line.

네 경직성 솔버 모두 성능이 뛰어나지만, 이 특정 문제에 대해서는 ode23s가 가장 적은 개수의 스텝으로 적분을 완료하며 실행 속도도 가장 빠릅니다. 상수 야코비 행렬이 지정되었으므로, 이들 중 어떤 솔버도 해를 구하기 위해서 편도함수를 계산할 필요가 없습니다. ode23s는 보통 각 스텝에서 야코비 행렬을 계산하므로 야코비 행렬을 지정하는 경우 이 솔버를 사용하는 것이 가장 유리합니다.

일반적인 경직성 문제의 경우, 경직성 솔버의 성능은 문제의 형식과 지정된 옵션에 따라 달라집니다. 경직성 문제에 대해 야코비 행렬이나 희소성 패턴을 제공하면 솔버의 효율성은 항상 더 높아집니다. 하지만 경직성 솔버는 야코비 행렬을 각각 다르게 사용하기 때문에 향상되는 정도는 크게 달라질 수 있습니다. 실제로, 연립방정식의 크기가 매우 크거나 여러 번 해를 구해야 하는 경우 실행 시간을 최소화하기 위해 다양한 솔버의 성능을 검토하는 것이 좋습니다.

입력 인수

모두 축소

풀려는 함수로, 적분할 함수를 정의하는 함수 핸들로 지정됩니다.

스칼라 t와 열 벡터 y에 대한 함수 dydt = odefun(t,y)f(t,y)에 대응하는 single이나 double 데이터형의 열 벡터 dydt를 반환해야 합니다. odefun은 입력 인수 ty 모두를 받아야만 하는데, 이는 이 중 하나가 함수에 사용되지 않더라도 마찬가지입니다.

예를 들어, y'=5y3을 풀려면 다음 함수를 사용하십시오.

function dydt = odefun(t,y)
dydt = 5*y-3;
end

연립방정식에 대한 odefun의 출력값은 벡터입니다. 벡터의 각 요소는 한 개 방정식 우변의 계산된 값입니다. 예를 들어, 다음과 같이 두 개로 이루어진 연립방정식이 있다고 가정하겠습니다.

y'1=y1+2y2y'2=3y1+2y2

각 시간 스텝에서 각 방정식의 우변 값을 계산하는 함수는 다음과 같습니다.

function dydt = odefun(t,y)
dydt = zeros(2,1);
dydt(1) = y(1)+2*y(2);
dydt(2) = 3*y(1)+2*y(2);
end

함수 odefun에 추가 파라미터를 제공하는 방법에 대한 자세한 내용은 함수를 파라미터화하기 항목을 참조하십시오.

예: @myFcn

데이터형: function_handle

적분 구간으로, 벡터로 지정됩니다. 최소한, tspan은 초기 시간과 최종 시간을 지정하는, 요소를 2개 가진 벡터 [t0 tf]여야 합니다. t0tf 사이 특정 시간에서의 해를 구하려면 [t0,t1,t2,...,tf] 형식의 더 긴 벡터를 사용해야 합니다. tspan의 요소는 모두 증가하거나 모두 감소해야 합니다.

솔버는 초기 시간 tspan(1)y0으로 주어진 초기 조건을 적용하고 tspan(1)에서 tspan(end)까지의 구간에 대해 적분을 계산합니다.

  • tspan이 두 개의 요소 [t0 tf]를 갖는 경우, 솔버는 구간 내 각 내부 적분 스텝에서 계산된 해를 반환합니다.

  • tspan이 세 개 이상의 요소 [t0,t1,t2,...,tf]를 갖는 경우 솔버는 지정된 지점에서 계산된 해를 반환합니다. 하지만, 솔버가 tspan에 지정된 각 지점으로 정확하게 이동하는 것은 아닙니다. 대신에 솔버는 자체 내부 스텝을 사용하여 해를 계산한 다음에 tspan의 요청된 지점에서 해를 계산합니다. 지정된 지점에서 구해진 해는 각 내부 스텝에서 계산된 해와 동일한 정도의 정확성을 가집니다.

    중간 지점을 여러 개 지정해도 계산의 효율성에는 거의 영향을 미치지 않지만 대규모 방정식 시스템의 경우에는 메모리 관리에 영향을 미칠 수 있습니다.

tspan의 값은 다음과 같이 솔버가 InitialStepMaxStep에 적합한 값을 계산하는 데 사용됩니다.

  • tspan에 여러 개의 중간 지점 [t0,t1,t2,...,tf]가 있는 경우 지정된 지점은 문제의 크기를 나타내며, 이는 솔버에서 사용되는 InitialStep의 값에 영향을 미칠 수 있습니다. 따라서, 솔버에서 구한 해는 tspan을 요소를 2개 가진 벡터, 또는 중간 지점을 갖는 벡터로 지정하는지 여부에 따라 달라질 수 있습니다.

  • tspan의 초기값과 최종 값은 최대 스텝 크기 MaxStep을 계산하는 데 사용됩니다. 따라서, tspan에서 초기값이나 최종 값을 변경하면 솔버가 다른 스텝 시퀀스를 사용하게 되어 해가 바뀔 수 있습니다.

예: [1 10]

예: [1 3 5 7 9 10]

데이터형: single | double

초기 조건으로, 벡터로 지정됩니다. y0odefun에 정의된 각 방정식에 대한 초기 조건을 포함하도록 y0odefun의 벡터 출력값과 길이가 동일해야 합니다.

데이터형: single | double

options 구조체로, 구조체형 배열로 지정됩니다. odeset 함수를 사용하여 options 구조체를 만들거나 수정할 수 있습니다. 각 솔버와 호환되는 옵션 목록은 ODE 옵션 요약 항목을 참조하십시오.

예: options = odeset('RelTol',1e-5,'Stats','on','OutputFcn',@odeplot)1e-5의 상대 허용오차를 지정하고, 솔버 통계량 표시를 설정하고, 해가 계산될 때 해를 플로팅하도록 출력 함수 @odeplot을 지정합니다.

데이터형: struct

출력 인수

모두 축소

계산 지점으로, 열 벡터로 반환됩니다.

  • tspan이 두 개의 요소 [t0 tf]를 포함하는 경우 t는 적분이 수행된 내부 계산 지점을 포함합니다.

  • tspan이 세 개 이상의 요소를 포함하는 경우 ttspan과 동일합니다.

해로, 배열로 반환됩니다. y의 각 행은 대응하는 t의 행에 반환된 값에서 계산된 해에 해당합니다.

이벤트 시간으로, 열 벡터로 반환됩니다. te의 이벤트 시간은 ye로 반환되는 해에 대응되며, ie는 발생한 이벤트를 지정합니다.

이벤트 발생 시 계산된 해로, 배열로 반환됩니다. te의 이벤트 시간은 ye로 반환되는 해에 대응되며, ie는 발생한 이벤트를 지정합니다.

트리거된 이벤트 함수의 인덱스로, 열 벡터로 반환됩니다. te의 이벤트 시간은 ye로 반환되는 해에 대응되며, ie는 발생한 이벤트를 지정합니다.

계산할 구조체로, 구조체형 배열로 반환됩니다. 이 구조체를 deval 함수와 함께 사용하여 구간 [t0 tf] 내에 있는 임의의 지점에서 해를 계산합니다. sol 구조체형 배열은 항상 다음 필드를 포함합니다.

구조체 필드설명

sol.x

솔버에서 선택한 스텝으로 구성된 행 벡터입니다.

sol.y

해입니다. 각 열 sol.y(:,i)에는 시간 sol.x(i)에서 계산된 해가 포함됩니다.

sol.solver

솔버 이름입니다.

또한, odesetEvents 옵션을 지정한 상태에서 이벤트가 발견되면 sol은 다음 필드도 포함합니다.

구조체 필드설명

sol.xe

이벤트가 발생한 지점입니다. sol.xe(end)는 종료 이벤트(있을 경우)의 정확한 지점을 포함합니다.

sol.ye

sol.xe의 이벤트에 대응하는 해입니다.

sol.ie

Events 옵션에 지정된 함수가 반환하는 벡터에 대한 인덱스입니다. 이러한 값은 솔버가 감지한 이벤트를 나타냅니다.

알고리즘

ode23s는 수정된 2차의 로젠브록(Rosenbrock) 공식을 기반으로 합니다. 이는 단일 스텝(Single-step) 솔버이므로 엄격하지 않은 허용오차를 허용하는 문제나 급격히 달라지는 해를 갖는 문제를 풀 때 ode15s보다 더 효율적일 수 있습니다. 이 솔버는 ode15s가 효과적이지 않은 일부 유형의 경직성 문제를 풀 수 있습니다. ode23s 솔버는 각 적분 스텝에서 야코비 행렬을 계산하므로, 야코비 행렬에 대한 정보를 제공하는 것이 안정성과 효율성 측면에서 매우 중요합니다[1].

참고 문헌

[1] Shampine, L. F. and M. W. Reichelt, “The MATLAB ODE Suite,” SIAM Journal on Scientific Computing, Vol. 18, 1997, pp. 1–22.

버전 내역

R2006a 이전에 개발됨