خانه / fd / روش اویلر — از صفر تا صد

روش اویلر — از صفر تا صد

در آموزش‌های قبلی از مجموعه مباحث ریاضیات مجله فرادرس، با معادلات دیفرانسیل آشنا شدیم و درباره برخی از روش‌های تحلیلی حل انواع مختلف آن‌ها بحث کردیم. علاوه بر روش‌های تحلیلی، با استفاده از روش‌های عددی نیز می‌توان جواب معادلات دیفرانسیل را محاسبه کرد. روش اویلر، روشی عددی برای حل معادلات دیفرانسیل است. در این آموزش، روش اویلر (Euler Method) یا رونگه-کوتای مرتبه اول (First Order Runge–Kutta) را معرفی می‌کنیم.

روش اویلر

روش اویلر یا رونگه کوتای مرتبه اول، ریاضیات بسیار ساده‌ای دارد و می‌توان آن را به سادگی درک کرد. فرض کنید معادله دیفرانسیل مرتبه اول زیر و شرایط اولیه معلوم $$ y (t _ 0 ) = y _ 0 $$ را داریم:

$$ large { { d y ( t ) } over { d t } } = y ^ prime left ( t right ) = f ( y ( t ) , t ) $$

تقریب مشتق را به صورت زیر می‌نویسیم:

$$ large k _ 1 = y ^ prime left ( t right ) = f ( y ^ * ( t ) , t ) $$

بسط تیلور $$ y (t) $$ را حول $$ t _ 0$$ و با فرض گام زمانی $$h$$ می‌نویسیم:

$$ large y ( { t _ 0 } + h ) = y ( { t _ 0 } ) + y ^ prime ( {t _ 0 } ) h + y ^ {prime prime } ( { t _ 0 } ) { { { h ^ 2 } } over 2 } + cdots $$

در عبارت بالا، از جملات بعد از جمله خطی (جملاتی با توان دو و بالاتر) صرفنظر می‌کنیم. بنابراین، عبارت بالا را به صورت زیر می‌نویسیم:

$$ large y ( { t _ 0 } + h ) approx y ( { t _ 0 } ) + y ^ prime ( { t _ 0 } ) h $$

در نتیجه، می‌توانیم جواب تقریبی را در گام زمانی بعدی به صورت زیر به دست آوریم:

$$ large y ^ * ( { t _ 0 } + h ) = y ^ * ( { t _ 0 } ) + { k _ 1 } h $$

در ادامه، روش اویلر را برای انواع معادلات دیفرانسیل و در قالب مثال بیان می‌کنیم.

معادله دیفرانسیل خطی همگن

فرض کنید می‌خواهیم با استفاده از کامپیوتر، جواب معادله دیفرانسیل زیر را به دست آوریم:

$$ large { { d y ( t ) } over { d t } } + 2 y ( t ) = 0 $$

یا

$$ large { { d y ( t ) } over { d t } } = – ۲ y ( t ) $$

که شرط اولیه آن، $$y (0 ) = 3 $$ است. در این حالت، جواب دقیق به صورت $$ y ( t) = 3 e ^ { – ۲ t } $$ برای $$ t ge 0 $$ است. این جواب در شکل زیر رسم شده است. با دانستن جواب دقیق، می‌توانیم جواب تقریبی خود را با آن مقایسه کنیم.

نمودار جواب معادله

راه‌های مختلفی برای به دست آوردن جواب تقریبی وجود دارد. در اینجا از بسط تیلور $$ y ( t) $$ حول $$t=0$$ استفاده می‌کنیم (در حالت کلی، این بسط حول نقطه $$ t = t _ 0 $$ است). بسط تیلور تابع به صورت زیر است:‌

$$ large y ( t ) = y ( 0 ) + y ^ prime ( 0 ) t + y ^ { prime prime } ( 0 ) { { { t ^ 2 } } over 2 } + cdots $$

اکنون جواب را به گام زمانی کوچک $$h$$ بعد از $$t =0 $$ محدود کرده و بسط تیلور را تا مشتق اول در نظر می‌گیریم. بنابراین، داریم:

$$ large eqalign {
& y ( h ) = y ( 0 ) + y^ prime ( 0 ) h + y ^ {prime prime } ( 0 ){ { { h ^ 2 } } over 2 } + cdots cr
& y ( h ) approx y ( 0 ) + y ^ prime ( 0 ) h cr } $$

