2014 dxdy logo

Научный форум dxdy

Математика, Физика, Computer Science, Machine Learning, LaTeX, Механика и Техника, Химия,
Биология и Медицина, Экономика и Финансовая Математика, Гуманитарные науки




Начать новую тему Ответить на тему
 
 Программы по численным методам
Сообщение18.09.2009, 17:42 
Аватара пользователя


01/12/07
172
Помогите пожалуйста разобраться почему программа не завершает работу(решение уравнения методом хорд)
код: [ скачать ] [ спрятать ]
Используется синтаксис C++
#include "stdafx.h"
#include <math.h>
#include <iostream>
using namespace std;

double f (double x){
        return sin(5*x)*exp(-x)+pow(x,3);
}
double df (double x){
        return  3*pow(x,2) + 5*exp(-x)*cos(5*x)-exp(-x)*sin(5*x);
}
double d2f (double x){
        return 6*x-10*exp(-x)*cos(5*x)-24*exp(-x)*sin(5*x);
}
double min(double a,double b){
        double m1,r;
        int n1=64;
        m1=fabs(df(a));
        double h1=(b-a)/n1;
        for(int e=1;e<=n1;e++){
                r=fabs(df(a-e*h1));
                if(r<m1) m1=r;
        }
        return m1;
}
double max(double a,double b){
        double M1,r;
        int n1=64;
        M1=fabs(df(a));
        double h1=(b-a)/n1;
        for(int e=1;e<=n1;e++){
                r=fabs(df(a-e*h1));
                if(r>M1) M1=r;
        }
        return M1;
}
void hordi(double x0, double c, double m1, double M1){
        int k=1;
        double fc=f(c);
        double fx0=f(x0);
        double x;
        double epsilon=pow(10,-6);
        x=x0-((c-x0)/(fc-fx0))*fx0;
        while((((M1-m1)/m1)*fabs(x-x0))>=epsilon){
                k++;
                x0=x;
                fx0=f(x0);
                x=x0-((c-x0)/(fc-fx0))*fx0;
        }
        cout<<"        x="<<x<<"          f(x)="<<f(x)<<"    k="<<k<<endl;

}
void main(){
        double a=-5;
        double b=1;
        int l=1;
        int j=1;
        int i;
        double A, B, c, x0;
        double n=64;
        double h=(b-a)/n;
for(i=1;i<=n;i++){
                A=a+(i-1)*h;
                B=a+i*h;
                if(f(A)*d2f(A)<0){
                        x0=A;
                        c=B;
                }else{
                        x0=B;
                        c=A;
                }
                cout<<"Root hordi  "<<j;
                hordi(x0,c,min(A,B),max(A,B));
                j++;
        }
}
 

 Профиль  
                  
 
 Re: Программы по численным методам
Сообщение18.09.2009, 19:40 
Заслуженный участник


26/07/09
1559
Алматы
По видимому, проблема с циклом while на 44 строке.

 Профиль  
                  
 
 Re: Программы по численным методам
Сообщение18.09.2009, 19:44 
Заслуженный участник


04/05/09
4582
Скорее всего. Надо убрать множитель ((M1-m1)/m1) - он может оказаться сколь угодно большим.

 Профиль  
                  
 
 Re: Программы по численным методам
Сообщение18.09.2009, 19:56 
Заслуженный участник


26/07/09
1559
Алматы
2venco
Цитата:
Надо убрать множитель ((M1-m1)/m1) - он может оказаться сколь угодно большим

Нет, здесь проблема в том, что модуль разности x-x0 вместо того, чтобы уменьшаться и в конечном счете привести к прерыванию цикла (при сравнении с epsilon), начинает флуктуировать около некоторого значения...

-- Пт сен 18, 2009 23:02:51 --

2matan
Ваш код очень сложно читать и понимать, соответственно и помочь вам будет не легко. Но можно попробовать придумать какое-нибудь ad hoc решение проблемы ("на соплях"), например, попробуйте добавить к предикату проблемного цикла условие &&k<500. То есть ограничьте количество итераций искусственно (у меня работает).

 Профиль  
                  
 
 Re: Программы по численным методам
Сообщение18.09.2009, 20:22 
Аватара пользователя


01/12/07
172
Circiter в сообщении #244481 писал(а):
Ваш код очень сложно читать и понимать

Знаю, но ничего не могу с собой поделать :oops:

