Professional Documents
Culture Documents
24 Nguyen Thanh Trung 03
24 Nguyen Thanh Trung 03
24 Nguyen Thanh Trung 03
- Source code
#include<stdio.h>
#include<conio.h>
#include<math.h>
/*
Định nghĩa phương trình cần giải.
Thay đổi phương trình này để giải quyết vấn đề khác.
*/
#define f(x) x*cos(x) - 2*x*x +3*x -1
void main()
{
float x0, x1, x2, f0, f1, f2, e;
int step = 1;
printf("\nNhập hai giá trị đoán ban đầu:\n");
scanf("%f%f", &x0, &x1);
printf("Nhập sai số có thể chấp nhận:\n");
scanf("%f", &e);
/* Tính giá trị hàm số */
f0 = f(x0);
f1 = f(x1);
/* Kiểm tra xem hai giá trị đoán có nằm cùng một phía của nghiệm hay không.
*/
if (f0 * f1 > 0.0)
{
printf("Giá trị đoán ban đầu không chính xác.\n");
}
/* Thực hiện Phương pháp Chia Đôi */
printf("\nBước\t\tx0\t\tx1\t\tx2\t\tf(x2)\n");
do
{
x2 = (x0 + x1) / 2;
f2 = f(x2);
if (f0 * f2 < 0)
{
x1 = x2;
f1 = f2;
}
else
{
x0 = x2;
f0 = f2;
}
step = step + 1;
} while (fabs(f2) > e);
printf("\nNghiệm là: %f", x2);
}
#include<stdio.h>
#include <math.h>
#include<stdlib.h>
// Định nghĩa hàm f(x) cần giải
#define f(x) x*x*x*x + 2*x*x - x -3
int main() {
int step = 1, N;
float x0, x1, e;
// Nhập dữ liệu
printf("Nhập giá trị đoán ban đầu: ");
scanf("%f", &x0);
printf("Nhập sai số chấp nhận được: ");
scanf("%f", &e);
printf("Nhập số lần lặp tối đa: ");
scanf("%d", &N);
if (step > N) {
printf("Không hội tụ.\n");
exit(0);
}
x0 = x1;
} while (fabs(f(x1)) > e);
- Soulution
3. Phương pháp điểm sai
a. Thuật toán và source code bài toán phương pháp điểm sai
1. Khởi tạo và Đầu vào:
- Khai báo các biến x0, x1 (giá trị đoán ban đầu), x2 (nghiệm tìm
được), f0, f1, f2 (giá trị hàm số tại các điểm tương ứng), và e (sai số có thể
chấp nhận).
- Nhập giá trị đoán ban đầu và sai số có thể chấp nhận từ người dùng.
2. Tính toán Giá trị Hàm số:
- Tính giá trị hàm số tại x0 và x1 sử dụng định nghĩa hàm f(x).
3. Kiểm tra Giá trị Đoán:
- Kiểm tra xem hai giá trị đoán x0 và x1 có bao quanh nghiệm hay không bằng
cách nhân f0 và f1. Nếu tích lớn hơn 0, thông báo rằng giá trị đoán không
chính xác.
4. Lặp để Tìm Nghiệm:
- Thực hiện vòng lặp do-while với điều kiện là giá trị tuyệt đối của f2 lớn hơn
sai số e.
- Trong mỗi lần lặp:
o Tính x2 sử dụng công thức Regula Falsi.
o Tính f2 tại x2 mới này.
o In ra bước hiện tại và các giá trị x0, x1, x2, f(x2).
o Cập nhật x0 hoặc x1 dựa trên dấu của f0 * f2.
o Tăng số bước lên 1.
5. Kết quả:
- Khi điều kiện dừng của vòng lặp được thỏa mãn, tức là f2 nhỏ hơn hoặc bằng
sai số e, in ra nghiệm x2.
- Ví dụ: sử dụng phương pháp Điểm sai để tìm nghiệm có độ chính xác 10-6
cho bài toán
#include<stdio.h>
#include<conio.h>
#include<math.h>
/* Định nghĩa phương trình cần giải.
Thay đổi phương trình này để giải quyết vấn đề khác. */
#define f(x) x – cos(x)
int main()
{
float x0, x1, x2, f0, f1, f2, e;
int step = 1;
printf("\nNhập hai giá trị đoán ban đầu:\n");
scanf("%f%f", &x0, &x1);
printf("Nhập sai số có thể chấp nhận:\n");
scanf("%f", &e);
/* Tính toán Giá trị Hàm số */
f0 = f(x0);
f1 = f(x1);
/* Kiểm tra xem các giá trị đoán có bao quanh nghiệm hay không. */
if (f0 * f1 > 0.0)
{
printf("Giá trị đoán ban đầu không chính xác.\n");
}
/* Thực hiện Phương pháp Điểm Sai */
printf("\nBước\t\tx0\t\tx1\t\tx2\t\tf(x2)\n");
do
{
x2 = x0 - (x0 - x1) * f0 / (f0 - f1);
f2 = f(x2);
printf("%d\t\t%f\t%f\t%f\t%f\n", step, x0, x1, x2, f2);
if (f0 * f2 < 0)
{
x1 = x2;
f1 = f2;
}
else
{
x0 = x2;
f0 = f2;
}
step = step + 1;
- Soulution
4. Phương pháp Newton
a. Bài toán
- Tìm nghiệm của phương tình f(x) = 4 * sin(x) - exp(x)
1. Định nghĩa phương trình và đạo hàm của nó:
- Phương trình: f(x) = 4 * sin(x) - exp(x)
- Đạo hàm: g(x) = 4 * cos(x) - exp(x)
2. Chọn giá trị đoán ban đầu (x0) và sai số có thể chấp nhận ( e ).
3. Thực hiện các bước lặp theo phương pháp Newton-Raphson:
- Tính giá trị hàm (f(x0) ) và đạo hàm ( g(x0) ).
- Kiểm tra điều kiện dừng: Nếu (|f ( x 0 )|≤ e), nghiệm đã được tìm thấy.
f ( x 0)
- Cập nhật giá trị (x0) bằng công thức: x 1=x 0− .
g (x 0)
- Lặp lại các bước trên cho đến khi điều kiện dừng được thỏa mãn hoặc số lần
lặp vượt quá giới hạn cho phép.
/* Chương trình: Tìm nghiệm thực của phương trình phi tuyến bằng phương pháp
Newton-Raphson */
#include <stdio.h>
#include <conio.h>
#include <math.h>
#include <stdlib.h>
void main()
{
float x0, x1, f0, f1, g0, e;
int step = 1, N;
printf("----------------------------------------------------\n\n");
printf("Tìm nghiệm bằng phương pháp NEWTON-RAPHSON\n\n");
printf("----------------------------------------------------\n\n");
/* Nhập liệu */
printf("\nNhập giá trị đoán ban đầu:\n");
scanf("%f", &x0);
printf("Nhập sai số có thể chấp nhận:\n");
scanf("%f", &e);
printf("Nhập số lần lặp tối đa:\n");
scanf("%d", &N);
/* Thực hiện phương pháp Newton Raphson */
printf("\nBước\t\tx0\t\tf(x0)\t\tx1\t\tf(x1)\n");
do
{
g0 = g(x0);
f0 = f(x0);
if (g0 == 0.0)
{
printf("Lỗi Toán học.");
exit(0);
}
x1 = x0 - f0 / g0;
step = step + 1;
if (step > N)
{
printf("Không hội tụ.");
exit(0);
}
f1 = f(x1);
printf("\nNghiệm theo phương pháp Newton-Raphson sau %d lần lặp là: %f",
step - 1, x1);
getch();
}
- Lặp lại các bước trên cho đến khi điều kiện dừng được thỏa mãn hoặc số lần
lặp vượt quá giới hạn cho phép.
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<stdlib.h>
void main()
{
float x0, x1, x2, f0, f1, f2, e;
int step = 1, N;
x0 = x1;
f0 = f1;
x1 = x2;
f1 = f2;
step = step + 1;
if (step > N)
{
printf("Không hội tụ.");
exit(0);
}
} while (fabs(f2) > e);
2x+3y−z4 =5
x+y+2z = 6
−3x+2y+4z = 10
[ ] []
2 3 −1 5
A= 4 1 2 , B= 6
−3 2 4 10
- Sử dụng chương trình bạn đã cung cấp, nhập ma trận ( A ) vào chương trình
khi được yêu cầu.
- Chương trình sẽ thực hiện các phép biến đổi hàng để chuyển ma trận ( A )
thành ma trận đơn vị ( I ), và phần mở rộng của nó sẽ trở thành ma trận nghịch
đảo ( A^{-1} ).
- Nghiệm của hệ phương trình có thể được tìm thấy bằng cách nhân ma trận
nghịch đảo ( A^{-1} ) với ma trận cột ( B ):
−1
X =A B
- So sánh kết quả thu được từ chương trình với phương pháp giải thủ công hoặc
sử dụng máy tính để đảm bảo tính chính xác.
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<stdlib.h>
#define SIZE 10
int main()
{
float a[SIZE][SIZE], x[SIZE], ratio;
int i, j, k, n;
return(0);
}
[ ]
3 21∨1
2−2 4∨−2
−1 0.5−1∨0
- Sử dụng chương trình bạn đã cung cấp, nhập ma trận tăng cường vào chương trình khi
được yêu cầu.
- Chương trình sẽ thực hiện các phép biến đổi hàng để chuyển ma trận tăng cường thành
dạng bậc thang rồi thực hiện thay thế ngược để tìm giải pháp cho hệ phương trình.
- So sánh kết quả thu được từ chương trình với phương pháp giải thủ công hoặc sử dụng
máy tính để đảm bảo tính chính xác.
#include<stdio.h>
#include<conio.h>
#include<math.h>
#include<stdlib.h>
#define SIZE 10
int main()
{
float a[SIZE][SIZE], x[SIZE], ratio;
int i, j, k, n;
return(0);
}
3. Phương pháp tìm ma trận nghịch đảo sử dụng phương pháp Gauss – Jordan
a. Bài toán
Ví du:
[ ]
3 21∨1
2−2 4∨−2
−1 0.5−1∨0
- Sử dụng chương trình bạn đã cung cấp, nhập ma trận ( A ) vào chương trình khi
được yêu cầu.
- Chương trình sẽ thực hiện các phép biến đổi hàng để chuyển ma trận ( A ) thành
ma trận đơn vị ( I ), và phần mở rộng của nó sẽ trở thành ma trận nghịch đảo
( A^{-1} ).
- Nghiệm của hệ phương trình có thể được tìm thấy bằng cách nhân ma trận
nghịch đảo ( A^{-1} ) với ma trận cột ( B ):
X=A^−1*B
- So sánh kết quả thu được từ chương trình với phương pháp giải thủ công hoặc sử
dụng máy tính để đảm bảo tính chính xác.
#include<stdio.h>
#include<conio.h>
#include<math.h>
#define SIZE 10
int main()
{
float a[SIZE][SIZE], x[SIZE], ratio;
int i, j, k, n;
/* 1. Đọc cấp của ma trận */
printf("Nhập cấp của ma trận: ");
scanf("%d", &n);
/* 2. Đọc Ma trận */
printf("Nhập hệ số của Ma trận:\n");
for (i = 1;i <= n;i++)
{
for (j = 1;j <= n;j++)
{
printf("a[%d][%d] = ", i, j);
scanf("%f", &a[i][j]);
}
}
/* Bổ sung Ma trận Đơn vị cấp n */
for (i = 1;i <= n;i++){
for (j = 1;j <= n;j++){
if (i == j){
a[i][j + n] = 1;
}else
{
a[i][j + n] = 0;
}
}
}
/* Áp dụng Phương pháp loại trừ Gauss Jordan */
for (i = 1;i <= n;i++)
{
if (a[i][i] == 0.0)
{
printf("Lỗi Toán học!");
break;
}
for (j = 1;j <= n;j++)
{
if (i != j)
{
ratio = a[j][i] / a[i][i];
for (k = 1;k <= 2 * n;k++)
{
a[j][k] = a[j][k] - ratio * a[i][k];
}
}
}
}
/* Thao tác hàng để làm cho Đường chéo chính thành 1 */
for (i = 1;i <= n;i++)
{
for (j = n + 1;j <= 2 * n;j++)
{
a[i][j] = a[i][j] / a[i][i];
}
}
/* Hiển thị Ma trận Nghịch đảo */
printf("\nMa trận Nghịch đảo là:\n");
for (i = 1;i <= n;i++)
{
for (j = n + 1;j <= 2 * n;j++)
{
printf("%0.3f\t", a[i][j]);
}
printf("\n");
}
return(0);
}
1. Định nghĩa các hàm lặp tương ứng với mỗi biến:
40− y+ 5 z
o f 1 ( x , y , z )=
20
−18−3 x +44 z
o f 2 ( x , y , z )=
20
25−2 x +3 z
o f 3 ( x , y , z )=
20
2. Chọn giá trị ban đầu cho ( x ), ( y ), và ( z ). Trong trường hợp này, giá trị ban
đầu là 0 cho cả ba biến.
3. Thực hiện lặp:
o Tính giá trị mới cho mỗi biến dựa trên giá trị hiện tại của các biến khác.
o Kiểm tra sai số giữa giá trị mới và giá trị cũ cho mỗi biến.
o Tiếp tục lặp cho đến khi sai số cho mỗi biến nhỏ hơn sai số có thể chấp
nhận được ( e ).
4. In ra kết quả:
o Khi sai số đủ nhỏ, in ra giá trị của ( x ), ( y ), và ( z ) là nghiệm của hệ
phương trình.
#include<stdio.h>
#include<conio.h>
#include<math.h>
int main()
{
float x0 = 0, y0 = 0, z0 = 0, x1, y1, z1, e1, e2, e3, e;
int count = 1;
printf("\nLần\tX\tY\tZ\n");
do
{
/* Tính toán */
x1 = f1(x0, y0, z0);
y1 = f2(x0, y0, z0);
z1 = f3(x0, y0, z0);
printf("%d\t%0.4f\t%0.4f\t%0.4f\n", count, x1, y1, z1);
/* Sai số */
e1 = fabs(x0 - x1);
e2 = fabs(y0 - y1);
e3 = fabs(z0 - z1);
count++;
/* Đặt giá trị cho lần lặp tiếp theo */
x0 = x1;
y0 = y1;
z0 = z1;
} while (e1 > e && e2 > e && e3 > e);
Chúng ta có thể biểu diễn hệ phương trình này dưới dạng ma trận ( A ) và vector cột ( b )
như sau:
[ ] [ ]
2 1−1 8
A= −3−12 , b= −11
−2 12 3
Bây giờ, chúng ta sẽ sử dụng code đã cho để thực hiện phân tích LU trên ma trận ( A ).
Sau khi phân tích, chúng ta sẽ có hai ma trận ( L ) và ( U ) mà ( A = LU ). Sử dụng ( L )
và ( U ), chúng ta có thể giải hệ phương trình bằng cách giải hai hệ phương trình con:
#include <stdio.h>
#include <stdlib.h>
#define N 3
int main() {
float a[N][N];
int i, j;
// khai bao ma tran
for (i = 0;i < N;i++)
{
for (j = 0;j < N;j++)
{
printf("a[%d][%d] = ", i, j);
scanf("%f", &a[i][j]);
}
}
luDecomposition(a, l, u);
return 0;
}
float x_val[n];
float fx_val[n][n];
int i, j = 0;
float x;
printf("\nNhập điểm nội suy:");
scanf("%f", &x);
int c = 10;
case 2:
for (i = 0;i < (n - 1);i++) {
for (j = 0;j < (n - i - 1);j++) {
fx_val[i + 1][j] = fx_val[i][j + 1] - fx_val[i][j];
}
}
printf("\n\n\n");
for (j = 0;j < (n - i);j++) {
printf("%f ", fx_val[j][i]);
}
}
}
}
int giaiThua(int x) {
int f = 1;
int i = 0;
for (i = 1;i <= x;i++) {
f = f * i;
}
return f;
}
#include<stdio.h>
#include<math.h>
int main() {
printf("--------------------------------------------------------------------------\n");
printf("Phương Pháp Nội Suy Lagrange\n");
printf("--------------------------------------------------------------------------\n\n\n");
int p;
printf("Nhập số lượng giá trị mẫu cần nhập: ");
scanf("%d", &p);
float x_val[p];
float fx_val[p];
int i = 0;
}
printf("\nCác giá trị x đã nhập và giá trị hàm tương ứng là\n\n ");
printf("-----------------------------------------------\n");
for (i = 0;i < p;i++) {
printf("%f ", x_val[i]);
}
printf("\n");
for (i = 0;i < p;i++) {
printf("%f ", fx_val[i]);
}
printf("\n-----------------------------------------------\n");
float x;
ip = ip + (l * fx_val[i]);
l = 1;
}
printf("\n\nGiá trị nội suy tại x=%f theo phương pháp nội suy Lagrange là %f: ",
x, ip);
}
l[n - 1] = 1;
z[n - 1] = c[n - 1] = 0;
// Bước 3: Tính c, b và d
for (i = n - 2; i >= 0; i--) {
c[i] = z[i] - mu[i] * c[i + 1];
b[i] = (y[i + 1] - y[i]) / h[i] - h[i] * (c[i + 1] + 2 * c[i]) / 3;
d[i] = (c[i + 1] - c[i]) / (3 * h[i]);
}
return yp;
}
int main() {
// Mảng các điểm dữ liệu x và y
double x[] = { /* Điền giá trị x */ };
double y[] = { /* Điền giá trị y */ };
int n = sizeof(x) / sizeof(x[0]); // Số lượng điểm dữ liệu
return 0;
}
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
int main() {
// Mảng dữ liệu x và y
double x[] = { 1.0, 2.0, 3.0, 4.0, 5.0 }; // có thể thay đổi dữ liệu x và y//
double y[] = { 2.1, 3.9, 6.0, 8.2, 9.9 };
int n = sizeof(x) / sizeof(x[0]); // Số lượng điểm dữ liệu
return 0;
}
∫ [ f ( x )− pn ( x) ] dx
2
a
Để xác định một xấp xỉ đa thức bình phương tối thiểu, tức là, một đa thức làm
n
+ …+a1 x+ a0=∑ ak ( x ) E=
n n−1 k
cực tiểu giá trị này, đặt (x) pn ( x )=a n x +an−1 x
k=0
[ ]
b n 2
E2 ( a 0 , a 1 , … , an ) =∫ f ( x )−∑ a k ( x )
k
dx
a k=0
Bài toán là tìm các hệ số a0, a1, …, an để làm cực tiểu E. Khi đó cần phải giải
các phương trình
(∑ )
b n b b n 2
δE
=0 , j=0 ,1 , 2 , … ,n E=∫ f ( x )2 dx −2 ∑ ak ∫ f ( x ) x k dx +∫ ak ( x ) k
dx
δ aj a k=0 a a k=0
b n b
δE
=−2∫ ( x ) f ( x ) dx +¿ 2∑ ak ∫ ( x ) dx j = 0, 1, 2, ...
j k+ j
Ta có:
δ aj a k=0 a
Từ đó, để tìm Pn(x), ta cần phải giải (n+1) phương trình tuyến tính chuẩn:
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double B[degree + 1]; // Mảng chứa tổng của x lũy thừa nhân với y
for (int i = 0; i < degree + 1; i++) {
B[i] = sumOfProducts(x, y, n); // Tính tổng của x lũy thừa nhân với y
}
int main() {
// Mảng dữ liệu x và y
double x[] = { 1.0, 2.0, 3.0, 4.0, 5.0 }; //du lieu dau bai cho san
double y[] = { 2.1, 3.9, 6.0, 8.2, 9.9 };
int n = sizeof(x) / sizeof(x[0]); // Số lượng điểm dữ liệu
int degree = 2; // Bậc của đa thức
double coeff[degree + 1]; // Mảng chứa hệ số đa thức
return 0;
}
#include <stdio.h>
#include <math.h>
int main() {
// Khai báo và khởi tạo dữ liệu
int n = /* Số chiều dữ liệu */;
double* a[n]; // Ma trận A
double* q[n]; // Ma trận Q sau khi trực giao hóa
double b[n]; // Vectơ b
double x[n]; // Nghiệm x
return 0;
}
CHƯƠNG 5: TÍNH GẦN ĐÚNG ĐẠO HÀM, TÍCH PHÂN
#include<stdio.h>
#include<conio.h>
#include<math.h>
int main()
{
float canDuoi, canTren, tichPhan = 0.0, buocNhay, k;
int i, soDoanNho;
/* Tính toán */
/* Tìm kích thước bước nhảy */
buocNhay = (canTren - canDuoi) / soDoanNho;
int main()
{
float canDuoi, canTren, tichPhan = 0.0, buocNhay, k;
int i, soDoanNho;
/* Tính toán */
/* Tìm kích thước bước nhảy */
buocNhay = (canTren - canDuoi) / soDoanNho;
#include <stdio.h>
#include <math.h>
int main() {
double a, b; // Lower and upper limits of integration
size_t max_steps; // Maximum steps
double acc; // Desired accuracy
return 0;
}
Ví Dụ: Giả sử bạn là một nhà kinh tế học và muốn dự đoán sự tăng trưởng
kinh tế dựa trên lãi suất liên tục. Lãi suất liên tục được mô tả bởi công thức
rt
A=P e
nơi ( P ) là số tiền ban đầu, ( r ) là lãi suất hàng năm, và ( t ) là thời gian tính
bằng năm.
Giả sử bạn muốn tính số tiền tương lai ( A ) sau 5 năm với số tiền ban đầu là
1000 đô la và lãi suất hàng năm là 5%. Bạn có thể sử dụng chuỗi Taylor để tính
giá trị gần đúng của ( e^{rt} ) như sau:
#include <stdio.h>
#include <math.h>
// In kết quả
for (int i = 0; i <= n; ++i) {
printf("x[%d] = %f, y[%d] = %f\n", i, x[i], i, y[i]);
}
}
int main() {
double x0, y0, h;
int n;
printf("Nhập giá trị ban đầu x0: ");
scanf("%lf", &x0);
printf("Nhập giá trị ban đầu y0: ");
scanf("%lf", &y0);
printf("Nhập bước nhảy h: ");
scanf("%lf", &h);
printf("Nhập số bước n: ");
scanf("%d", &n);
return 0;
}
- Soulution run code:
2. Phương pháp Euler’s
#include <stdio.h>
#include <stdlib.h>
// Hàm để tính giá trị gần đúng của hàm mũ sử dụng chuỗi Taylor
float Taylor_exponential(int n, float x) {
float exp_sum = 1; // Khởi tạo tổng là 1 (thành phần đầu tiên của chuỗi Taylor)
// Vòng lặp để tính từng thành phần của chuỗi Taylor cho hàm mũ
for (int i = n - 1; i > 0; --i) {
exp_sum = 1 + x * exp_sum / i; // Tính thành phần tiếp theo của chuỗi và cập nhật
tổng
}
return exp_sum; // Trả về kết quả gần đúng của chuỗi Taylor cho $$ e^x $$
}
// Hàm chính
int main(void) {
int n = 25; // Số thành phần của chuỗi Taylor
float x = 5.0; // Giá trị của x trong $$ e^x $$
#include <stdio.h>
#include <math.h>
area *= h; // Nhân với kích thước mỗi phân đoạn để có diện tích
return area;
}
int main() {
double lower_limit, upper_limit;
int sub_intervals;
return 0;
}
4. Phương pháp RUNGE-KUTTA 4
#include<stdio.h>
#include<math.h>
/* Định nghĩa hàm f(x, y) ở đây (Ví dụ: dy/dx = f(x, y)) */
double f(double x, double y) {
return 2 * x * x - 3 * x + 4;
}
int main()
{
int i;
double x, y, x0, y0, h, k1, k2, k3, k4;
printf("---------------------------------------------------------------------------\n");
printf("PHƯƠNG PHÁP RUNGE - KUTTA - BẬC 4\n\n");
printf("---------------------------------------------------------------------------\n\n");
printf("Nhập điều kiện ban đầu cho y: ");
scanf("%lf", &y0);
printf("Nhập điều kiện ban đầu cho x: ");
scanf("%lf", &x0);
printf("Nhập giá trị của x mà tại đó y cần được tìm: ");
scanf("%lf", &x);
printf("Nhập bước nhảy h: ");
scanf("%lf", &h);
printf("x\t\ty\t\tk1\t\tk2\t\tk3\t\tk4\t\tk_avg\n");
printf("__________________________________________________________________
________________________________________\n");
// Bắt đầu quy trình Runge-Kutta
while ((x - x0) > 0.0000000001) {
k1 = h * f(x0, y0);
k2 = h * f(x0 + h / 2.0, y0 + k1 / 2.0);
k3 = h * f(x0 + h / 2.0, y0 + k2 / 2.0);
k4 = h * f(x0 + h, y0 + k3);
printf("%lf\t%lf\t%lf\t%lf\t%lf\t%lf\t%lf\n", x0, y0, k1, k2, k3, k4, 1 / 6.0 * (k1 + 2
* k2 + 2 * k3 + k4));
y = y0 + 1 / 6.0 * (k1 + 2 * k2 + 2 * k3 + k4);
y0 = y;
x0 = x0 + h;
}
printf("%lf\t%lf\n", x0, y0);
printf("__________________________________________________________________
__________________________________________\n");
printf("Giá trị của y theo phương pháp Runge-Kutta bậc 4 là %.4lf\n\n", y);
return 0;
}
5. Phương pháp Huen
a. Bài toán
#include <stdio.h>
#include <math.h>
// Hàm f(t, y) biểu diễn phương trình vi phân dy/dt = f(t, y)
double f(double t, double y) {
return -y + sin(t); // Ví dụ: dy/dt = -y + sin(t)
}
// Phương pháp Heun
void heun(double y0, double t0, double h, int n) {
double t = t0;
double y = y0;
double y_pred, f0, f1;
for (int i = 0; i & lt; n; ++i) {
f0 = f(t, y); // Giá trị ban đầu của hàm f(t, y)
y_pred = y + h * f0; // Dự đoán giá trị y tại t+h
f1 = f(t + h, y_pred); // Giá trị của hàm f(t+h, y dự đoán)
y = y + (h / 2) * (f0 + f1); // Cập nhật giá trị y bằng trung bình cộng của f0 và f1
t += h; // Cập nhật thời gian
printf("Tại t = % f, y = % f\n & quot;, t, y);
}
}
int main() {
double y0 = 1; // Giá trị ban đầu của y
double t0 = 0; // Thời gian bắt đầu
double h = 0.1; // Kích thước bước
int n = 10; // Số bước lặp
heun(y0, t0, h, n);
return 0;
}
- Soulution run code:
6. Phương pháp hiệu chỉnh nhiều bước Adam - Moulton
a. Bài toán:
Adam-Moulton: một phương pháp đa bước để giải các phương trình vi phân thông
thường. Đây là một phương pháp hiệu quả để giải các bài toán vi phân trong thực tế, đặc
biệt khi chúng ta cần độ chính xác cao và ổn định trong các bước tính toán.
Bài toán thực tế: Giả sử chúng ta muốn mô hình hóa sự tăng trưởng của một quần thể
sinh vật, nơi tốc độ tăng trưởng phụ thuộc vào kích thước hiện tại của quần thể. Phương
trình vi phân có thể được biểu diễn như sau:
dy y
=ry (1− )
dt K
trong đó:
Chúng ta có thể sử dụng phương pháp Adam-Moulton để giải phương trình này với các
giá trị cụ thể cho ( r ), ( K ), và điều kiện ban đầu ( y_0 ).
Để áp dụng code cho bài toán này, bạn cần thay đổi hàm ( f(t, y) ) để phản ánh mô hình
tăng trưởng quần thể và cập nhật các giá trị ban đầu và tham số phù hợp.
#include <stdio.h>
#include <math.h>
// Tính toán giá trị ban đầu bằng phương pháp Euler hoặc một phương pháp một
bước khác
w[1] = w[0] + h * f(t0, w[0]);
return 0;
}