در ادامه، تقریب جواب را $$ y ^ * (h) $$ و مشتق آن را $$ y ^ prime ( 0 ) = k _ 1 $$ می‌نامیم.

$$ large y ^ * ( h ) = y ( 0 ) + { k _ 1 } h $$

شکل زیر، نمودار جواب را برای $$ h = 0.2 $$ نشان می‌دهد.

نمودار جواب تقریبی

نمودار سمت راست، ناحیه سایه زده شده نمودار سمت چپ را با بزرگنمایی نشان می‌دهد. تقریب تیلور مرتبه اول، یک خط راست است که از مقدار اولیه شروع شده و شیب آن $$-۶$$ است (یعنی $$ k _ 1 = y ^ prime ( 0 ) = -2 y (0) = – ۶ $$).

تقریب در $$ t= h = 0.2 $$ برابر با حاصل‌ جمع مقدار اولیه و ضرب شیب در گام زمانی $$h$$ است:

$$ large y ^ * ( h ) = y ^ * ( 0 .2 ) = y ( 0 ) + { k _ 1} y ^ prime (0) = 1.8$$

واضح است که هرچه $$h$$ کوچکتر باشد، تقریب بهتر و دقیق‌تر خواهد بود.

برای پیدا کردن تقریب گام بعدی $$ y ^ * ( 2 h ) $$، به سادگی فرایند را تکرار کرده و از مقدار قبلی $$ y ^ * ( h ) $$ برای تخمین مشتق در زمان $$h$$ استفاده می‌کنیم (مقدار دقیق $$ y ( h ) $$ را نمی‌دانیم؛ بنابراین، فقط می‌توانیم مشتق ($$ k _ 1 $$) را محاسبه کنیم). ترتیب انجام مراحل به صورت زیر است:

عبارت دقیق مشتق: $$ large y ^ prime ( t ) = – ۲ y ( t ) $$

تقریب مشتق: $$ large { k _ 1 } = – ۲ y ^ * ( h ) $$

سری تیلور حول $$t = h $$: $$ large y ( 2 h ) = y ( h ) + y ^ prime ( h ) h + y ^ { prime prime }( h ) { { { h ^ 2 } } over 2 } + cdots $$

بسط تیلور بریده: $$ large y ( 2 h ) approx y ( h ) + y ^ prime ( 0 ) h $$

جواب تقریبی: $$ large y ^ * ( 2 h ) = y ^ * ( h ) + { k _ 1 } h $$

حرکت به سمت جلو از زمان $$ t _0 $$ تا $$ t_0 + h $$ در حالت کلی به صورت زیر خواهد بود:

عبارت دقیق مشتق در $$ t = t_0$$: $$ large y ^ prime ( t_0 ) = – ۲ y ( t_0 ) $$

تقریب مشتق با استفاده از تقریب قبلی $$ y (t ) $$: $$ large { k _ 1 } = – ۲ y ^ * ( t_0 ) $$

سری تیلور حول $$t = t _ 0 $$: $$ large y ( t_0 + h ) = y ( t _ 0 ) + y ^ prime ( t _ 0 ) h + y ^ { prime prime }( t _ 0 ) { { { h ^ 2 } } over 2 } + cdots $$

بسط تیلور بریده: $$ large y ( t _ 0 + h ) approx y ( t_ 0) + y ^ prime ( t_ 0 ) h $$

جواب تقریبی: $$ large y ^ * ( t _ 0 +h ) = y ^ * ( t _ 0 ) + { k _ 1 } h $$

پیاده‌سازی در متلب

محاسباتی را که گفته شد، می‌توان با استفاده از نرم‌افزار متلب پیاده‌سازی کرد. برنامه مثال عددی بالا در متلب، به صورت زیر است:

%% Example 1 % Solve y'(t)=-2y(t) with y0=3 y0 = 3;                  % Initial Condition h = 0.2;% Time step t = 0:h:2;               % t goes from 0 to 2 seconds. yexact = 3*exp(-2*t)     % Exact solution (in general we won't know this) ystar = zeros(size(t));  % Preallocate array (good coding practice)  ystar(1) = y0;           % Initial condition gives solution at t=0. for i=1:(length(t)-1)     k1 = -2*ystar(i);  % Previous approx for y gives approx for derivative     ystar(i+1) = ystar(i) + k1*h; % Approximate solution for next value of y end plot(t,yexact,t,ystar); legend('Exact','Approximate');

