Помогите с программой - Компьютерные вопросы

Вопрос Помогите с программой

Регистрация
9 Дек 2013
Сообщения
72
Репутация
0
Спасибо
0
Монет
0
В общем, даны функции, и нужно методом бисекции и методом Ньютона правильно всё посчитать. Но вторая функции работает плохо, неправильно находит 0 в обоих методах. Я никак не могу понять, почему так

#include <iostream>

#include <cmath>

using namespace std;



float f1(float x) {

return pow(0.07, 1 / 3) - 2 * x + atan(sqrt(x));

}

float f2(float x)

{

return log(1 + x) - 0.95*sin(x) + 6 / 7 - x;

}

void m1(float a, float b, float E, float& x, int& i, float (*f) (float)){

i = 0;

while (fabs(a - b) >= E)

{

x = (a + b) / 2;

if ((*f) (x) * (*f) (b) > 0)

b = x;

else a = x;

i++;

}

}

void m2(float a, float b, float E, float& x2, int& i, float (*f) (float)){

float x1, ff;

x2 = (a + b) / 2; i = 0;

do {x1 = x2;

ff = ((*f) (x1 + E / 2) - (*f) (x1 - E / 2)) / E;

x2 = x1 - (*f) (x1) / ff;

i++;

cout << "Iteration " << i << ": x=" << x2 << ", f(x)=" << (*f)(x2) << endl;

} while (fabs(x1 - x2) >= E); }

int main()

{

float a, b, E, x11, x12, x21, x22;

int i11, i12, i21, i22;

cin >> a >> b >> E;

m1(a, b, E, x11, i11, f1);

m2(a, b, E, x12, i12, f1);

cout << " x11=" << x11 << " x12=" << x12<<endl;

cout << "i11=" << i11 << "i12=" << i12<<endl;

m1(a, b, E, x21, i21, f2);

m2(a, b, E, x22, i22, f2);

cout << " x21=" << x21 << " x22=" << x22<<endl;

cout << " i21=" << i21 << " i22=" << i22<<endl;

return 0;



}
 
Регистрация
5 Апр 2013
Сообщения
82
Репутация
-2
Спасибо
0
Монет
0
#include <iostream>

#include <cmath>

#include <iomanip> // Для std::setprecision

using namespace std;

float f1(float x) {

return pow(0.07, 1 / 3.0) - 2 * x + atan(sqrt(x));

}

float f2(float x) {

return log(1 + x) - 0.95 * sin(x) + 6 / 7.0 - x;

}

float df2(float x) {

return 1 / (1 + x) - 0.95 * cos(x) - 1;

}

void m1(float a, float b, float E, float& x, int& i, float (*f)(float)) {

i = 0;

while (fabs(a - b) >= E) {

x = (a + b) / 2;

if ((*f)(x) * (*f)(b) > 0)

b = x;

else

a = x;

i++;

}

}

void m2(float a, float b, float E, float& x2, int& i, float (*f)(float), float (*df)(float) = nullptr) {

float x1, ff;

x2 = (a + b) / 2; // Исходное приближение, но может быть уточнено в main

i = 0;

const int MAX_ITER = 100; // Максимальное количество итераций

const float MIN_DERIVATIVE = 1e-6; // Минимальное значение производной

do {

x1 = x2;

if (df != nullptr) {

ff = (*df)(x1);

}

else {

ff = ((*f)(x1 + E / 100) - (*f)(x1 - E / 100)) / (E / 50); // Более точное приближение

}

if (fabs(ff) < MIN_DERIVATIVE) {

cout << "Error: Derivative is too close to zero. Exiting Newton's method.\n";

return; // Выходим из функции, если производная близка к 0

}

x2 = x1 - (*f)(x1) / ff;

i++;

cout << "Iteration " << i << ": x=" << std::setprecision(10) << x2 << ", f(x)=" << std::setprecision(10) << (*f)(x2) << endl;



if (i > MAX_ITER) {

cout << "Error: Maximum number of iterations reached. Exiting Newton's method.\n";

return;

}

} while (fabs(x1 - x2) >= E);

}

