روش رانگ کوتای مرتبه دوم – از صفر تا صد

سید سراج حمیدی
سید سراج حمیدی
۱۴۰۲/۰۲/۱۳
۲۸ دقیقه
۴۴۴۷
آموزش متنی جامع
در آموزش‌های پیشین مجله فرادرس، با روش رانگ کوتای مرتبه اول و مرتبه چهارم آشنا شدیم. در این آموزش، روش رانگ کوتای مرتبه دوم (Second Order Runge-Kutta) را برای حل معادلات دیفرانسیل معرفی خواهیم کرد.
روش رانگ کوتای مرتبه دوم – از صفر تا صد
997696

تعریف مسئله

معادله دیفرانسیل زیر با جواب y(t)y ( t) را در نظر بگیرید:

dy(t)dt=y′(t)=f(y(t),t),  y(t0)=y0\large { { d y ( t ) } \over { d t } } = y' ( t ) = f ( y ( t ) , t ) , \quad \quad { \rm{\;}} y ( t _0 ) = y _ 0

می‌خواهیم جواب y(t)y ( t) را با کامپیوتر تقریب بزنیم (با دانستن شرایط اولیه y(t0)=y0y ( t _ 0 ) = y _ 0). در ادامه، یک روش شهودی برای انجام این کار ارائه کرده و مثال‌هایی را نیز بررسی می‌کنیم. این روش همان روش رانگ کوتای مرتبه دوم است.

روش رانگ کوتای مرتبه دوم

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

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

همان‌طور که در آموزش‌های پیشین گفتیم، در روش رانگ کوتای مرتبه اول، از مشتق در زمان t0t _ 0 (در شکل زیر t0=0t _ 0 = 0) برای تخمین مقدار تابع در یک گام زمانی بعد استفاده می‌شود. برای مثال، معادله دیفرانسیل زیر را در نظر بگیرید:

dy(t)dt+2y(t)=0\large { { d y ( t ) } \over { d t } } + 2 y( t ) = 0   یا  dy(t)dt=−2y(t)\large { { d y ( t ) } \over { d t } } = - 2 y ( t )

که شرایط اولیه آن y(0)=3y ( 0 ) = 3 است. جواب دقیق این معادله y(t)=3e−2ty ( t) = 3 e ^ {-2t} برای t≥0t \ge 0 است که فرض می‌کنیم آن را نمی‌دانیم و برای ارائه یک تقریب به انتگرال‌گیری عددی نیاز داریم.

در شکل زیر، شیب در t=0t = 0 را k1k _ 1 و تخمین را y∗(h)y^* ( h ) می‌نامیم که در این مثال، h=0.2h = 0.2 است.

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

بدیهی است که مقداری خطای تخمین وجود دارد که می‌خواهیم آن را کم کنیم. یکی از راه‌های نیل به این هدف، استفاده از مشتق در نقطه میانی بین t=0t = 0 و t=h=0.2t = h = 0.2 است. شیب در این نقطه (t=12h=0.1t = \frac{1}{2}h=0.1) در شکل زیر نشان داده شده و با k2k _ 2 مشخص شده است. خط نارنجی نیز، در واقع خط مماس بر منحنی آبی در t=12ht = \frac{1}{2} h است.

خط مماس بر منحنی

اکنون اگر از شیب میانی k2k _ 2 استفاده کنیم، تخمین بهتری نسبت به قبل برای y∗(h)y ^ * ( h ) خواهیم داشت. در شکل زیر، مقدار دقیق جواب y(0.1)=2.0110y (0.1) = 2.0110 و همچنین، تقریب y∗(0.1)=2.0175y ^ * (0.1) = 2.0175 برای خطایی در حدود 0.30.3 درصد نشان داده شده‌اند. دقت کنید که در روش رانگ کوتای مرتبه اول، این خطا تقریباً 1010 درصد است.

تقریب با رونگه کوتای مرتبه دوم