می‌توانیم به سادگی برای مقایر مختلف $$h$$، جواب تقریبی را به دست آورده و با جواب اصلی مقایسه کنیم. شکل زیر، نمودار جواب واقعی و تقریبی را به ازای مقادیر مختلف $$h$$ نشان می‌دهد. همان‌طور که مشاهده می‌کنیم، با کاهش مقدار $$h$$، جواب تقریبی به جواب واقعی نزدیکتر می‌شود.

مقایسه جواب دقیق و تقریبی

خلاصه الگوریتم

برای به دست آوردن جواب تقریبی معادله دیفرانسیلِ

$$ large { { d y ( t ) } over { d t } } = f ( y ( t ) , t ) $$

به روش رونگه-کوتای مرتبه اول، از نقطه $$t _0 $$ شوع کرده و با گام زمانی $$ h $$، مراحل زیر را به ترتیب طی می‌کنیم:

تقریب مشتق: $$ large { k _ 1 } = f ( { y ^ * } { rm { ( } } { { rm{ t }} _ 0 } ) , { t _0 } ) $$

تقریب جواب در گام زمانی بعدی: $$ large { y ^ * } ( { t _ 0 } + h ) = { y ^ * } ( { t _ 0 } ) + { k _ 1 } h $$

داشتن مقدار اولیه برای شروع الگوریتم، ضروری است.

معادله دیفرانسیل مرتبه اول ناهمگن

اگر معادله مرتبه اول، ورودی داشته باشد، یا اصطلاحاً ناهمگن باشد، مشکلی خاصی برای جواب تقریبی وجود ندارد، اما یافتن جواب دقیق یا واقعی سخت‌تر خواهد شد. مثال زیر را در نظر بگیرید:

$$ large y ^ prime ( t ) + 2 y ( t ) = cos ( 4 t ) $$

یا

$$ large y ^ prime ( t ) = – ۲ y ( t ) + cos ( 4 t ) $$

برای به دست آوردن جواب تقریبی، مراحل زیر را طی می‌کنیم:

عبارت دقیق مشتق در $$ t = t _0 $$: $$ large y ^ prime ( { t _ 0 } ) = – ۲ y ( { t _ 0 } ) + cos ( 4 { t _ 0 } ) $$

تقریب مشتق: $$ large { k _ 1 } = – ۲ y ^ * ( { t _ 0 } ) + cos ( 4 { t _ 0 } ) $$

بسط تیلور حول $$ t = t _0 $$: $$ large y ( { t _ 0 } + h ) = y ( { t _ 0 } ) + y ^ prime ( { t _ 0 } ) h + y ^ { prime prime } ( { t _ 0 } ) { { { h ^ 2 } } over 2 } + cdots $$

بسط تیلور بریده: $$ large y ( { t _ 0 } + h ) approx y ( { t _ 0 } ) + y ^ prime ( { t _ 0 } ) h $$

جواب تقریبی: $$ large y ^ * ( { t _ 0 } + h ) = y ^ * ( { t _ 0 } ) + { k _ 1 } h $$

جواب دقیق این مثال $$ y ( t ) = 2.9 { e ^ { – ۲ { kern 1 pt } t } } + 0.1 cos ( 4 t ) + 0.2 sin ( 4 t ) $$ است.

پیاده‌سازی در متلب

برای پیاده‌سازی محاسبات بالا، می‌توانیم از نرم‌افزار متلب استفاده کنیم. دقت کنید که در محاسبات، مقدار $$k_1$$ تغییر می‌کند.

%% Example 2 % Solve y'(t)=-2y(t)+cos(4t) with y0=3 y0 = 3;                  % Initial Condition h = 0.2;% Time step t = 0:h:2;               % t goes from 0 to 2 seconds. % Exact solution, hard to find in this case (in general we won't have it) yexact = 0.1*cos(4*t)+0.2*sin(4*t)+2.9*exp(-2*t); ystar = zeros(size(t));  % Preallocate array (good coding practice)  ystar(1) = y0;           % Initial condition gives solution at t=0. for i=1:(length(t)-1)     k1 = -2*ystar(i)+cos(4*t(i));  % Previous approx for y gives approx for deriv     ystar(i+1) = ystar(i) + k1*h; % Approximate solution for next value of y end plot(t,yexact,t,ystar); legend('Exact','Approximate');

