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

Численные методы решения нелинейного уравнения - C++

Восстановить пароль Регистрация
 
Drosya12
0 / 0 / 0
Регистрация: 22.10.2013
Сообщений: 61
07.07.2015, 20:42     Численные методы решения нелинейного уравнения #1
Доброе время суток, товарищи программисты. Есть задача: решить уравнение Cos(1.3x)=1/x. Численным методом. Написал программу для решения, но проблема в том, что надо найти первые n корней, не понимаю, как подобное можно реализовать.
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
#include "stdafx.h"
#include <iostream>
#include <math.h>
 
using namespace std;
float m_ch(float, float, float);
float your_function(float);
int main()
{
    cout << m_ch(3, 4, 0.001) << endl;
    return 0;
}
float m_ch(float x1, float x2, float e){
    if (fabs(x2 - x1)<e) return x2;
    return m_ch((x1 - ((your_function(x1))*(x2 - x1)) / (your_function(x2) - your_function(x1))), x1, e);
}
float your_function(float x){
    return cos(1.3*x) -(1/x);
}
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
07.07.2015, 20:42     Численные методы решения нелинейного уравнения
Посмотрите здесь:

C++ Численные методы. Дихотомия
C++ численные методы
C++ Численные методы решения линейных алгебраических уравнений
Численные методы C++
Программы для решения нелинейного уравнения C++
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
Sn1p3rOk
 Аватар для Sn1p3rOk
281 / 168 / 66
Регистрация: 19.04.2014
Сообщений: 1,078
Завершенные тесты: 2
08.07.2015, 01:48     Численные методы решения нелинейного уравнения #2
Вывести первые n - корней на экран и что тут такого. Или я чего-то не понимаю?
Drosya12
0 / 0 / 0
Регистрация: 22.10.2013
Сообщений: 61
08.07.2015, 06:45  [ТС]     Численные методы решения нелинейного уравнения #3
Не совсем представляю:как это сделать

Добавлено через 6 минут
Засунуть условия в цикл и выполнять его до n шага,заданного вручную? Как бы,мысль есть, но из-за недостаточного понимания численных методов(всего день изучаю) и малой фантазии в программировании, не выходит сделать...
Mr.X
Эксперт С++
 Аватар для Mr.X
2799 / 1575 / 246
Регистрация: 03.05.2010
Сообщений: 3,656
08.07.2015, 09:16     Численные методы решения нелинейного уравнения #4
Не очень понятно о каких n корнях идет речь. Они по всей числовой оси есть от минус до плюс бесконечности. Если для определенности говорить об n положительных корнях, то вот так можно:
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
/////////////////////////////////////////////////////////////////////////////////////////
//Решить уравнение
//cos(1.3 * x) = 1/x
//численным методом. Найти первые n корней.
/////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <cmath>
#include <iostream>
#include <set>
#include <string>
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::string                 T_str;
typedef std::set    < double    >   T_roots;
/////////////////////////////////////////////////////////////////////////////////////////
const   double  EPS     =   0.00001;
const   T_str   EQ_STR  =   "cos(1.3 * x) = 1/x";
/////////////////////////////////////////////////////////////////////////////////////////
double  f( double   x )
{
    return  cos( 1.3 * x ) - 1 / x;
}
/////////////////////////////////////////////////////////////////////////////////////////
double  get_root_in_segment
    (
        double  L,
        double  R
    )
{
    while   (
                R - L   >   EPS
            )
    {
        double  M   =   (L + R) / 2;
 
        f(M) * f(L)     <   0
            ?   R   =   M
            :   L   =   M;
    }//while
 
    return  L;
}
/////////////////////////////////////////////////////////////////////////////////////////
double  get_root_to_right_of( double   L )
{
    if  (
            f(L) == 0
        )
    {
        L   +=  EPS;
    }
 
    double  R   =   L;
 
    while   (
                f(L) * f(R)     >=  0
            )
    {
        R   +=  EPS;
    }
 
    return  get_root_in_segment( L, R );
}
/////////////////////////////////////////////////////////////////////////////////////////
T_roots     get_n_positive_roots( int    n )
{
    T_roots     res_roots;
    double      root    =   0;
 
    for( int  i = 0; i < n; ++i )
    {
        root    =   get_root_to_right_of( root + EPS );
        res_roots.insert( root );
    }//for
 
    return  res_roots;
}
/////////////////////////////////////////////////////////////////////////////////////////
void    print_roots( T_roots    const   &   roots )
{
    std::cout   <<  std::endl
                <<  "Первые "
                <<  roots.size()
                <<  " положительных корней уравнения "
                <<  EQ_STR
                <<  ":"
                <<  std::endl;
 
    std::for_each
        (
            roots.begin     (),
            roots.end       (),
 
            []              ( double    root )
            {
                static  int     counter     =   0;
 
                std::cout   <<  '#'
                            <<  ++counter
                            <<  "\t"
                            <<  "f( "
                            <<  std::fixed
                            <<  root
                            <<  "\t) = "
                            <<  f( root )
                            <<  std::endl;
            }
        );
}
/////////////////////////////////////////////////////////////////////////////////////////
int     main()
{
    std::locale::global(std::locale(""));
 
    std::cout   <<  "Введите количество искомых положительных корней уравнения"
                <<  std::endl
                <<  EQ_STR
                <<  ": ";
 
    int         n   =   0;
    std::cin    >>  n;
    T_roots     roots   =   get_n_positive_roots( n );
    print_roots     ( roots );
    system          ("pause");
}
Drosya12
0 / 0 / 0
Регистрация: 22.10.2013
Сообщений: 61
08.07.2015, 22:44  [ТС]     Численные методы решения нелинейного уравнения #5
Да-да, я имел в виду положительные,извиняюсь,что не оговорил это. При повышении точности,только,программа,почему-то не отрабатывает вовсе...
Mr.X
Эксперт С++
 Аватар для Mr.X
