Main Content

ode78

비경직성(Nonstiff) 미분방정식 풀기 — 고차수법(High Order Method)

R2021b 이후

설명

예제

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

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

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

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

예제

모두 축소

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

다음 ODE를 풉니다.

y=2t.

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

tspan = [0 5];
y0 = 0;
[t,y] = ode78(@(t,y) 2*t, tspan, y0);

해를 플로팅합니다.

plot(t,y,'-o')

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

반데르폴 방정식은 2계 ODE입니다.

y1-μ(1-y12)y1+y1=0,

여기서 μ>0는 스칼라 파라미터입니다. 대입 y1=y2를 수행하여 이 방정식을 연립 1계 ODE로 재작성합니다. 결과로 생성되는 1계 연립 ODE는 다음과 같습니다.

y1=y2y2=μ(1-y12)y2-y1.

함수 파일 vdp1.mμ=1를 사용하여 반데르폴 방정식을 나타냅니다. 변수 y1y2는 요소를 2개 가진 벡터 dydt의 항목 y(1)y(2)에 해당합니다.

function dydt = vdp1(t,y)
%VDP1  Evaluate the van der Pol ODEs for mu = 1
%
%   See also ODE113, ODE23, ODE45.

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

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

초기값 [2 0]을 사용하고 시간 구간 [0 20]에 대해 ode78 함수를 사용하여 ODE를 풉니다. 결과로 생성되는 출력값은 시간 지점 t로 구성된 열 벡터와 해 배열 y입니다. y의 각 행은 t의 해당 행에 반환된 시간에 대응됩니다. y의 첫 번째 열은 y1에 대응되고, 두 번째 열은 y2에 대응됩니다.

[t,y] = ode78(@vdp1,[0 20],[2; 0]);

t에 대해 y1y2의 해를 플로팅합니다.

plot(t,y(:,1),'-o',t,y(:,2),'-o')
title('Solution of van der Pol Equation (\mu = 1) with ODE78');
xlabel('Time t');
ylabel('Solution y');
legend('y_1','y_2')

Figure contains an axes object. The axes object with title Solution of van der Pol Equation ( mu blank = blank 1) with ODE78, xlabel Time t, ylabel Solution y contains 2 objects of type line. These objects represent y_1, y_2.

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

다음 ODE를 풉니다.

y=ABty.

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

y1=y2y2=ABty1.

이 예시의 끝에 나와 있는 로컬 함수 odefcn은 이 연립방정식을 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);
end

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

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

결과를 플로팅합니다.

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

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

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

ode45에 비해 ode113, ode78, ode89 솔버가 엄격한 허용오차를 갖는 문제를 푸는 데 더 효과적입니다. 보통 이러한 솔버가 탁월한 성능을 보이는 경우는 해 곡선이 매끄럽고 솔버의 각 스텝에서 높은 정확성을 요하는 궤도 역학 문제를 다룰 때입니다.

2체 문제(Two-body problem)는 공통의 평면을 선회하는 두 개의 상호 작용하는 물체 m1m2가 있다고 가정합니다. 이 예제에서는 한 물체가 다른 물체보다 훨씬 더 큽니다. 무거운 물체가 원점에 있는 경우 운동 방정식은 다음과 같습니다.

x=-x/r3y=-y/r3,

여기서

r=x2+y2.

이 문제를 풀려면, 먼저 다음과 같이 대입을 사용하여 4개의 1계 ODE로 이루어진 시스템으로 변환해야 합니다.

y1=xy2=xy3=yy4=y.

이러한 대입을 마치면 다음과 같은 1계 시스템이 생성됩니다.

y1=y2y2=-y1/r3y3=y4y4=-y3/r3.

이 예시의 끝에 포함된 로컬 함수 twobodyode는 2체 문제에 대한 연립방정식을 작성합니다.

function dy = twobodyode(t,y)
% Two-body problem with one mass much larger than the other.
r = sqrt(y(1)^2 + y(3)^2);
dy = [y(2); 
     -y(1)/r^3;
      y(4);
     -y(3)/r^3];
end

ode78을 사용하여 연립 ODE를 풉니다. RelTol에는 1e-13, AbsTol에는 1e-14의 엄격한 허용오차를 지정합니다.

opts = odeset('Reltol',1e-13,'AbsTol',1e-14,'Stats','on');
tspan = [0 10*pi];
y0 = [2 0 0 0.5];
[t,y] = ode78(@twobodyode, tspan, y0, opts);
341 successful steps
0 failed attempts
5797 function evaluations
plot(t,y)
legend('x','x''','y','y''','Location','SouthEast')
title('Position and Velocity Components')

Figure contains an axes object. The axes object with title Position and Velocity Components contains 4 objects of type line. These objects represent x, x', y, y'.

figure
plot(y(:,1),y(:,3),'-o',0,0,'ro')
axis equal
title('Orbit of Smaller Mass')

Figure contains an axes object. The axes object with title Orbit of Smaller Mass contains 2 objects of type line. One or more of the lines displays its values using only markers

ode45에 비해 ode78 솔버는 더 적은 횟수의 스텝과 함수 계산을 수행하여 더욱 빠르게 해를 구할 수 있습니다.

function dy = twobodyode(t,y)
% Two-body problem with one mass much larger than the other.
r = sqrt(y(1)^2 + y(3)^2);
dy = [y(2); 
    -y(1)/r^3;
    y(4);
    -y(3)/r^3];
end

입력 인수

모두 축소

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

스칼라 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 옵션에 지정된 함수가 반환하는 벡터에 대한 인덱스입니다. 이러한 값은 솔버가 감지한 이벤트를 나타냅니다.

알고리즘

ode78은 Verner의 "가장 효율적인" 룽게-쿠타 8(7) 쌍을 7차 연속적 확장으로 구현한 것입니다. 이 해는 8차까지 일반화됩니다. 7차 연속적 확장은 4번의 추가적인 odefun 계산이 필요하지만 보간이 필요한 스텝에서만 계산됩니다.

참고 문헌

[1] Verner, J. H. “Numerically Optimal Runge–Kutta Pairs with Interpolants.” Numerical Algorithms 53, no. 2–3 (March 2010): 383–396. https://doi.org/10.1007/s11075-009-9290-3.

확장 기능

버전 내역

R2021b에 개발됨