شکل زیر، نمودار جواب دقیق و جواب‌های تقریبی را برای مقادیر متفاوت $$h$$ نشان می‌دهد. مانند مثال قبل، می‌بینیم که با کاهش $$h$$، جواب تقریبی به جواب دقیق نزدیک می‌شود.

جواب تقریبی و دقیق

معادله دیفرانسیل مرتبه اول غیرخطی

حل معادلات دیفرانسیل غیرخطی به صورت تحلیلی، کار دشواری است. اما در تقریب زدن آن، مشکلی وجود ندارد. معادله دیفرانسیل زیر را در نظر بگیرید.

$$ large { { d y ( t ) } over { d t } } – y ( t ) ( 1 – ۲ t ) = 0 , quad quad quad quad y ( 0 ) = 1 $$

جواب دقیق این معادله به صورت زیر است:

$$ large y ( t ) = { e ^ { t – { t ^ 2 } } } $$

برای به دست آوردن جواب تقریبی، عبارت $$ y ^ prime (t) $$ را نوشته و از آن برای یافتن $$ k _ 1 $$ استفاده می‌کنیم. محاسبات را به صورت زیر انجام می‌دهیم:

عبارت دقیق مشتق در $$ t = t _ 0 $$: $$ large y ^ prime ( { t _ 0 } ) = y ( { t _ 0 } ) ( 1 – ۲ { t _ 0 } ) $$

تقریب مشتق: $$ large { k _ 1 } = y ^ * ( { t _ 0 } ) ( 1 – ۲ { t _ 0 } ) $$

جواب تقریبی: $$ large y ^ * ( { t _ 0 } + h ) = y ^ * ( { t _ 0 } ) + { k _ 1 } h $$

پیاده‌سازی در متلب

مانند مثال‌های قبلی، محاسبات اخیر را می‌توانیم در متلب پیاده‌سازی کنیم. برنامه مربوط به مثال اخیر به صورت زیر است.

%% Example 3 % Solve y'(t)=y(t)(1-2t) with y0=1 y0 = 1;                  % Initial Condition h=0.2;                   % Time step t = 0:h:2;               % t goes from 0 to 2 seconds. % Exact solution, hard to find in this case (in general we won't have it) yexact = exp(t-t.^2); ystar = zeros(size(t));  % Preallocate array (good coding practice)  ystar(1) = y0;           % Initial condition gives solution at t=0. for i=1:(length(t)-1)   k1 = ystar(i)*(1-2*t(i));   % Approx for y gives approx for deriv   ystar(i+1) = ystar(i) + k1*h; % Approximate solution at next value of y end plot(t,yexact,t,ystar); legend('Exact','Approximate');

نمودار جواب دقیق و جواب‌های تقریبی به ازای مقادیر مختلف $$h $$ در شکل زیر نشان داده شده‌اند.

منحنی جواب تقریبی و دقیق

معادله دیفرانسیل مرتبه بالا

روش‌هایی که تاکنون معرفی شد، فقط به معادلات دیفرانسیل مرتبه اول قابل اعمال هستند و در صورتی می‌توان برای معادلات مرتبه بالاتر از آن‌ها استفاده کرد که این نوع معادلات را به فرم معادلات دیفرانسیل ماتریسی مرتبه اول در بیاوریم. معادله دیفرانسیل مرتبه سوم زیر را با شرایط اولیه آن در نظر بگیرید:

$$ large displaylines {
{ { { d ^ 3 } y ( t ) } over { d t } } + 4 { { { d ^ 2 } y ( t ) } over { d t } } + 6 { { d y ( t ) } over { d t } } + 4 y ( t ) = gamma ( t ) quad quad quad cr
{ left . { { {{ d ^ 2 } y ( t ) } over { d t } } } right | _ { t = { 0 ^ + } } } = 0 , quad quad { left . { { { d y ( t ) } over { d t } } } right | _ { t = { 0 ^ + } } } = – ۱ , quad quad y ( { 0 ^ + } ) = 0 quad cr } $$