به نظر می‌رسد جواب تقریب بسیار مناسبی دارد و بدیهی است که دقت آن نسبت به جواب به دست آمده از روش رانگ کوتای مرتبه اول (که در آن از خطی با شیب k1k _ 1 در t=0t = 0 استفاده می‌شد) بسیار بیشتر است. مسئله‌ای که با آن مواجهیم، این است که مقدار دقیق y(12h)y ( \frac{1}{2} h ) را نمی‌دانیم و به همین دلیل نمی‌توانیم مقدار دقیق k2k _ 2 را بیابیم. لازم به یادآوری است که محاسبه مشتق نیازمند دانستن مقدار تابع است (y′(t)=−2y(t)y' ( t ) = - 2 y ( t)).

یک راه برای حل این مشکل، استفاده از روش اویلر یا همان روش رانگ کوتای مرتبه اول برای به دست آوردن تقریب y(t)y ( t) در t=12h=0.1t = \frac{1}{2} h = 0.1 است که آن را y1(12h)y _ 1 ( \frac{1}{2} h ) می‌نامیم. سپس می‌توانیم از این تخمین برای به دست آوردن k2k _ 2 (که تقریبی از شیب در نقطه میانی است) استفاده کنیم و در نتیجه، از k2k _ 2 برای یافتن y∗(t)y ^* ( t) بهره ببریم. برای رفتن از نقطه شروع در t=0t = 0 تا تخمین در t=ht = h، فرایند زیر را انجام می‌دهیم:

عبارت مشتق در t=0t = 0:    y′(0)=−2y(0)\large y' ( 0 ) = - 2 y ( 0)

مشتق در t=0t = 0:    k1=−2y(0)\large { k _ 1 } = - 2 y ( 0 )

تخمین میانی تابع در t=h/2t = h / 2:    y1(h2)=y(0)+k1h2\large { y _ 1 } \left ( { { h \over 2 } } \right ) = y ( 0 ) + { k _ 1 } { h \over 2 }

تخمین شیب در t=h/2t = h / 2:    k2=−2y1(h2)\large { k _ 2 } = - 2 { y _ 1 } \left ( { { h \over 2 } } \right )

سری تیلور حول t=0t = 0:    y(h)=y(0)+y′(0)h+y′′(0)h22+⋯\large y ( h ) = y ( 0 ) + y' ( 0 ) h + y^{\prime \prime } ( 0 ) { { { h ^ 2 } } \over 2 } + \cdots

سری تیلور بریده:    y(t)≈y(0)+y′(0)h\large y ( t ) \approx y ( 0 ) + y' ( 0 ) h

تخمین y(h)y ( h):    y∗(h)=y(0)+k2h\large { y ^ * } ( h ) = y ( 0 ) + { k _ 2 } h

در حالت کلی، یک گام به جلو از تخمین t=t0t = t _ 0 تا t=t0+ht = t _ 0 + h به صورت زیر انجام می‌شود:

عبارت مشتق در t=t0t = t _ 0:    y′(t0)=−2y(t0)\large y' ( t _ 0 ) = - 2 y ( t _0)

مشتق در t=t0t = t _ 0:    k1=−2y(t0)\large { k _ 1 } = - 2 y ( t _ 0 )

تخمین میانی تابع در t=t0+h/2t = t _ 0 + h / 2:    y1(t0+h/2)=y(t0)+k1h2\large { y _ 1 } \left ( { {t _ 0 + h / 2 } } \right ) = y ( t_0 ) + { k _ 1 } { h \over 2 }

تخمین شیب در t=t0+h/2t = t _ 0 + h / 2:    k2=−2y1(t0+h/2)\large { k _ 2 } = - 2 { y _ 1 } \left ( { { t _ 0 + h / 2 } } \right )

سری تیلور حول t=t0t = t _ 0:    y(t0+h)=y(t0)+y′(t0)h+y′′(t0)h22+⋯\large y ( t _ 0 + h ) = y ( t _ 0 ) + y' ( t _ 0 ) h + y^{\prime \prime } ( t _ 0 ) { { { h ^ 2 } } \over 2 } + \cdots

سری تیلور بریده:    y(t)≈y(t0)+y′(t0)h\large y ( t ) \approx y ( t _ 0 ) + y' ( t _ 0 ) h

تخمین y(t0+h)y ( t _ 0 + h):    y∗(t0+h)=y(t0)+k2h\large { y ^ * } ( t _ 0 + h ) = y ( t _ 0 ) + { k _ 2 } h

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

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

هر خط از کد بالا به خوبی مراحل الگوریتم را نشان می‌دهد. با تغییر اندکی در برنامه، می‌توان اثر اندازه hh را بر دقت جواب مشاهده کرد. شکل زیر این موضوع را به خوبی نشان می‌دهد. همان‌طور که می‌بینیم، هرچه مقدار hh بزرگ‌تر باشد، تقریب ضعیف‌تر خواهد بود.

تقریب رونگه کوتای مرتبه دو

الگوریتم روش رانگ کوتای مرتبه دوم (نقطه میانی)

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

dy(t)dt=f(y(t),t)\large { { d y ( t ) } \over { d t } } = f ( y ( t ) , t )

برای حرکت رو به جلوی یک نقطه در t=t0t = t _ 0، یعنی y∗(t0)y ^ * ( t _ 0 )، به اندازه یک گام زمانی hh، مراحل زیر را طی می‌کنیم:

تخمین مشتق در t=t0t = t _ 0:    k1=f(y∗(t0),  t0)\large { k _ 1 } = f ( { y ^ * } ( { t _ 0 } ) , \; { t _ 0 } )

تخمین میانی تابع در t=t0+h2t = t _ 0 + \frac { h } { 2 }:    y1(t0+h2)=y∗(t0)+k1h2\large { y _ 1 } \left ( { { t _ 0 } + { h \over 2 } } \right ) = { y ^ * } ( { t _ 0 } ) + { k _ 1 } { h \over 2 }

تخمین شیب در t=t0+h2t = t _ 0 + \frac {h } { 2 }:    k2=f(y1(t0+h2),  t0+h2)\large { k _ 2 } = f \left ( { { y _ 1 } \left ( { { t _ 0 } + { h \over 2 } } \right ) , \; { t _ 0 } + { h \over 2 } } \right )

تخمین y(t0+h)y ( t _ 0 + h ):    y∗(t0+h)=y∗(t0)+k2h\large { y ^ * } \left ( { { t _ 0 } + h } \right ) = { y ^ * } ( { t _ 0 } ) + { k _ 2 } h

دقت کنید که مقدار اولیه یا همان شرایط اولیه در ابتدای الگوریتم مشخص باشد.

از الگوریتم رانگ کوتای مرتبه دوم اغلب با نام الگوریتم نقطه میانی (Midpoint Algorithm) یاد می‌شود، زیرا از شیب k2k_ 2 در نقطه میانی استفاده می‌کند.

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

با اضافه شدن تابع ورودی به معادله دیفرانسیل، مشکل چندانی به وجود نخواهد آمد. فقط لازم است مقدار تابع در t=t0t = t _ 0 را برای یافتن k1k _ 1 و همچنین، مقدار آن را در t=t0+12ht = t _ 0 + \frac { 1 } { 2 } h برای یافتن k2k _ 2 تضمین کنیم. برای مثال، ورودی cos⁡(4t)\cos ( 4 t ) را در نظر بگیرید.

y′(t)+2y(t)=cos⁡(4t)\large y' ( t ) + 2 y ( t ) = \cos ( 4 t )   یا  y′(t)=−2y(t)+cos⁡(4t)\large y' ( t ) = - 2 y ( t ) + \cos ( 4 t )

بنابراین، مراحل زیر را طی می‌کنیم:

عبارت مشتق در t=t0t = t _ 0:      y′(t0)=−2y(t0)+cos⁡(4t0)\large y' ( { t _ 0 } ) = - 2 y ( { t _ 0 } ) + \cos ( 4 { t _ 0 } )

تقریب مشتق در t=t0t= t _ 0:    k1=−2y∗(t0)+cos⁡(4t0)\large { k _ 1 } = - 2 { y ^ * } ( { t _ 0 } ) + \cos ( 4 { t _ 0 } )

تخمین میانی تابع در t=t0+h/2t = t _ 0 + h / 2:    y1(t0+h2)=y∗(t0)+k1h2\large { y _ 1 } \left ( { { t _ 0 } + { h \over 2 } } \right ) = { y ^ * } ( { t _ 0 } ) + { k _ 1 } { h \over 2 }

تخمین شیب در t=t0+h/2t = t _ 0 + h / 2:    k2=−2y1(t0+h2)+cos⁡(t0+h2)\large { k _ 2 } = - 2 { y _ 1 } \left ( { { t _ 0 } + { h \over 2 } } \right ) + \cos \left ( { { t _ 0 } + { h \over 2 } } \right )

تخمین y(t0+h)y ( t _ 0 + h ):    y∗(t0+h)=y(t0)+k2h\large { y ^ * } ( { t _ 0 } + h ) = y ( { t _ 0 } ) + { k _ 2 } h

گفتنی است که جواب دقیق این معادله y(t)=2.9e−2t+0.1cos⁡(4t)+0.2sin⁡(4t)y ( t ) = 2 . 9 { e ^ { - 2 { \kern 1pt} t } } + 0 . 1 \cos ( 4 t ) + 0 . 2 \sin ( 4 t ) است.

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

می‌توانیم از متلب برای محاسبات بالا استفاده کنیم. برای این تقریب جدید، باید محاسبات k1k _ 1 و k2k _ 2 را با استفاده از مقدار مناسب متغیر زمان تغییر دهیم. برنامه زیر در متلب مربوط به مثال اخیر است.

با کمی تغییر در برنامه بالا، می‌توانیم تقریب را برای hhهای مختلف رسم کنیم. همان‌طور که می‌بینیم، با کوچک شدن hh، تقریب‌ها دقیق‌تر خواهند بود.

مقایسه تقریب‌ها

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

در این مورد نیز با مشکل خاصی مواجه نخواهیم بود. در اینجا نیز باید تضمین کنیم که مقدار تابع در t=t0t = t _ 0 را برای یافتن k1k _ 1 و همچنین، مقدار آن را در t=t0+12ht = t _ 0 + \frac { 1 } { 2 } h برای یافتن k2k _ 2 داریم. برای مثال، سیستم زیر را در نظر بگیرید:

dy(t)dt−y(t)(1−2t)=0,y(0)=1\large { { d y ( t ) } \over { d t } } - y ( t ) ( 1 - 2 t ) = 0 , \quad \quad y ( 0 ) = 1

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

y(t)=et−t2\large y ( t ) = { e ^ { t - { t ^ 2 } } }

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

عبارت مشتق در t=t0t = t _ 0:      y′(t0)=y(t0)(1−2t0)\large y' ( { t _ 0 } ) = y ( { t _ 0 } ) ( 1 - 2 { t _ 0 } )

تقریب مشتق در t=t0t= t _ 0:    k1=y∗(t0)(1−2t0)\large { k _ 1 } = y ^ * ( { t _ 0 } ) ( 1 - 2 { t _ 0 } )

تخمین میانی تابع در t=t0+h/2t = t _ 0 + h / 2:    y1(t0+h2)=y∗(t0)+k1h2\large { y _ 1 } \left ( { { t _ 0 } + { h \over 2 } } \right ) = { y ^ * } ( { t _ 0 } ) + { k _ 1 } { h \over 2 }

تخمین شیب در t=t0+h/2t = t _ 0 + h / 2:    k2=−2y1(t0+h2)(1−2(t0+h2))\large { k _ 2 } = - 2 { y _ 1 } \left ( { { t _ 0 } + { h \over 2 } } \right ) \left ( { 1 - 2 \left ( { { t _ 0 } + { h \over 2 } } \right ) } \right )

تخمین y(t0+h)y ( t _ 0 + h ):    y∗(t0+h)=y(t0)+k2h\large { y ^ * } ( { t _ 0 } + h ) = y ( { t _ 0 } ) + { k _ 2 } h

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

مانند مثال‌های قبل، به سادگی می‌توانیم برنامه تقریب معادله دیفرانسیل غیرخطی مرتبه اول با ورودی را در متلب بنویسیم. این برنامه به صورت زیر است:

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

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

همان‌طور که مشاهده می‌کنیم، با کاهش hh، دقت تقریب زیاد می‌شود.

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

معادله دیفرانسیل مرتبه بالاتر زیر را در نظر بگیرید:

$$ \large \displaylines {<br /> { { { 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 \gamma ( t ) = { \rm{unit step function}} \cr<br /> { \left . { { { { d ^ 2 } y ( t ) } \over { d t } } } \right | _ { t = { 0 ^ + } } } = 0 , \quad \quad { \left. { { { d y ( t ) } \over { d t } } } \right | _ { t = { 0 ^ + } } } = - 1 , \quad \quad y ({ 0 ^ + } ) = 0 \quad \cr } $$

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

بر اساس رای ۶ نفر
آیا این مطلب برای شما مفید بود؟
اگر پرسشی درباره این مطلب دارید، آن را با ما مطرح کنید.
منابع:
Erik Cheever
PDF
مطالب مرتبط
نظر شما چیست؟

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