来源:https://www.ijeter.everscience.org/Manuscripts/Volume-6/Issue-4/Vol-6-issue-4-M-54.pdf
这是用打靶法求解边值问题的程序。我决定使用割线法(换句话说,牛顿法)的公式。并决定相应地更改m3搜索。
前:m3=m2+(m2-M1)(b-b2))/(1.0(b2-b1);
后:m3=m2-((m2-m1)/(b2-b1))*(b2-b);
我得到了这个结果:
Exact value of M =-1.305508
0.500000 -1.#IND00
1.000000 -1.#IND00
1.500000 -1.#IND00
2.000000 -1.#IND00
2.500000 -1.#IND00
3.000000 -1.#IND00也就是说,显然M的确切值是正确的,但是第二列不想正确计数。为什么会这样?我会非常感谢你的帮助。
#include<stdio.h>
#include<math.h>
#include<stdlib.h>
float f1(float x, float y, float z)
{
return(z);
}
float f2(float x, float y, float z)
{
return(x + y);
}
float shoot(float x0, float y0, float z0, float xn, float h, int p)
{
float x, y, z, k1, k2, k3, k4, l1, l2, l3, l4, k, l, x1, y1, z1;
x = x0;
y = y0;
z = z0;
do
{
k1 = h * f1(x, y, z);
l1 = h * f2(x, y, z);
k2 = h * f1(x + h / 2.0, y + k1 / 2.0, z + l1 / 2.0);
l2 = h * f2(x + h / 2.0, y + k1 / 2.0, z + l1 / 2.0);
k3 = h * f1(x + h / 2.0, y + k2 / 2.0, z + l2 / 2.0);
l3 = h * f2(x + h / 2.0, y + k2 / 2.0, z + l2 / 2.0);
k4 = h * f1(x + h, y + k3, z + l3);
l4 = h * f2(x + h, y + k3, z + l3);
l = 1 / 6.0 * (l1 + 2 * l2 + 2 * l3 + l4);
k = 1 / 6.0 * (k1 + 2 * k2 + 2 * k3 + k4);
y1 = y + k;
x1 = x + h;
z1 = z + l;
x = x1;
y = y1;
z = z1;
if (p == 1)
{
printf("\n%f\t%f", x, y);
}
} while (x < xn);
return(y);
}
main()
{
float x0, y0, h, xn, yn, z0, m1, m2, m3, b, b1, b2, b3, e;
int p = 0;
printf("\n Enter x0,y0,xn,yn,h:");
scanf("%f%f%f%f%f", &x0, &y0, &xn, &yn, &h);
printf("\n Enter the trial M1:");
scanf("%f", &m1);
b = yn;
z0 = m1;
b1 = shoot(x0, y0, z0, xn, h, p = 1);
printf("\nB1 is %f", b1);
if (fabs(b1 - b) < 0.00005)
{
printf("\n The value of x and respective z are:\n");
e = shoot(x0, y0, z0, xn, h, p = 1);
return(0);
}
else
{
printf("\nEnter the value of M2:");
scanf("%f", &m2);
z0 = m2;
b2 = shoot(x0, y0, z0, xn, h, p = 1);
printf("\nB2 is %f", b2);
}
if (fabs(b2 - b) < 0.00005)
{
printf("\n The value of x and respective z are\n");
e = shoot(x0, y0, z0, xn, h, p = 1);
return(0);
}
else
{
printf("\nM2=%f\tM1=%f", m2, m1);
m3 = m2 - ((m2 - m1) / (b2 - b1)) * (b2 - b);
if (b1 - b2 == 0)
exit(0);
printf("\nExact value of M =%f", m3);
z0 = m3;
b3 = shoot(x0, y0, z0, xn, h, p = 0);
}
if (fabs(b3 - b) < 0.000005)
{
printf("\nThere is solution :\n");
e = shoot(x0, y0, z0, xn, h, p = 1);
exit(0);
}
do
{
m1 = m2;
m2 = m3;
b1 = b2;
b2 = b3;
m3 = m2 - ((m2 - m1) / (b2 - b1)) * (b2 - b);
z0 = m3;
b3 = shoot(x0, y0, z0, xn, h, p = 0);
} while (fabs(b3 - b) < 0.0005);
z0 = m3;
e = shoot(x0, y0, z0, xn, h, p = 1);
}发布于 2021-12-25 10:15:11
这也是错误的文件来源,也许是一些善意的编辑看到了一个明显的错误,从来没有。
当到目标值的距离很大时,要继续的割线循环。
do
{
...
} while (fabs(b3 - b) > 0.0005);这样,当到目标的距离足够小时,您就离开了这个循环。这也就排除了零除法。
另外,在Runge-Kutta循环中,添加为第一行。
if(x+1.2*h>xn) h=xn-x因此,最后一次迭代正好到达间隔结束。否则,如果xn-x0不是h的倍数,或者浮点错误以不幸的模式累积,则情况可能不是这样。这与测试数据无关,但可能发生在h=0.1中。
https://stackoverflow.com/questions/70313881
复制相似问题