که در آن، $$gamma (t) $$ تابع پله واحد است.

جواب دقیق این معادله برای $$t ge 0 $$، $$ y ( t ) = { 1 over 4 } + { { rm { e } } ^ { – t } } { mkern 1mu } left ( { cos ( t ) – { ۵ over 2 } sin ( t ) } right ) – { ۵ over 4 } { { rm { e } } ^ { – ۲ { kern 1pt } t } } $$ است.

با تعریف متغیرهای جدید $$q _ 1$$، $$ q _ 2$$ و $$q _ 3$$ معادله دیفرانسیل فوق را با سه معادله مرتبه اول توصیف می‌کنیم:

$$ large eqalign {
{ q _ 1 } ( t ) & = y ( t ) cr
{ q _ 2 } ( t ) & = y ^ prime ( t ) cr
{ q _ 3 } ( t ) & = y ^ { prime prime } ( t ) cr
cr
{ q _ 1 } ^ prime ( t ) & = y ^ prime ( t ) & = { q _ 2 } (t ) cr
{ q _ 2 } ^ prime ( t ) & = y ^ { prime prime } ( t ) & = { q _ 3 } ( t ) cr
{ q _ 3 } ^ prime ( t ) & = y ^ {prime primeprime } ( t ) & = gamma ( t ) – ۴ y ^ { prime prime } ( t ) – ۶ y ^ prime ( t ) – ۴ y ( t ) cr
& & = gamma ( t ) – ۴ { q _ 3 } ( t ) – ۶ { q _ 2 } ( t ) – ۴ { q _ 1 } ( t ) cr } $$

می‌توانیم معادلات فوق را به فرم ساده‌تر ماتریسی زیر بنویسیم:

$$ large eqalign {
{ bf { q } } ^ prime ( t ) & = left [ { matrix {
{ { q _ 1 } ^ prime ( t ) } cr
{ { q _ 2 } ^ prime ( t ) } cr
{ { q _ 3 } ^ prime ( t ) } cr } } right ] = left [ { matrix {
0 & 1 & 0 cr
0 & 0 & 1 cr
{ – ۴ } & { – ۶ } & { – ۴ } cr } } right ] left [ { matrix {
{ { q _ 1 } ( t ) } cr
{ { q _ 2 } ( t ) } cr
{ { q _ 3 } ( t ) } cr } } right ] + left [ { matrix {
0 cr
0 cr
1 cr } } right ] gamma ( t ) cr
{ bf { q } } ^ prime ( t ) & = { bf { A q } } ( t ) + { bf { B gamma } } ( t ) cr
{ bf { A } } & = left [ { matrix {
0 & 1 & 0 cr
0 & 0 & 1 cr
{ – ۴ } & { – ۶ } & { – ۴ } cr } } right ] , quad quad quad { bf { B } } = left [ { matrix {
0 cr
0 cr
1 cr
} } right ] cr } $$

اکنون، مسئله مشابه موارد قبلی است؛ با این تفاوت که متغیرها و مقادیر $$k_1$$، در این حالت بردار هستند:

عبارت دقیق مشتق در $$ t = t_0 $$: $$ large { bf { q } } ^ prime ( { t _ 0 } ) = { bf { A q } } ( { t _ 0 } ) + { bf { B gamma } } ( { t _ 0 } ) $$

تقریب مشتق: $$ large { { bf { k } } _ 1 } = { bf { A } } { { bf { q } } ^ * } ( { t _ 0 } ) + { bf { B gamma } } ( { t _ 0 } ) $$

بسط تیلور حول $$ t = t _0$$: $$ large { bf { q } } ( { t _ 0 } + h ) = { bf { q } } ( { t _ 0 } ) + { bf { q } } ^ prime ( { t _ 0 } ) h + { bf { q } } ^ {prime prime } ( { t _ 0 } ) { { { h ^ 2 } } over 2 } + cdots $$

بسط تیلور بریده: $$ large { bf { q } } ( { t _ 0} + h ) approx { bf { q } } ( { t _ 0 } ) + { bf { q } } ^ prime ( { t _ 0 } ) h $$

