Нахождение корней нелинейного уравнения методом секущих на С++ (метод итераций, метод хорд)
Разработаем программу нахождения корней нелинейного уравнения (f(x)=sinx – x + 0,15) методом секущих. Составим алгоритм программы, напишем код. Прикинем, какие данные взять для тестирования. Код написан для программы Borland C++ (3 или 5), но может быть использован и в других программах, например, Microsoft Visual Studio 6.Суть метода можно почитать в википедии, все очень понятно описано, даже есть программа:
(http://ru.wikipedia.org/wiki/%D0%9C%D0%B5%D1%82%D0%BE%D0%B4_%D1%85%D0%BE%D1%80%D0%B4).
По формуле
Вычисляем значения х. Нужно повторять итерации, пока разница между значениями х0 и х1 не будет равна заданной погрешности.
Определим входные и выходные данные. Входными данными являются первые приближения х0 и х1, а также требуемое значение точности eps.
Выходные данные – корень уравнения, результат проверки найденного корня (значение функции с подставленным значением корня). Добавим еще счетчик итераций, чтобы посмотреть, сколько потребовалось итераций цикла для нахождения корня.
Взаимосвязь между входными и выходными данными.
Чем больше значение eps, тем менее точным будет найденное значение корня.
Если введенные приближения х0 и х1 равны, то результат будет получен неверный (если только они оба не равны корню).
Алгоритм программы
Чтобы не запускать многократно программу для ввода каждого набора данных, лучше организовать ввод данных в цикле. В данном случае это цикл с предусловием. Первый раз итерация цикла пройдет без запроса пользователю, но перед началом каждой следующей итерации будет выдан запрос на продолжение работы и предложение ввести символ «у», если пользователь желает продолжить. Если значение y не будет равно «y» или «Y», то программа завершит работу.
Далее пользователю нужно ввести значения приближений и требуемой точности. Затем обнуляем счетчик итераций и начинаем цикл расчетов. Этот цикл также с предусловием. Он будет выполняться, если разность между х0 и х1 больше заданной точности. В цикле проводим вычисление корня по формуле итераций.
После цикла (или минуя его, если заданы одинаковые значения приближений) на экран выводятся корень, число итераций и результат проверки найденного корня.
На схеме алгоритма видно, что некоторые однотипные действия повторяются (вычисление функции с подставленным значением х). Поэтому для них лучше создать отдельную функцию в программе. Эта функция будет принимать в качестве аргумента значение х, а возвращать вычисленное значение f(x) = sin(x) – x + 0,15.
Программа будет состоять из двух функций – основной (main) и функции f. Все действия по вводу данных и расчетам будут проводиться в основной (главной) функции. А к функции f программа будет обращаться четыре раза – три раза в цикле вычислений по итерационной формуле и один раз при проверке найденного корня.
Текст программы
#include <iostream.h>
#include <stdlib.h>
#include <math.h>
double f(double x) { return sin(x)-x+0.15; } //Функция, нули которой ищем
int main() {
double tmp,x0,x1,eps;
int N;
char y='y'; //переменная для символа продолжения работы
while (y=='y' || y=='Y') //если пользователь ввел у или Y, продолжаем цикл
{
N=0; //обнуляем счетчик итераций,
cout<<endl<<"eps="; // затем запрашиваем ввод переменных
cin>>eps; //Точность
cout<<"x0=";
cin>>x0; //Первое начальное приближение
cout<<"x1=";
cin>>x1; //Второе начальное приближение
//начинаем итерации
while(fabs(x1-x0)>eps) { //Остановимся, если |x[n]-x[n+1]|<eps
tmp=x1;
x1=x1-(x1-x0)*f(x1)/(f(x1)-f(x0));
x0=tmp;
N++;
}
cout.setf(ios::scientific); //выведем результат в научном формате
cout<<endl<<endl<<"Koren x = "<<x1<<endl<<"chislo iteraciy N="<<N<<endl;
cout<<"Proverka f = "<<f(x1)<<endl; //проведем проверку полученного значения
cout<<endl<<"Prodolzhit? (y - da)"<<endl; //запрос на продолжение работы
cin>>y; //пользователь должен ввести символ для продолжения
}
cin.get();
return 0; //завершаем работу
}
1. Сначала возьмем приближения из окрестности корня. Учитывая вид функции, можно предположить, что корень лежит около единицы. Поэтому возьмем значения -1 и 1, а точность примем 0,00001.
2. Затем возьмем значения подальше от корня - -100 и 100, точность 0,00001.
3. Возьмем большие числа -999 999 999 999 и 999 999 999 999, точность 0,00001.
4. Возьмем числа, лежащие по одну сторону от корня, - 100 и 1000, точность 0, 00001.
5. Приближения - -1 и 10, точность 0.
6. Приближения - -1 и 10, точность 0,1, 0,5 и 1.
7. Приближения 0, 0 и точность 0, а также 0,98 и 0,98
8. Приближения -1 и 10, точность -1. Эти значения должны вызвать исключительную ситуацию, потому что модуль (всегда положительное число) и ноль всегда больше отрицательного числа. В результате проверка сравнения модуля разности (х1 – х0) с eps не сработает ни разу. Если и не возникнет деления на ноль (когда х0 и х1 совпадут), то возникнет ошибка переполнения буфера памяти.
Теоретически ошибка может еще возникнуть, если пользователь введет очень большое число. Но случайно ввести такое число затруднительно.
Далее запускаем программу, подставляем тестовые данные, скриншотим результаты и делаем выводы.
Пример работы программы
