x=-9:9;
y=-9:9;
f1=sin(y+0.5)-x-1;
f2=y+cos(x-2);
plot(x,f1,x,f2);
grid on;
модифицированный метод (E = 0.01-для не модифицированного метода; E1=0.0001;-для модифицированного метода)
-1.43817(x,y) = (-0.137061,-0.52487) |f1 - f2| = 0.0469158 d.x=0.0370609 d.
y=-0.0248702
-1.43044(x,y) = (-0.136012,-0.535939) |f1 - f2| = 0.00863316 d.x=-0.00104867
d.y=-0.0110687
-1.42892(x,y) = (-0.138763,-0.537) |f1 - f2| = 0.00272782 d.x=0.00275041 d.
y=-0.00106113
-1.42844(x,y) = (-0.13847,-0.53777) |f1 - f2| = 0.000453661 d.x=-0.000293048
d.y=-0.000769578
Step count = 4
(x,y) = (-0.138708,-0.537793) |f1 - f2| = 0.000177708 d.x=-0.000293048 d.y=
-0.000769578
(x,y) = (-0.138666,-0.537851) |f1 - f2| = 2.16549e-005 d.x=-0.000293048 d.y
=-0.000769578
модифицированный метод (E = 0.1-для не модифицированного метода; E1=0.0001;-для модифицированного метода)
Для продолжения нажмите любую клавишу . . .
-1.43817(x,y) = (-0.137061,-0.52487) |f1 - f2| = 0.0469158 d.x=0.0370609 d.
y=-0.0248702
Step count = 1
(x,y) = (-0.136005,-0.536014) |f1 - f2| = 0.00871456 d.x=0.0370609 d.y=-0.0
248702
(x,y) = (-0.138786,-0.537009) |f1 - f2| = 0.00268575 d.x=0.0370609 d.y=-0.0
248702
(x,y) = (-0.138467,-0.537776) |f1 - f2| = 0.000435217 d.x=0.0370609 d.y=-0.
0248702
(x,y) = (-0.13871,-0.537793) |f1 - f2| = 0.000175382 d.x=0.0370609 d.y=-0.0
248702
(x,y) = (-0.138666,-0.537852) |f1 - f2| = 2.03085e-005 d.x=0.0370609 d.y=-0
.0248702
Для продолжения нажмите любую клавишу . . .
Немодифицированный метод:
(x,y) = (-0.137061,-0.52487) |f1 - f2| = 0.0469158
(x,y) = (-0.136012,-0.535939) |f1 - f2| = 0.00863316
(x,y) = (-0.138763,-0.537) |f1 - f2| = 0.00272782
(x,y) = (-0.13847,-0.53777) |f1 - f2| = 0.000453661
(x,y) = (-0.138708,-0.537793) |f1 - f2| = 0.000177709
(x,y) = (-0.138666,-0.537851) |f1 - f2| = 2.16604e-005
Step count = 6
Для продолжения нажмите любую клавишу . . .
Код программы для немодифицированного метода:
#include <iostream>
#include <cmath>
using namespace std;
class Vector
{
public:
double x;
double y;
double norm() { return sqrt(x * x + y * y); }
Vector operator-(Vector b)
{
Vector result;
result.x = x - b.x;
result.y = y - b.y;
return result;
}
};
double detJ(Vector v) { return -1 + cos(v.y + 0.5) * sin(v.x - 2); }
double f1(Vector v) { return sin(v.y + 0.5) - v.x - 1; }
double f2(Vector v) { return v.y + cos(v.x - 2); }
Vector Func(Vector v)
{
Vector temp;
temp.x = (f1(v) * 1 + f2(v) * sin(v.x - 2)) / detJ(v);
temp.y = (-f1(v) * cos(v.y + 0.5) - f2(v) * 1) / detJ(v);
return temp;
}
int main()
{
Vector x = {0, 0};
Vector res = {-0.1,- 0.5};
const double E = 0.0001;
int step = 0;
while ((x - res).norm() > E)
{
x = res;
res = x - Func(x);
cout << "(x,y) = (" << res.x << "," << res.y << ")" << " "
<< "|f1 - f2| = " << abs(f1(x) - f2(res)) << endl;
step++;
}
cout << "Step count = " << step << endl;
system("pause");
return 0;
}
Код программы для модифицированного метода:
#include <iostream>
#include <cmath>
using namespace std;
class Vector
{
public:
double x;
double y;
double norm() { return sqrt(x * x + y * y); }
Vector operator-(Vector b)
{
Vector result;
result.x = x - b.x;
result.y = y - b.y;
return result;
}
};
double detJ(Vector v) { return -1 + cos(v.y + 0.5) * sin(v.x - 2); }
\\Якобиан
double f1(Vector v) { return sin(v.y + 0.5) - v.x - 1; }
double f2(Vector v) { return v.y + cos(v.x - 2); }
Vector Func(Vector v)
\\считаем [F(x[k])’] в минус первой умножить на F(x[k]) при непостоянном Якобиане
{
Vector temp;
temp.x = (f1(v) * 1 + f2(v) * sin(v.x - 2)) / detJ(v);
\\\\верхняя строчка матрицы [F(x[k])’] в минус первой умножить на F(x[k])
temp.y = (-f1(v) * cos(v.y + 0.5) - f2(v) * 1) / detJ(v);
\\ нижняя строчка матрицы [F(x[k])’] в минус первой умножить на F(x[k])
return temp;
}
Vector Func1(Vector v)
\\\\считаем [F(x[k])’] в минус первой умножить на F(x[k]) при постоянном Якобиане
{
Vector temp;
temp.x = (f1(v) * 1 + f2(v) * sin(v.x - 2))/(-1.42844);
temp.y = (-f1(v) * cos(v.y + 0.5) - f2(v) * 1)/(-1.42844);
return temp;
}
int main()
{
Vector x = {0, 0};
Vector d;
Vector res = {-0.1, -0.5};
\\ выбираем начальное приближение, основываясь на графике, построеннои в матлабе
const double E = 0.001; до этой точности считаем немодифицированный метод
const double E1=0.0001; до этой точности считаем модифицированный метод
int step = 0;
while ((x - res).norm() > E)-цикл для немодифицированного метода
{
x = res;
res = x - Func(x);
d=Func(x);
cout<<detJ(res) << "(x,y) = (" << res.x << "," <<res.y << ")" << " "
<< "|f1 - f2| = " << abs(f1(x) - f2(res)) <<" "<<"d.x="<< d.x <<" "<<"d.y="<<d.y<<endl;
step++;
}
Здесь d.x и d.y-верхняя и нижняя строчки Якобиана, выводим его , чтобы зафиксировать для последующих шагов.
cout << "Step count = " << step << endl;
//system("pause");
while ((x - res).norm() > E1) цикл для модифицированного метода
{
x = res;
res = x - Func1(x);
cout << "(x,y) = (" << res.x << "," << res.y << ")" << " "
<< "|f1 - f2| = " << abs(f1(x) - f2(res)) <<" "<<"d.x="<< d.x <<" "<<"d.y="<<d.y<<endl;
step++;
}
system("pause");
return 0;
}
Как видно из ответов число шагов при использовании модифицированного и не модифицированного метода Ньютона не различается. Таким образом, в данном случае возможно использование модифицированного метода с первого шага, что упрощает процесс(не требует на каждом шаге вычислять заново Якобиан).
В данном примере чтобы локализовать корень был построен график в матлабе.(прилагается). За начальное приближение, был взят вектор: Vector res = {-0.1, -0.5}.
Уважаемый посетитель!
Чтобы распечатать файл, скачайте его (в формате Word).
Ссылка на скачивание - внизу страницы.