روش رانگ کوتا مرتبه چهارم (RK4) — از صفر تا صد (+ دانلود فیلم آموزش گام به گام)
در محاسبات عددی یا همان آنالیز عددی (Numerical Analysis)، «روشهای رانگ کوتا» (Runge–Kutta Methods) (روشهای رونگه کوتا نیز به آن گفته میشود) خانوادهای از روشهای تکرار شدنی «صریح و ضمنی» (Explicit and Implicit Methods) هستند. یکی از این روشها، یعنی رانگ کوتای مرتبه اول با عنوان «روش اویلر» نیز شناخته شده و از محبوبیت قابل توجهی برخوردار است. روشهای رانگ کوتا برای «گسستهسازی زمانی» (Temporal Discretization) جهت تخمین راه حلهای «معادلات دیفرانسیل معمولی» (Ordinary Differential Equations) مورد استفاده قرار میگیرند. این روشها در حدود سال ۱۹۰۰ توسط دو ریاضیدان آلمانی به نامهای «کارل رانگ» (Carl Runge) و «ویلهلم کوتا» (Wilhelm Kutta) ساخته شده است. شناخته شدهترین روش از خانواده روشهای رانگ کوتا، RK4، رانگ کوتای کلاسیک و یا روش رانگ کوتای مرتبه چهارم است که به طور خلاصه به آن روش رانگ کوتا گفته میشود. در این مطلب، به روش رانگ کوتا پرداخته شده و کد پیادهسازی آن در زبانهای گوناگون ارائه شده است. همچنین، برای درک بهتر مطلب، مثال هایی از حل معادلات دیفرانسیل با روش رانگ کوتا ارائه شده و پیادهسازی آن در زبان برنامهنویسی «متلب» (MATLAB) انجام شده است.
روش رانگ کوتا مرتبه چهارم
ورودیهای زیر وجود دارند:
- یک معادلات دیفرانسیل معمولی که مقدار dy/dx را به شکل x و y تعریف میکند.
- مقدار اولیه y (یعنی (0)y)
بدین ترتیب، معادله زیر وجود دارد.
اکنون، باید مقدار تابع ناشناخته y در نقطه x را به دست آورد. روش رانگ کوتا مقدار تقریبی y برای یک x داده شده را پیدا میکند. تنها، معادلات دیفرانسیل معمولی مرتبه اول را میتوان با استفاده از روش رانگ کوتا مرتبه چهارم حل کرد. در زیر، فرمول مورد استفاده برای محاسبه مقدار بعدی yn+1 از مقدار پیشین yn به دست میآید. مقدار n برابر است. در اینجا، h طول هر گام و xn+1 = x0 + h است. طول گام کمتر به معنای صحت بیشتر است.
فرمول بالا اساسا مقدار بعدی yn+1 را با استفاده از yn کنونی، همراه با میانگین چهار افزایش محاسبه میکند.
- k1 افزایش بر پایه شیب در آغاز بازه با استفاده از y است.
- k2 افزایش بر پایه شیب در نقطه میانی بازه با استفاده از y + hk1/2 است.
- k3 افزایش بر پایه نقطه میانی با استفاده از y + hk2/2 است.
- k4 افزایش بر پایه شیب در پایان بازه با استفاده از y + hk3 است.
متد بیان شده در بالا، روش مرتبه چهارم است. بدین معنا که خطای برش محلی از مرتبه (O(h5 است؛ در حالی که خطای کلی تجمیع شده از مرتبه (O(h4 است. در ادامه، پیادهسازی این متد در زبانهای برنامهنویسی «پایتون» (Python)، «جاوا» (Java)، «سی» (C) و «سیپلاسپلاس» (++C)، «پیاچپی» (PHP) و «سیشارپ» (#C) ارائه شده است.
کد روش رانگ کوتا در پایتون
پیاده سازی این متد در زبان برنامه نویسی پایتون را در ادامه مشاهده میکنیم.
1# Python program to implement Runge Kutta method
2# A sample differential equation "dy / dx = (x - y)/2"
3def dydx(x, y):
4 return ((x - y)/2)
5
6# Finds value of y for a given x using step size h
7# and initial value y0 at x0.
8def rungeKutta(x0, y0, x, h):
9 # Count number of iterations using step size or
10 # step height h
11 n = (int)((x - x0)/h)
12 # Iterate for number of iterations
13 y = y0
14 for i in range(1, n + 1):
15 "Apply Runge Kutta Formulas to find next value of y"
16 k1 = h * dydx(x0, y)
17 k2 = h * dydx(x0 + 0.5 * h, y + 0.5 * k1)
18 k3 = h * dydx(x0 + 0.5 * h, y + 0.5 * k2)
19 k4 = h * dydx(x0 + h, y + k3)
20
21 # Update next value of y
22 y = y + (1.0 / 6.0)*(k1 + 2 * k2 + 2 * k3 + k4)
23
24 # Update next value of x
25 x0 = x0 + h
26 return y
27
28# Driver method
29x0 = 0
30y = 1
31x = 2
32h = 0.2
33print 'The value of y at x is:', rungeKutta(x0, y, x, h)
34
35# This code is contributed by Prateek Bhindwar
کد روش رانگ کوتا در جاوا
در این بخش پیاده سازی کد روش رانگ کوتا در جاوا را بررسی میکنیم.
1// Java program to implement Runge Kutta method
2import java.io.*;
3class differential
4{
5 double dydx(double x, double y)
6 {
7 return ((x - y) / 2);
8 }
9
10 // Finds value of y for a given x using step size h
11 // and initial value y0 at x0.
12 double rungeKutta(double x0, double y0, double x, double h)
13 {
14 differential d1 = new differential();
15 // Count number of iterations using step size or
16 // step height h
17 int n = (int)((x - x0) / h);
18
19 double k1, k2, k3, k4, k5;
20
21 // Iterate for number of iterations
22 double y = y0;
23 for (int i = 1; i <= n; i++)
24 {
25 // Apply Runge Kutta Formulas to find
26 // next value of y
27 k1 = h * (d1.dydx(x0, y));
28 k2 = h * (d1.dydx(x0 + 0.5 * h, y + 0.5 * k1));
29 k3 = h * (d1.dydx(x0 + 0.5 * h, y + 0.5 * k2));
30 k4 = h * (d1.dydx(x0 + h, y + k3));
31
32 // Update next value of y
33 y = y + (1.0 / 6.0) * (k1 + 2 * k2 + 2 * k3 + k4);
34
35 // Update next value of x
36 x0 = x0 + h;
37 }
38 return y;
39 }
40
41 public static void main(String args[])
42 {
43 differential d2 = new differential();
44 double x0 = 0, y = 1, x = 2, h = 0.2;
45
46 System.out.println("\nThe value of y at x is : "
47 + d2.rungeKutta(x0, y, x, h));
48 }
49}
50
51// This code is contributed by Prateek Bhindwar
کد روش رانگ کوتا در C++/C
در این بخش پیاده سازی کد رانگ کوتا در زبان برنامه نویسی C و سی پلاس پلاس را مشاهده میکنیم.
1// C program to implement Runge Kutta method
2#include<stdio.h>
3
4// A sample differential equation "dy/dx = (x - y)/2"
5float dydx(float x, float y)
6{
7 return((x - y)/2);
8}
9
10// Finds value of y for a given x using step size h
11// and initial value y0 at x0.
12float rungeKutta(float x0, float y0, float x, float h)
13{
14 // Count number of iterations using step size or
15 // step height h
16 int n = (int)((x - x0) / h);
17
18 float k1, k2, k3, k4, k5;
19
20 // Iterate for number of iterations
21 float y = y0;
22 for (int i=1; i<=n; i++)
23 {
24 // Apply Runge Kutta Formulas to find
25 // next value of y
26 k1 = h*dydx(x0, y);
27 k2 = h*dydx(x0 + 0.5*h, y + 0.5*k1);
28 k3 = h*dydx(x0 + 0.5*h, y + 0.5*k2);
29 k4 = h*dydx(x0 + h, y + k3);
30
31 // Update next value of y
32 y = y + (1.0/6.0)*(k1 + 2*k2 + 2*k3 + k4);;
33
34 // Update next value of x
35 x0 = x0 + h;
36 }
37
38 return y;
39}
40
41// Driver method
42int main()
43{
44 float x0 = 0, y = 1, x = 2, h = 0.2;
45 printf("\nThe value of y at x is : %f",
46 rungeKutta(x0, y, x, h));
47 return 0;
48}
کد روش رانگ کوتا در PHP
در ادامه کد متد رانگ کوتا در PHP را مشاهده میکنیم.
1<?php
2// PHP program to implement
3// Runge Kutta method
4
5// A sample differential equation
6// "dy/dx = (x - y)/2"
7function dydx($x, $y)
8{
9 return(($x - $y) / 2);
10}
11
12// Finds value of y for a
13// given x using step size h
14// and initial value y0 at x0.
15function rungeKutta($x0, $y0, $x, $h)
16{
17
18 // Count number of iterations
19 // using step size or step
20 // height h
21 $n = (($x - $x0) / $h);
22
23 $k1; $k2; $k3; $k4; $k5;
24
25 // Iterate for number
26 // of iterations
27 $y = $y0;
28 for($i = 1; $i <= $n; $i++)
29 {
30
31 // Apply Runge Kutta
32 // Formulas to find
33 // next value of y
34 $k1 = $h * dydx($x0, $y);
35 $k2 = $h * dydx($x0 + 0.5 * $h,
36 $y + 0.5 * $k1);
37 $k3 = $h * dydx($x0 + 0.5 * $h,
38 $y + 0.5 * $k2);
39 $k4 = $h * dydx($x0 + $h, $y + $k3);
40
41 // Update next value of y
42 $y = $y + (1.0 / 6.0) * ($k1 + 2 *
43 $k2 + 2 * $k3 + $k4);;
44
45 // Update next value of x
46 $x0 = $x0 + $h;
47 }
48
49 return $y;
50}
51
52 // Driver method
53 $x0 = 0;
54 $y = 1;
55 $x = 2;
56 $h = 0.2;
57 echo "The value of y at x is : ",
58 rungeKutta($x0, $y, $x, $h);
59
60// This code is contributed by anuj_67.
61?>
کد روش رانگ کوتا در #C
در آخرین بخش کد روش رانگ کوتا در سی شارپ را مورد بررسی قرار میدهیم.
1// C# program to implement Runge
2// Kutta method
3using System;
4
5class GFG {
6
7 static double dydx(double x, double y)
8 {
9 return ((x - y) / 2);
10 }
11
12 // Finds value of y for a given x
13 // using step size h and initial
14 // value y0 at x0.
15 static double rungeKutta(double x0,
16 double y0, double x, double h)
17 {
18
19 // Count number of iterations using
20 // step size or step height h
21 int n = (int)((x - x0) / h);
22
23 double k1, k2, k3, k4;
24
25 // Iterate for number of iterations
26 double y = y0;
27
28 for (int i = 1; i <= n; i++)
29 {
30
31 // Apply Runge Kutta Formulas
32 // to find next value of y
33 k1 = h * (dydx(x0, y));
34
35 k2 = h * (dydx(x0 + 0.5 * h,
36 y + 0.5 * k1));
37
38 k3 = h * (dydx(x0 + 0.5 * h,
39 y + 0.5 * k2));
40
41 k4 = h * (dydx(x0 + h, y + k3));
42
43 // Update next value of y
44 y = y + (1.0 / 6.0) * (k1 + 2
45 * k2 + 2 * k3 + k4);
46
47 // Update next value of x
48 x0 = x0 + h;
49 }
50
51 return y;
52 }
53
54 // Driver code
55 public static void Main()
56 {
57
58 double x0 = 0, y = 1, x = 2, h = 0.2;
59
60 Console.WriteLine("\nThe value of y"
61 + " at x is : "
62 + rungeKutta(x0, y, x, h));
63 }
64}
65
66// This code is contributed by Sam007.
خروجی
در کد بالا، به ازای y=1، x=2، x0=0 و h=0.2، خروجی به صورت زیر خواهد بود. باید به این نکته نیز توجه کرد که پیچیدگی روش ارائه شده در بالا برابر با (O(n است که در آن، n برابر با x-x0)/h) است.
The value of y at x is : 1.103639
حل معادله دیفرانسیل با روش رانگ کوتا مرتبه چهارم و پیادهسازی در متلب
در ادامه، دو مثال ارائه شده است که طی آنها، یک معادله دیفرانسیل با روش رانگ کوتا مرتبه چهارم حل و پیادهسازی آن در زبان برنامهنویسی متلب انجام شده است.
مثال اول
برنامهای بنویسید که معادله دیفرانسیل زیر را با طول گام دلخواه حل کند.
حل معادله دیفرانسیل بالا با روش رانگ کوتا مرتبه چهارم و پیادهسازی آن با زبان برنامهنویسی متلب انجام شده است.
1clc;
2clear;
3close all;
4%%
5h = 0.1 ;
6t = 0:h:2 ;
7x = t ;
8Nt = numel(t) ;
9y = zeros(1 , Nt) ; y(1) = 0.5 ;
10f = @(t , y) y - t^2 +1 ;
11
12for i = 1:Nt-1
13 K1 = h * f(x(i) , y(i)) ;
14 K2 = h * f(x(i)+h/2 , y(i)+K1/2) ;
15 K3 = h * f(x(i)+h/2 , y(i)+K2/2) ;
16 K4 = h * f(x(i)+h , y(i)+K3) ;
17 y(i+1) = y(i) + 1/6*(K1 + 2*K2 + 2*K3+K4) ;
18end
19
20yr = (1+t).^2-0.5.*exp(t);
21
22
23figure(1) ;
24subplot(211);
25plot(t , yr , t , y , 'LineWidth' , 3) ;
26xlabel('t'); ylabel('y') ;
27grid on
28legend('Real Y' , 'App Y');
29
30subplot(212);
31plot(t , yr-y , 'LineWidth' , 3) ;
32xlabel('t'); ylabel('error') ;
33grid on
34legend('Error');
مثال دوم
برنامهای بنویسید که معادله دیفرانسیل زیر را با طول گام دلخواه حل کند.
حل معادله دیفرانسیل بالا با روش رانگ کوتا مرتبه چهارم و پیادهسازی آن با زبان برنامهنویسی متلب انجام شده است.
1clc;
2clear;
3close all;
4%%
5h = 0.1;
6x = 0:h:5 ;
7Nt = numel(x) ;
8y = zeros(2 , Nt) ; y(: , 1) = [0.5;0] ;
9f = @(x , y) [y(2) ; x*y(1)];
10
11for i = 1:Nt-1
12 K1 = h * f(x(i) , y(: , i)) ;
13 K2 = h * f(x(i)+h/2 , y(: , i)+K1/2) ;
14 K3 = h * f(x(i)+h/2 , y(: , i)+K2/2) ;
15 K4 = h * f(x(i)+h , y(: , i)+K3) ;
16 y(: , i+1) = y(: , i) + 1/6*(K1 + 2*K2 + 2*K3+K4) ;
17end
18
19figure(1) ;
20plot(x , y , 'LineWidth' , 3) ;
21xlabel('x'); ylabel('y') ;
22grid on
23legend('Y1 = z(x)' , 'Y2 = dot Z(x)');
اگر نوشته بالا برای شما مفید بوده است، آموزشهای زیر نیز به شما پیشنهاد میشوند:
- مجموعه آموزشهای دروس ریاضیات
- آموزش محاسبات عددی با MATLAB
- مجموعه آموزشهای محاسبات عددی
- آموزش ریاضی پایه دانشگاهی
- معادلات دیفرانسیل — به زبان ساده
- روش نیوتن — به زبان ساده
^^
معادلات مرتبه بالاتر رو چطور میشه به روش رانگ کوتا مرتبه4 کدنویسی متلب کرد؟
مثلا معادله نقطه سکون در سیالات که هست:
f(3) +f*f(2)-f(1)^2+1=0 ;
با سلام. من یک سوالی داشتم. برای معادله دیفرانسیل مرتبه دو باید چکار کنم؟ یعنی معادله ای به شکل زیر:
d^2(x)/dt^2+(c/m)*dx/dt+(k/m)*x
این یک معادله ارتعاشی می باشد و برابر با صفر می باشد. ممنون میشم اگر راهنمای ی بفرمایید.
سلام.
برای آشنایی با روش حل آن، پیشنهاد میکنیم به آموزش «معادلات دیفرانسیل مرتبه دوم — به زبان ساده (+ دانلود فیلم آموزش گام به گام)» مراجعه کنید.
موفق باشید.
متشکر میشم کد متلبی را نیز برای آن ارسال کنید. با تشکر
سلام.
کد متلب این روش در فیلم آموزشی انتهای متن ارائه شده است.
سالم و موفق باشید.
سلام از دوستان کسی حل دستی معادله بلازیوس به روش رانگ کوتا را داره؟
سلام عالی هستیننننن خدا حفظتون کنه واقعا
چقدرم خوب درس میدین
با سلام و خسته نباشید.
ببخشید توی مثال اول اگر (y(t بشه (30-y(t یا هر عدد به جای 30 اونوقت باید چکار کنیم.
سلام کاش برا معادله دیفرانسیل مرتبه سوم هم میزاشتین خیلی بدردم میخوره
و برای شرایط مرزی اگه 0=(بینهایت)”y بجای 0=(0)”y بدن چی میشه؟
ممنون میشم بگین
سلام. برای یادگیری روش حل معادله دیفرانسیل مرتبه سوم، پیشنهاد میکنیم دو مطلب «روش اویلر — از صفر تا صد (+ دانلود فیلم آموزش گام به گام)» و «روش رانگ کوتای مرتبه دوم — از صفر تا صد» را مطالعه کنید.
از همراهیتان با مجله فرادرس خوشحالیم.
سلام.
کد متلب نمونه مثال شما رو اماده کردم .
انشالله که مفدی واقع بشه.
%% Runge Kutta method
clc
clear all
close all
%% Driver method
x0 = 0;
y = 1;
x = 2;
h = 0.2;
y = rk4(x0, y, x, h);
xi = linspace(x0,x,(x-x0)/h);
display(sprintf(‘The value of y at x is : %f ‘, y(end)));
plot(xi,y);
xlabel(‘x’)
ylabel(‘f(x,y)’)
%% A sample differential equation
%% “dy/dx = (x – y)/2”
function f = dydx(x,y)
f = (x-y) / 2;
end
%% Finds value of y for a
%% given x using step size h
%% and initial value y0 at x0.
function f_xi = rk4(x0, y0, x, h)
%% Count number of iterations
%% using step size or step
%% height h
n = ((x – x0) / h);
%% Iterate for number
%% of iterations
y = y0;
for i = 1:n
%% Apply Runge Kutta
%% Formulas to find
%% next value of y
k1 = h * dydx(x0, y);
k2 = h * dydx(x0 + 0.5 *h,y + 0.5 *k1);
k3 = h * dydx(x0 + 0.5 *h,y + 0.5 * k2);
k4 = h * dydx(x0 + h, y + k3);
%% Update next value of y
f(i) = y;
y = y + (1.0 / 6.0) * (k1 + 2*k2 + 2 *k3 + k4);
%% Update next value of x
x0 = x0 + h;
f_xi(i) = y;
end
end
% plot([x0:h:x],f_xi);
سلام کسی معادله y’1 = y’2 _ y’3 میتونه برحسب زمان انجام بده
با سلام و تشکر بخاطر نشر مطالب علمی
کد متلب مثال بالا رو برای استفاده دوستان میزارم :
%% Runge Kutta method
%% Driver method
x0 = 0;
y = 1;
x = 2;
h = 0.2;
display(sprintf(‘The value of y at x is : %f ‘, rk4(x0, y, x, h)))
%% A sample differential equation
%% “dy/dx = (x – y)/2”
function f = dydx(x,y)
f = (x-y) / 2;
end
%% Finds value of y for a
%% given x using step size h
%% and initial value y0 at x0.
function y = rk4(x0, y0, x, h)
%% Count number of iterations
%% using step size or step
%% height h
n = ((x – x0) / h);
%% Iterate for number
%% of iterations
y = y0;
for i = 1:n
%% Apply Runge Kutta
%% Formulas to find
%% next value of y
k1 = h * dydx(x0, y);
k2 = h * dydx(x0 + 0.5 *h,y + 0.5 *k1);
k3 = h * dydx(x0 + 0.5 *h,y + 0.5 * k2);
k4 = h * dydx(x0 + h, y + k3);
%% Update next value of y
y = y + (1.0 / 6.0) * (k1 + 2*k2 + 2 *k3 + k4);
%% Update next value of x
x0 = x0 + h;
end
end