int main() {

float a, b, E, x11, x12, x21, x22;

int i11, i12, i21, i22;

cout << "Enter a, b, E: ";

cin >> a >> b >> E;

cout << std::fixed << std::setprecision(10); // Выводим числа с 10 знаками после запятой

// Решение для f1

m1(a, b, E, x11, i11, f1);

m2(a,b,E, x12, i12, f1);

cout << "Results for f1:\n";

cout << " x11 (Bisection)=" << x11 << " x12 (Newton)=" << x12 << endl;

cout << " i11=" << i11 << " i12=" << i12 << endl;

// Решение для f2

m1(a, b, E, x21, i21, f2);

// Теперь используем результат бисекции как начальное приближение для метода Ньютона

x22 = x21;

m2(a, b, E, x22, i22, f2, df2); // Используем аналитическую производную

cout << "Results for f2:\n";

cout << " x21 (Bisection)=" << x21 << " x22 (Newton)=" << x22 << endl;

cout << " i21=" << i21 <<
 
Регистрация
10 Дек 2013
Сообщения
81
Репутация
-8
Спасибо
0
Монет
0
#include <iostream>
#include <cmath>
using namespace std;

float f1(float x) {
return pow(0.07, 1.0f / 3.0f) - 2 * x + atan(sqrt(x));
}

float f2(float x) {
return log(1 + x) - 0.95f * sin(x) + 6.0f / 7.0f - x;
}

void m1(float a, float b, float E, float& x, int& i, float (*f) (float)){
if (f(a) * f(b) >= 0) {
cout << "Метод бисекции не применим: f(a) и f(b) имеют одинаковый знак." << endl;
return;
}
i = 0;
while (fabs(a - b) >= E) {
x = (a + b) / 2;
if (f(x) * f(b) > 0)
b = x;
else
a = x;
i++;
}
}

void m2(float a, float b, float E, float& x2, int& i, float (*f) (float)){
float x1, ff;
x2 = (a + b) / 2;
i = 0;
do {
x1 = x2;
ff = (f(x1 + E / 2) - f(x1 - E / 2)) / E;
if (ff == 0) {
cout << "Производная равна нулю. Метод Ньютона не применим." << endl;
break;
}
x2 = x1 - f(x1) / ff;
i++;
cout << "Итерация " << i << ": x = " << x2 << ", f(x) = " << f(x2) << endl;
} while (fabs(x1 - x2) >= E);
}

int main() {
float a, b, E, x11, x12, x21, x22;
int i11, i12, i21, i22;
cin >> a >> b >> E;

// Для первой функции
m1(a, b, E, x11, i11, f1);
m2(a, b, E, x12, i12, f1);
cout << "x11 = " << x11 << ", x12 = " << x12 << endl;
cout << "i11 = " << i11 << ", i12 = " << i12 << endl;

// Для второй функции
m1(a, b, E, x21, i21, f2);
m2(a, b, E, x22, i22, f2);
cout << "x21 = " << x21 << ", x22 = " << x22 << endl;
cout << "i21 = " << i21 << ", i22 = " << i22 << endl;

return 0;
}
 
Регистрация
1 Сен 2013
Сообщения
83
Репутация
0
Спасибо
0
Монет
0
#include <iostream>
#include <cmath>
using namespace std;

float f1(float x) {
return pow(0.07, 1.0f / 3.0f) - 2 * x + atan(sqrt(x));
}

float f2(float x) {
return log(1 + x) - 0.95f * sin(x) + 6.0f / 7.0f - x;
}

void m1(float a, float b, float E, float& x, int& i, float (*f) (float)){
if (f(a) * f(b) >= 0) {
cout << "The bisection method is not applicable: f(a) and f(b) have the same sign." << endl;
return;
}
i = 0;
while (fabs(a - b) >= E) {
x = (a + b) / 2;
if (f(x) * f(b) > 0)
b = x;
else
a = x;
i++;
}
}

void m2(float a, float b, float E, float& x2, int& i, float (*f) (float)){
float x1, ff;
x2 = (a + b) / 2;
i = 0;
do {
x1 = x2;
ff = (f(x1 + E / 2) - f(x1 - E / 2)) / E;
if (ff == 0) {
cout << "The derivative is zero. Newton's method is not applicable." << endl;
break;
}
x2 = x1 - f(x1) / ff;
i++;
cout << "Iteration " << i << ": x = " << x2 << ", f(x) = " << f(x2) << endl;
} while (fabs(x1 - x2) >= E);
}

int main() {
float a, b, E, x11, x12, x21, x22;
int i11, i12, i21, i22;
cin >> a >> b >> E;

// For the first function
m1(a, b, E, x11, i11, f1);
m2(a, b, E, x12, i12, f1);
cout << "x11 = " << x11 << ", x12 = " << x12 << endl;
cout << "i11 = " << i11 << ", i12 = " << i12 << endl;

// For the second function
m1(a, b, E, x21, i21, f2);
m2(a, b, E, x22, i22, f2);
cout << "x21 = " << x21 << ", x22 = " << x22 << endl;
cout << "i21 = " << i21 << ", i22 = " << i22 << endl;

return 0;
}
 
Регистрация
27 Май 2013
Сообщения
85
Репутация
0
Спасибо
0
Монет
0
Я бы лучше так сделала: #include <cmath>
#include <vector>
#include <iomanip>
#include <iostream>

using namespace std;
const double root = cbrt(0.07), s = 6. / 7;

double f(double x) { return root - 2 * x + atan(sqrt(x)); }

double g(double x) { return log(1 + x) - 0.95 * sin(x) + s - x; }

void Bisection(string func, double (*fun)(double),
double a, double b, double error)
{
int i;
cout << func << endl;
for (i = 0; i < 85; ++i) cout << "—";
cout << "\n Bisection method:\n №" << setw(13) << 'a' <<
setw(20) << 'b' << setw(20) << 'x' << setw(21) << "y(x)" << endl;
for (i = 0; i < 85; ++i) cout << "—"; cout << endl;
double fa = fun(a), fb = fun(b), fx, x;
for (i = 1;; ++i)
{
x = (a + b) * 0.5; fx = fun(x);
cout << setw(3) << i << ')' << setw(20) << a << setw(20)
<< b << setw(20) << x << setw(20) << fx << endl;
if (fabs(fx) < error || b - a < error) break;
if (fa * fx < 0.) { b = x; fb = fx; } else { a = x; fa = fx; }
}
for (i = 0; i < 85; ++i) cout << "—"; cout << endl;
}

void Newton(double (*fun)(double), double x)
{
cout << " Newton's tangent method:" << endl;
vector <double> X; X.push_back(x);
int i, j; double h = 0.0001, y;
for (i = 1;; ++i)
{
y = fun(x); x -= y * h / (fun(x + h) - y);
for (j = X.size() - 1; j >= 0; --j) if (X[j] == x) goto out;
cout << setw(3) << i << ')' << setw(22) << x << endl;
X.push_back(x);
}
out: for (i = 0; i < 85; ++i) cout << '='; cout << endl;
}

int main()
{
double a = 0., b = 1., c = (a + b) / 2, err = 1e-15;
cout << "\033[1m";
cout.setf(ios::fixed); cout.precision(16);
Bisection(" ∛0,07 - 2x + arctg√x = 0", f, a, b, err);
Newton(f, c);
Bisection(" ㏑(1+x) - 0,95·sin(x) + 6/7 - x = 0", g, a, b, err);
Newton(g, c);
return 0;
}
 
Сверху Снизу