جواب تقریبی: $$ large { bf { q } } ^ * ( { t _ 0 } + h ) = { bf { q } } ^ * ( { t _ 0 } ) + { { bf { k } } _ 1 } h $$

پیاده‌سازی در متلب

مانند مثال‌های قبلی، محاسبات اخیر را می‌توانیم در متلب پیاده‌سازی کنیم. برنامه مربوط به این مثال به صورت زیر است:

%% Example 4 % Solve y'''(t)+4y''(t)+6y'(t)+4y(t)=gamma(t),  y''(0)=0, y'(0)=-1, y(0)=0 q0 = [0; -1; 0];         % Initial Condition (vector) h = 0.2;% Time step t = 0:h:5;               % t goes from 0 to 2 seconds. A = [0 1 0; 0 0 1; -4 -6 -4];  % A Matrix B = [0; 0; 1];                 % B Matrix  yexact = 1/4 + exp(-t).*(cos(t) - 5*sin(t)/2) - 5*exp(-2*t)/4;  % Exact soln qstar = zeros(3,length(t));  % Preallocate array (good coding practice)  qstar(:,1) = q0;             % Initial condition gives solution at t=0. for i=1:(length(t)-1)   k1 = A*qstar(:,i)+B*1;            % Approx for y gives approx for deriv   qstar(:,i+1) = qstar(:,i) + k1*h; % Approximate solution at next value of q end plot(t,yexact,t,qstar(1,:));        % ystar = first row of qstar legend('Exact','Approximate'); hold off

نمودار جواب دقیق و جواب‌های تقریبی به ازای مقادیر مختلف $$h $$ در شکل زیر نشان داده شده‌اند.

جواب معادله مرتبه سوم

اگر این مطلب برایتان مفید بوده است، آموزش‌های زیر نیز به شما پیشنهاد می‌شوند:

  • مجموعه آموزش‌های دروس ریاضیات
  • آموزش محاسبات عددی با MATLAB
  • مجموعه آموزش‌های محاسبات عددی
  • آموزش ریاضی پایه دانشگاهی
  • روش نیوتن — به زبان ساده
  • معادله خط — به زبان ساده
  • دستگاه معادلات خطی — به زبان ساده
  • جذر یا محاسبه ریشه دوم عدد — به زبان ساده

^^

بلی خیر

نوشته روش اویلر — از صفر تا صد اولین بار در مجله فرادرس. پدیدار شد.

درباره ی admin

مطلب پیشنهادی

جستجوی تمام متن در لاراول با استفاده از Scout — به زبان ساده

جستجوی تمام متن یک قابلیت ضروری جهت فراهم ساختن امکان حرکت در میان صفحه‌های وب‌سایت‌های با محتوای گسترده است. در این مقاله، شیوه پیاده‌سازی امکان جستجوی تمام متن را برای یک اپلیکیشن لاراول بررسی می‌کنیم. در واقع ما از کتابخانه Scout لاراول استفاده می‌کنیم که پیاده‌سازی جستجوی تمام متن را به امری ساده و جذاب تبدیل کرده است. مستندات رسمی، کتابخانه Scout لاراول را به صورت زیر توصیف می‌کنند: کتابخانه Scout لاراول یک راه‌حل ساده و مبتنی بر درایور برای افزودن امکان جستجوی تمام متن به مدل‌های Eloquent ارائه می‌کند. Scout با استفاده از «مشاهده‌گرهای مدل» (model observers) به طور خودکار اندیس‌های جستجو را در وضعیتی همگام‌سازی شده با رکوردهای Eloquent حفظ می‌کند. کتابخانه Scout لاراول به مدیریت دستکاری اندیس‌ها در زمان بروز تغییراتی در داده‌های مدل می‌پردازد. جایی که داده‌های اندیس می‌شوند به درایوری وابسته است که برای کتابخانه Scout پیکربندی‌شده است. در حال حاضر کتابخانه Scout از Algolia پشتیبانی می‌کند که یک API موتور جستجوی مبتنی بر کلود است و ما نیز در این مقاله از آن برای نمایش پیاده‌سا..

دیدگاهتان را بنویسید

نشانی ایمیل شما منتشر نخواهد شد. بخش‌های موردنیاز علامت‌گذاری شده‌اند *