Форум программистов, компьютерный форум CyberForum.ru

Решение нелинейного уравнения. Метод хорд и касательных - C++

Войти
Регистрация
Восстановить пароль
Другие темы раздела
C++ Узнать количество динамической памяти http://www.cyberforum.ru/cpp-beginners/thread281654.html
Здравствуйте. Препод задал задание на работу с динамической памятью. Саму работу сделал, но теперь вопрос - необходимо узнать сколько доступно программе динамической памяти до обработки и после. Можно ли это сделать в с++? На паскале, помнится, была переменная memavail
C++ Не могу найти ошибку.Наследование Есть код,не компилиться,выдает ошибку,код такой /*13. Задание 1. Создать класс Function с методом вычисления значения функции y=f(x) в заданной точке. 2. Создать производные классы: Line (y=ax+b), Kub (y=ax2+bx+c), Hyperbola ( y=a/x+b ) со своими методами вычисления значения в заданной точке. 3. Создать массив n функций и вывести полную информацию о значении данных функций в точке х. */ http://www.cyberforum.ru/cpp-beginners/thread281652.html
как убрать лишний пробел при выводе дня в дате C++
#include <vcl.h> #include <stdio.h> #include <string.h> #pragma hdrstop #pragma argsused #include <iostream.h> #include <iomanip.h> const int m=20; struct date {unsigned int day,
C++ Структуры
Народ помогите составить прогу на TC со структурами, вообще не врубился как это делать! Задача: Ввести структуру с полями: фамилия, город, адрес для описания понятия житель. Составить и протестировать функцию ИРОНИЯ_СУДЬБЫ (С), которая печатает фамилии двух (любых) жителей из списка С, живущих в разных городах по одинаковому адресу. Заранее благодарю!
C++ Решть систему уравнений http://www.cyberforum.ru/cpp-beginners/thread281636.html
Люди добрые помогите найти ошибку в программе:( не считает матр Н... Решив систему уравнений A(n,n)X=B(n) методом Гаусса, вычислить H=E-XXT. #include <stdio.h> #include <stdlib.h> #include <iostream.h> #include <conio.h> // Функция обращения матрицы
C++ Работа с vector-ом Как организовать поиск заданного элемента в векторе??? подробнее

Показать сообщение отдельно
Iworb
анимешник++
93 / 60 / 2
Регистрация: 03.11.2009
Сообщений: 413

Решение нелинейного уравнения. Метод хорд и касательных - C++

22.04.2011, 22:42. Просмотров 4830. Ответов 2
Метки (Все метки)

Написал я программку для решения, но вот незадача:
Не находит их на некоторых отрезках.
Уравнение: ln(x+1)-p/(x^2)=0
p = -1...1
(т.е. 20 уравнений)
Вот класс, реализующий это решение:
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
typedef double(*foo)(double,double);
 
typedef struct _item
{
    double a,b,p,x;         //[a,b] - интервал, на котором есть корень для уравнения с параметром p. Решение - x
}item;
 
double f(double x, double p)
{
    return log(x+1)-p/(x*x);
}
 
class HK
{
    private:
        foo f;              //функция по которой считаем
        double c,d;         //границы
        int n;              //на сколько разбиваем
        double eps;
        vector<item> s;
        double df(double x, double p);
        double ddf(double x, double p);
        item m(vector<item> x, int f=-1);   //f=1 - максимум, f=-1 - минимум
    public:
        HK(foo function, double c=-1, double d=1, int n=20, double e=0.01);
        vector<item> solve();
        double clarify(double a, double b, double p);
};
 
    HK::HK(foo function, double c, double d, int n, double e)
    {
        f=function;
        this->c=c;
        this->d=d;
        this->n=n;
        eps=e;
        s.clear();
    }
 
    double HK::ddf(double x, double p)
    {
        double dx=pow(10.0,-6);
        return (((f)(x,p)-2*(f)(x-dx,p)+f(x-2*dx,p))/(pow(dx,2)));
    }
 
    double HK::df(double x, double p)
    {
        double dx=pow(10.0,-6);
        return (((f)(x+dx,p)-(f)(x,p))/dx);
    }
 
    item HK::m(vector<item> x, int f)
    {
        item r;
        r.x=(-f)*32000;
        for(int i=0;i<x.size();i++)
            if(f*x[i].x>f*r.x) r=x[i];
        return r;
    }
 
    double HK::clarify(double a, double b, double p)
    {
        double x=(a+b)/2;
        while(fabs(a-b)>eps)
        {
            double ai=a, bi=b;      //старые значения - нужны для расчета новых
            if(df(x,p)*ddf(x,p)>0)
            {
                a=ai-((f)(ai,p)*(bi-ai))/((f)(bi,p)-f(ai,p));
                b=bi-((f)(bi,p))/(df(bi,p));
            }
            else
            {
                a=ai-((f)(ai,p))/(df(ai,p));
                b=bi-((f)(bi,p)*(bi-ai))/((f)(bi,p)-f(ai,p));
            }
            x=(a+b)/2;
        }
        return x;
    }
 
    vector<item> HK::solve()
    {
        double h=(d-c)/n;           //шаг p
        vector<item> x_all;     //вектор всех корней
        for(double p=c;p<=d;p+=h)   //для каждого p от с до d
        {
            x_all.clear();
            for(double x=-2;x<=2;x+=0.2)//бесконечный цикл нахождения корня, начиная от -2. Ищем интервалы по 0.2 и корень в нём
            {
                double a=(f)(x,p), b=(f)(x+0.2,p), a_d=df(x,p), b_d=df(x+0.2,p);
                if((fabs(a-b)>fabs(a+b))&&(fabs(a_d-b_d)<fabs(a_d+b_d)))
                //если знаки разные, то корень есть, а если производная не меняет свой знак - корень один
                //если на интервале [x;x+0.2] есть корень, то его нужно уточнить методом хорд и касательных
                //и занести в значения x_all
                {
                    item temp;
                    temp.a=x;
                    temp.b=x+0.2;
                    temp.p=p;
                    temp.x = clarify(a,b,p);
                    x_all.push_back(temp);
                }
            }
            //если корень не один, то отдаем предпочтение положительным. Если все корни одного знака - наибольшего по модулю
            if(x_all.size()>1)
            {
                vector<item> less, large;
                less.clear(); large.clear();
                for(int i=0;i<x_all.size();i++)
                {
                    if(x_all[i].x<0) less.push_back(x_all[i]);
                    else large.push_back(x_all[i]);
                }
                x_all.clear();
                if(!large.size())
                    x_all.push_back(m(less,-1));
                else
                    x_all.push_back(m(large,1));
            }
            s.push_back(x_all[0]);
        }
        return s;
    }
помогите пожауйста отладить функцию clarify - выдаёт много неправильных значений, но сработало при значениях (-0.8,-0.7,-1) вполне правильно. Ошибка связана с логирафимом - там x>-1 должен быть. Но он и так должен быть >-1, просто со временем интервал [a;b] при уточнение расширяется, а не сужается как надо.
Кому нужно - даю ссылку на сам метод

Добавлено через 17 минут
вроде как отработала нормально, потестил solve, вот что выдало:
| a| b| pi| x|
---------------------------------------------
|-0.8000000|-0.6000000|-1.0000000|-1.#IND000|
|-0.8000000|-0.6000000|-0.9000000|-1.#IND000|
|-0.8000000|-0.6000000|-0.8000000|-1.#IND000|
|-0.8000000|-0.6000000|-0.7000000|-1.#IND000|
|-0.8000000|-0.6000000|-0.6000000|-0.7029787|
|-0.8000000|-0.6000000|-0.5000000|-1.#IND000|
|-0.8000000|-0.6000000|-0.4000000|-0.6316026|
|-0.6000000|-0.4000000|-0.3000000|-1.#IND000|
|-0.6000000|-0.4000000|-0.2000000|-1.#IND000|
|-0.6000000|-0.4000000|-0.1000000|-0.4249508|
| 0.4000000| 0.6000000| 0.1000000|-1.#IND000|
| 0.6000000| 0.8000000| 0.2000000|-1.#IND000|
| 0.6000000| 0.8000000| 0.3000000|-1.#IND000|
| 0.8000000| 1.0000000| 0.4000000| 0.8180327|
| 0.8000000| 1.0000000| 0.5000000|-1.#IND000|
| 0.8000000| 1.0000000| 0.6000000|-1.#IND000|
| 1.0000000| 1.2000000| 0.7000000|-1.#IND000|
| 1.0000000| 1.2000000| 0.8000000|-1.#IND000|
| 1.0000000| 1.2000000| 0.9000000|-1.#IND000|
| 1.0000000| 1.2000000| 1.0000000|-1.#IND000|
---------------------------------------------
как видно - на многих участках работает неправильно(

Добавлено через 14 минут
проверил отдельно: при (-0.8,-0.6,-1) clarify выдает правильное значение, но вот в solve что-то происходит, что делает его неправильным.
Пока заметил, что вместо -0.8, -0.6 передается число ака -0.80000000063 - т.е. что-то в последних битах еще есть. Не знаете как это побороть?
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
 
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.
Рейтинг@Mail.ru