2799 / 1575 / 246
Регистрация: 03.05.2010
Сообщений: 3,656
09.07.2015, 01:46     Численные методы решения нелинейного уравнения #6
Цитата Сообщение от Drosya12 Посмотреть сообщение
При повышении точности,только,программа,почему-то не отрабатывает вовсе...
Вот так работает:
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
125
126
127
128
129
130
131
132
/////////////////////////////////////////////////////////////////////////////////////////
//Решить уравнение
//cos(1.3 * x) = 1/x
//численным методом. Найти первые n корней.
/////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <set>
#include <string>
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::string                 T_str;
typedef std::set    < double    >   T_roots;
/////////////////////////////////////////////////////////////////////////////////////////
const   int     EPS_EXP     =   12;
const   double  EPS         =   pow( 10.0, -EPS_EXP );
const   double  STEP        =   0.1;
const   T_str   EQ_STR  =   "cos(1.3 * x) = 1/x";
/////////////////////////////////////////////////////////////////////////////////////////
double  f( double   x )
{
    return  cos( 1.3 * x ) - 1 / x;
}
/////////////////////////////////////////////////////////////////////////////////////////
double  get_root_in_segment
    (
        double  L,
        double  R
    )
{
    while   (
                    abs (
                            f(R) - f(L)
                        )
 
                >   EPS
            )
    {
        double  M   =   (L + R) / 2;
 
        f(M) * f(L)     <   0
            ?   R   =   M
            :   L   =   M;
    }//while
 
    return  L;
}
/////////////////////////////////////////////////////////////////////////////////////////
double  get_root_to_right_of( double   L )
{
    if  (
            f(L) == 0
        )
    {
        return  L;
    }
 
    double  R   =   L;
 
    while   (
                f(L) * f(R)     >=  0
            )
    {
        R   +=  STEP;
    }
 
    return  get_root_in_segment( L, R );
}
/////////////////////////////////////////////////////////////////////////////////////////
T_roots     get_n_positive_roots( int    n )
{
    T_roots     res_roots;
    double      root    =   0;
 
    for( int  i = 0; i < n; ++i )
    {
        root    =   get_root_to_right_of( root + STEP );
        res_roots.insert( root );
    }//for
 
    return  res_roots;
}
/////////////////////////////////////////////////////////////////////////////////////////
void    print_roots( T_roots    const   &   roots )
{
    std::cout   <<  std::endl
                <<  "Первые "
                <<  roots.size()
                <<  " положительных корней уравнения "
                <<  EQ_STR
                <<  ":"
                <<  std::endl;
 
    std::for_each
        (
            roots.begin     (),
            roots.end       (),
 
            []              ( double    root )
            {
                static  int     counter     =   0;
 
                std::cout   <<  '#'
                            <<  ++counter
                            <<  "\t"
                            <<  "f( "
                            <<  std::fixed
                            <<  std::setprecision( EPS_EXP + 2 )
                            <<  root
                            <<  "\t) = "
                            <<  f( root )
                            <<  std::endl;
            }
        );
}
/////////////////////////////////////////////////////////////////////////////////////////
int     main()
{
    std::locale::global(std::locale(""));
 
    std::cout   <<  "Введите количество искомых положительных корней уравнения"
                <<  std::endl
                <<  EQ_STR
                <<  ": ";
 
    int         n   =   0;
    std::cin    >>  n;
    T_roots     roots   =   get_n_positive_roots( n );
    print_roots     ( roots );
    system          ("pause");
}
Добавлено через 1 час 17 минут
А еще правильнее вот так будет:
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
125
126
127
128
129
130
131
132
/////////////////////////////////////////////////////////////////////////////////////////
//Решить уравнение
//cos(1.3 * x) = 1/x
//численным методом. Найти первые n корней.
/////////////////////////////////////////////////////////////////////////////////////////
#include <algorithm>
#include <cmath>
#include <iomanip>
#include <iostream>
#include <limits>
#include <set>
#include <string>
/////////////////////////////////////////////////////////////////////////////////////////
typedef std::string                 T_str;
typedef std::set    < double    >   T_roots;
/////////////////////////////////////////////////////////////////////////////////////////
const   int     EPS_EXP     =   12;
const   double  EPS         =   pow( 10.0, -EPS_EXP );
const   double  STEP        =   0.1;
const   T_str   EQ_STR  =   "cos(1.3 * x) = 1/x";
/////////////////////////////////////////////////////////////////////////////////////////
double  f( double   x )
{
    return  cos( 1.3 * x ) - 1 / x;
}
/////////////////////////////////////////////////////////////////////////////////////////
double  get_root_in_segment
    (
        double  L,
        double  R
    )
{
    while   (
                    R - L   >   std::max    (
                                                EPS,
                                                abs( R )    *   std::numeric_limits < double >::epsilon()
                                            )
            )
    {
        double  M   =   (L + R) / 2;
 
        f(M) * f(L)     <   0
            ?   R   =   M
            :   L   =   M;
    }//while
 
    return  L;
}
/////////////////////////////////////////////////////////////////////////////////////////
double  get_root_to_right_of( double   L )
{
    if  (
            f(L) == 0
        )
    {
        return  L;
    }
 
    double  R   =   L;
 
    while   (
                f(L) * f(R)     >=  0
            )
    {
        R   +=  STEP;
    }
 
    return  get_root_in_segment( L, R );
}
/////////////////////////////////////////////////////////////////////////////////////////
T_roots     get_n_positive_roots( int    n )
{
    T_roots     res_roots;
    double      root    =   0;
 
    for( int  i = 0; i < n; ++i )
    {
        root    =   get_root_to_right_of( root + STEP );
        res_roots.insert( root );
    }//for
 
    return  res_roots;
}
/////////////////////////////////////////////////////////////////////////////////////////
void    print_roots( T_roots    const   &   roots )
{
    std::cout   <<  std::endl
                <<  "Первые "
                <<  roots.size()
                <<  " положительных корней уравнения "
                <<  EQ_STR
                <<  ":"
                <<  std::endl;
 
    std::for_each
        (
            roots.begin     (),
            roots.end       (),
 
            []              ( double    root )
            {
                static  int     counter     =   0;
 
                std::cout   <<  '#'
                            <<  ++counter
                            <<  "\t"
                            <<  "f( "
                            <<  std::fixed
                            <<  std::setprecision( EPS_EXP + 2 )
                            <<  root
                            <<  "\t) = "
                            <<  f( root )
                            <<  std::endl;
            }
        );
}
/////////////////////////////////////////////////////////////////////////////////////////
int     main()
{
    std::locale::global(std::locale(""));
 
    std::cout   <<  "Введите количество искомых положительных корней уравнения"
                <<  std::endl
                <<  EQ_STR
                <<  ": ";
 
    int         n   =   0;
    std::cin    >>  n;
    T_roots     roots   =   get_n_positive_roots( n );
    print_roots     ( roots );
    system          ("pause");
}
Yandex
Объявления
09.07.2015, 01:46     Численные методы решения нелинейного уравнения
Ответ Создать тему
Опции темы

Текущее время: 00:56. Часовой пояс GMT +3.
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2016, vBulletin Solutions, Inc.
Рейтинг@Mail.ru