Circiter в сообщении #244481 писал(а):
попробуйте добавить к предикату проблемного цикла условие &&k<500. То есть ограничьте количество итераций искусственно (у меня работает).

Выполнение программы то заканчивается, только вот на экран выводятся не только корни. Может есть какой-то другой способ?

 Профиль  
                  
 
 Re: Программы по численным методам
Сообщение18.09.2009, 20:27 
Заслуженный участник


26/07/09
1559
Алматы
Цитата:
Может есть какой-то другой способ?

Переписать все с нуля. :) Но мне лень. :) Можно пошукать готовые реализации в сети.

А у вас есть тестовый пример к задаче? Что программулька должна выводить на самом деле?

 Профиль  
                  
 
 Re: Программы по численным методам
Сообщение18.09.2009, 20:30 
Аватара пользователя


01/12/07
172
Circiter в сообщении #244504 писал(а):
А у вас есть тестовый пример к задаче? Что программулька должна выводить на самом деле?

Примера нет, преподователь просто написал алгоритм.
Circiter в сообщении #244504 писал(а):
Можно пошукать готовые реализации в сети

Готовые реализации есть, но в них разбираться еще сложнее, чем в моем коде :)

 Профиль  
                  
 
 Re: Программы по численным методам
Сообщение18.09.2009, 20:53 
Заслуженный участник


26/07/09
1559
Алматы
Цитата:
Примера нет

Ну вы же говорили, что программка печатает что-то лишнее. Я просто хочу выяснить, что именно. Что выводится кроме корней, какая часть вывода правильна?

 Профиль  
                  
 
 Re: Программы по численным методам
Сообщение19.09.2009, 11:45 
Аватара пользователя


01/12/07
172
Circiter в сообщении #244525 писал(а):
Цитата:
Примера нет

Ну вы же говорили, что программка печатает что-то лишнее. Я просто хочу выяснить, что именно. Что выводится кроме корней, какая часть вывода правильна?

Просто в моей программе есть еще процедура нахождения корней методом дихотомии
Код:
void dihotomia(double a1, double b1){
   int k=1;
   double x;
   double epsilon=pow(10,-6);
   x=(b1+a1)/2;
   double fx=f(x), fa=f(a1);
   while((fabs((b1-a1)/2)>epsilon) || (fabs(fx)>epsilon)){
      if(fa*fx<0){
         b1=x;
      }else{
         a1=x;
         fa=fx;
      }
      k++;
      x=(b1+a1)/2;
      fx=f(x);
   }
   cout<<"    x="<<x;
   cout<<"    f(x)="<<f(x);
   cout<<"    k="<<k<<endl;
}

которая работает правильно(преподователь одобрил). И находит эта процедура 5 корней уравнения. А при выводе результатов процедуры hordi на экране появляются 14 значений(в моем исходном варианте, все 5 корней повторяются по 3 раза), а если воспользоваться Вашей подсказкой, то 64 значения, 59 из которых корнями не являются.

 Профиль  
                  
 
 Re: Программы по численным методам
Сообщение19.09.2009, 12:03 
Заслуженный участник


11/05/08
32166
matan в сообщении #244689 писал(а):
А при выводе результатов процедуры hordi на экране появляются 14 значений (в моем исходном варианте, все 5 корней повторяются по 3 раза),

У Вас там в конце какой-то Очень Странный Цикл for. Метод хорд ведь корректен, только если знаки на концах отрезка противоположны. У Вас же этой проверки не делается. Чего ж и удивляться-то, что корни дублируются: два соседних отрезка и должны типично выбрасывать в один и тот же корень.

Кроме того (хотя это уже и не по существу), довольно нелепо выглядит интерфейс процедуры hordi. Какой смысл вводить четыре формальных параметра, если два последних фактически дублируют два первых?

 Профиль  
                  
 
 Re: Программы по численным методам
Сообщение19.09.2009, 12:11 
Аватара пользователя


01/12/07
172
ewert
Огромное Вам спасибо! Теперь все заработало

 Профиль  
                  
Показать сообщения за:  Поле сортировки  
Начать новую тему Ответить на тему  [ Сообщений: 11 ] 

Модераторы: Karan, Toucan, PAV, maxal, Супермодераторы



Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей


Вы не можете начинать темы
Вы не можете отвечать на сообщения
Вы не можете редактировать свои сообщения
Вы не можете удалять свои сообщения
Вы не можете добавлять вложения

Найти:
Powered by phpBB © 2000, 2002, 2005, 2007 phpBB Group