二分法收敛参数。 C代码
Parameter of convergence of bisection method. C code
我在代码中坚持使用一个公式。以不同的方式多次更改,但我的老师一直说它不正确。我放弃了,不知道我还能做什么。我想我只是没有正确理解公式,这就是我做错的原因。你能帮我找到解决办法吗?谢谢!
这是一个非常简单的二分法,我必须求解方程。除此之外,我还必须使用公式 α = |Xn+1 - Xn| 找到收敛参数(我不确定我是否使用了正确的术语。任务是俄语) / |Xn - Xn-1|,其中 n - 收敛阶数(这里我不确定这是否正确。我使用了 Google 翻译器)。
请看一下我计算这个值的代码末尾,请给我一个建议,我做错了什么?我使用根 ξ 作为 Xn、a 和 b 作为 Xn-1 和 Xn+1。老师的评论是“收敛参数仍然不正确。用这种方法总是会得到1。正如我写的那样,使用任务中的公式”。
#include<stdio.h>
#include<math.h>
#include<time.h>
double f(double x); //Function
int res(int i, double a, double b, double ξ, double ε1, double ε2); //Print result
double Bisection(double a, double b, double ε1, double ε2); //Bisection method
int main()
{
double a=-10, b=0, ξ, h=0.5, α, x1, x2, ε1, ε2;
int i=0;
printf("\nf(x) = 2^x - 2 * cos(x)");
printf("\nStart of the interval a = %.0lf", a);
printf("\nEnd of the interval b = %.0lf", b);
printf("\nEnter error ε1 for function = ");
scanf("%lf", &ε1);
printf("Enter error ε2 for argument = ");
scanf("%lf", &ε2);
printf("\n\nSOLUTION:");
//selection of roots
x1=a;
x2=x1+h;
while (x2<=b)
{
if ((f(x1)*f(x2))<0)
{
i++;
printf("\n\n%d) %d root of the function is in the interval [%.1f, %.1f]\n",i, i, x1, x2);
printf("\nn\t a\t\t b\t\t ξ\t f(ξ)\t ε1\t\t ε2\n");
Bisection(x1,x2,ε1,ε2); //Bisection method
}
x1=x2;
x2=x1+h;
}
return 0;
}
//Function
double f(double x)
{
double y;
y=pow(2,x)-2*cos(x);
return y;
}
//Print result
int res(int i, double a, double b, double ξ, double ε1, double ε2)
{
printf("%d\t%10.7f %10.7f %10.7f %10.7f %e %e\n", i, a, b, ξ, f(ξ), ε1, ε2);
return 0;
}
//Bisection method
double Bisection(double a, double b, double ε1, double ε2)
{
double ξ=(a+b)/2; //Middle of the interval
double α;
int i=0;
if (f(ξ)==0)
{
printf("Root: %f \n\n", ξ);
}
else
{
while ((fabs(f(ξ))>ε1) && ((fabs(b-a)/2)>ε2)) //The accuracy of the definition of the root
{
if ((f(a)*f(ξ))<0)
{
b=ξ;
}
else
{
a=ξ;
}
ξ=(a+b)/2;
res(i+1, a, b, ξ, ε1, ε2); //Print results
i++;
}
α = fabs(ξ-b)/fabs(ξ-a); //Parameter of convergence
printf("\nParameter of convergence: α=%.1f\n", α);
printf("Root ξ=%.7f found after %d iterations\n", ξ, i);
printf("Function f(ξ)=%.10f found after %d iterations\n", f(ξ), i);
}
return 0;
}
据我了解
the formula α = |Xn+1 - Xn| / |Xn - Xn-1|
指的是在每次迭代(n)时计算根(X),所以在第一次迭代时
|Xn - Xn-1| = fabs(b - a)
|Xn+1 - Xn| = fabs(ξ - a) = fabs(b - ξ)
= fabs(b - a) / 2 given that ξ=(a+b)/2 (ignoring numerical errors)
在二分法的每次连续迭代中,范围 [a, b] 减半,这意味着 α 将始终为 1/2。
由于浮点类型的精度和范围有限,表达式 ξ=(a+b)/2(或 ξ = a + (b - a)/2)最终会生成一个数值等价的值到极端之一,导致 α = 0.
我在代码中坚持使用一个公式。以不同的方式多次更改,但我的老师一直说它不正确。我放弃了,不知道我还能做什么。我想我只是没有正确理解公式,这就是我做错的原因。你能帮我找到解决办法吗?谢谢!
这是一个非常简单的二分法,我必须求解方程。除此之外,我还必须使用公式 α = |Xn+1 - Xn| 找到收敛参数(我不确定我是否使用了正确的术语。任务是俄语) / |Xn - Xn-1|,其中 n - 收敛阶数(这里我不确定这是否正确。我使用了 Google 翻译器)。
请看一下我计算这个值的代码末尾,请给我一个建议,我做错了什么?我使用根 ξ 作为 Xn、a 和 b 作为 Xn-1 和 Xn+1。老师的评论是“收敛参数仍然不正确。用这种方法总是会得到1。正如我写的那样,使用任务中的公式”。
#include<stdio.h>
#include<math.h>
#include<time.h>
double f(double x); //Function
int res(int i, double a, double b, double ξ, double ε1, double ε2); //Print result
double Bisection(double a, double b, double ε1, double ε2); //Bisection method
int main()
{
double a=-10, b=0, ξ, h=0.5, α, x1, x2, ε1, ε2;
int i=0;
printf("\nf(x) = 2^x - 2 * cos(x)");
printf("\nStart of the interval a = %.0lf", a);
printf("\nEnd of the interval b = %.0lf", b);
printf("\nEnter error ε1 for function = ");
scanf("%lf", &ε1);
printf("Enter error ε2 for argument = ");
scanf("%lf", &ε2);
printf("\n\nSOLUTION:");
//selection of roots
x1=a;
x2=x1+h;
while (x2<=b)
{
if ((f(x1)*f(x2))<0)
{
i++;
printf("\n\n%d) %d root of the function is in the interval [%.1f, %.1f]\n",i, i, x1, x2);
printf("\nn\t a\t\t b\t\t ξ\t f(ξ)\t ε1\t\t ε2\n");
Bisection(x1,x2,ε1,ε2); //Bisection method
}
x1=x2;
x2=x1+h;
}
return 0;
}
//Function
double f(double x)
{
double y;
y=pow(2,x)-2*cos(x);
return y;
}
//Print result
int res(int i, double a, double b, double ξ, double ε1, double ε2)
{
printf("%d\t%10.7f %10.7f %10.7f %10.7f %e %e\n", i, a, b, ξ, f(ξ), ε1, ε2);
return 0;
}
//Bisection method
double Bisection(double a, double b, double ε1, double ε2)
{
double ξ=(a+b)/2; //Middle of the interval
double α;
int i=0;
if (f(ξ)==0)
{
printf("Root: %f \n\n", ξ);
}
else
{
while ((fabs(f(ξ))>ε1) && ((fabs(b-a)/2)>ε2)) //The accuracy of the definition of the root
{
if ((f(a)*f(ξ))<0)
{
b=ξ;
}
else
{
a=ξ;
}
ξ=(a+b)/2;
res(i+1, a, b, ξ, ε1, ε2); //Print results
i++;
}
α = fabs(ξ-b)/fabs(ξ-a); //Parameter of convergence
printf("\nParameter of convergence: α=%.1f\n", α);
printf("Root ξ=%.7f found after %d iterations\n", ξ, i);
printf("Function f(ξ)=%.10f found after %d iterations\n", f(ξ), i);
}
return 0;
}
据我了解
the formula α = |Xn+1 - Xn| / |Xn - Xn-1|
指的是在每次迭代(n)时计算根(X),所以在第一次迭代时
|Xn - Xn-1| = fabs(b - a)
|Xn+1 - Xn| = fabs(ξ - a) = fabs(b - ξ)
= fabs(b - a) / 2 given that ξ=(a+b)/2 (ignoring numerical errors)
在二分法的每次连续迭代中,范围 [a, b] 减半,这意味着 α 将始终为 1/2。
由于浮点类型的精度和范围有限,表达式 ξ=(a+b)/2(或 ξ = a + (b - a)/2)最终会生成一个数值等价的值到极端之一,导致 α = 0.