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

Нахождение комплексных корней методом Ньютона - C++

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 15, средняя оценка - 4.67
gaaalim
0 / 0 / 0
Регистрация: 27.04.2013
Сообщений: 9
02.05.2013, 07:17     Нахождение комплексных корней методом Ньютона #1
Нужно решить уравнение с комплексной переменной z^n +1 = 0. Код вроде написал,но ищет неверно корни.Помогите,пожалуйста.
Заголовочный файл с описание класса.
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
#include <iostream>
#include <cmath>
using namespace std;
 
class Complex
{
private:
        double re, im;
public:
        Complex () {};
        Complex (double r)
        {
            re = r;
            im = 0;
        }
        Complex (double r, double i)
        {
            re = r;
            im = i;
        }
        Complex (const Complex &c)   // конструктор копирования
        {
            re = c.re;
            im = c.im;
        }
        ~Complex () {}
        Complex& operator = (Complex &c)
        {
            re = c.re;
            im = c.im;
            return (*this);
        }
        Complex& operator != (Complex &c)
        {
            re != c.re;
            im != c.im;
            return *this;
        }
        Complex& operator == (Complex &c)
        {
            re == c.re;
            im == c.im;
            return *this;
        }
        Complex& operator += (Complex &c)
        {
            re += c.re;
            im += c.im;
            return *this;
        }
        Complex& operator -= (Complex &c)
        {
            re -= c.re;
            im -= c.im;
            return *this;
        }
        Complex& operator *= (Complex &c)
        {
            re *= c.re;
            im *= c.im;
            return *this;
        }
        Complex& operator /= (Complex &c)
        {
            re /= c.re;
            im /= c.im;
            return *this;
        }
        Complex operator + (const Complex &c)
        {
            return *this;
        }
 
          // оператор вычитания
        Complex operator - (const Complex &c)
        {
            return *this;
        }
        Complex operator * (const Complex &c)
        {
            return Complex(re * c.re - im * c.im, re * c.im + im * c.re);
        }
        Complex operator / (const Complex &c)
        {
            Complex temp;
            double r = c.re * c.re + c.im * c.im;
            temp.re = (re * c.re + im * c.im) / r;
            temp.im = (im * c.re - re * c.im) / r;
            return temp;
        }
        friend ostream & operator<< (ostream &, const Complex &);
        friend istream & operator>> (istream &, Complex &);
        friend Complex powc (Complex f,int n);
        friend double abs (Complex c);
        friend Complex random (Complex c);
};

main
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
#include <iostream>
#include <cmath>
#include "Complex.h"
#include <cstdlib>
#include <ctime>
 
using namespace std;
 
 
// перегрузка оператора <<
ostream& operator<< (ostream &out, const Complex &c)
{
    if(c.im<0)
        out << c.re << c.im << "i";
    else
        out << c.re << "+" << c.im << "i";
    return out;
}
 
// перегрузка оператора >>
istream& operator>> (istream &in, Complex &c)
{
  in >> c.re >> c.im;
  return in;
}
double abs (Complex c)
{
    return sqrt (c.re * c.re + c.im * c.im);
}
 
Complex random (Complex c)
{
    srand(time(NULL));
    c.re=rand()%20 -10;
    c.im=rand()%20 -10;
    return c;
}
Complex koren(int n,Complex xn,Complex e)
{
    Complex xn1;
    do
        {
            xn = xn1;
            Complex xn1 =  xn -  ((powc(xn,n) + Complex (1.0,0.0))/Complex(n,0)*powc(xn,n-1));
            cout << ((powc(xn,n) + Complex (1.0,0.0))/Complex(n,0)*powc(xn,n-1)) <<endl;
            cout << "Koren'=" << xn1  <<  endl;
        }
    while (abs(xn1 - xn) > abs(e));
}
Complex powc (Complex f,int n)
{
    return Complex(pow((f.re * f.re + f.im * f.im),n/2) * cos (n*f.re/sqrt(f.re * f.re + f.im * f.im)),((f.re * f.re + f.im * f.im),n/2) * sin (n*f.re/sqrt(f.re * f.re + f.im * f.im)));
}
int main ()
{
    int n=2;
    Complex xn=random(xn);
    Complex pogr (0.1,0.1);
    koren(n,xn,pogr);
    return 0;
}
Добавлено через 3 минуты
Метод Ньютона http://ru.wikipedia.org/wiki/Метод_Ньютона
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
-=ЮрА=-
Заблокирован
Автор FAQ
02.05.2013, 09:47     Нахождение комплексных корней методом Ньютона #2
gaaalim,
Цитата Сообщение от gaaalim Посмотреть сообщение
Complex koren(int n,Complex xn,Complex e)
{
* * Complex xn1;
* * do
* * * * {
* * * * * * xn = xn1;
* * * * * * Complex xn1 = *xn - *((powc(xn,n) + Complex (1.0,0.0))/Complex(n,0)*powc(xn,n-1));
* * * * * * cout << ((powc(xn,n) + Complex (1.0,0.0))/Complex(n,0)*powc(xn,n-1)) <<endl;
* * * * * * cout << "Koren'=" << xn1 *<< *endl;
* * * * }
* * while (abs(xn1 - xn) > abs(e));
}
- что за вселенская глупость?Где функция, где производная, где возведение в степень?


Давай с нуля - z это комплекс?Какие вообще исходные данные имеются?
Для метода Ньютона ещё и интервал существования корня либо его начальное значение не помешали бы.
gaaalim
0 / 0 / 0
Регистрация: 27.04.2013
Сообщений: 9
02.05.2013, 10:09  [ТС]     Нахождение комплексных корней методом Ньютона #3
-=ЮрА=-, Переписал) производную посчитал вручную,такое было указание в задании. powc функция возведения комплексного числа в степень
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
Complex koren(int n,Complex xn,Complex e)
{
    Complex xn1;
    Complex x = xn;
    Complex f = (powc(xn,n) + Complex (1.0,0.0));
    Complex df = Complex(n,0)*powc(xn,n-1);
    do
        {
            Complex xn1= x - f/df;
            cout << "Koren'=" << xn1  <<  endl;
            x = xn1;
        }
    while (abs(xn1 - x) > abs(e));
}
Добавлено через 9 минут
Да,z комплексное.Исходных условий нет ,поэтому я задаю случайную точку отсчёта.
-=ЮрА=-
02.05.2013, 10:10
  #4

Не по теме:

gaaalim, за сегодня отпишусь кодом

-=ЮрА=-
Заблокирован
Автор FAQ
02.05.2013, 14:11     Нахождение комплексных корней методом Ньютона #5
Вот корректное на мой взгляд решение.
CComplex.h
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
#include <cmath>
#include <iostream>
using namespace std;
 
class CComplex
{
public :
    double _re;
    double _im;
    CComplex();
    CComplex(double re, double im);
    CComplex(const CComplex &pCopy);
 
    CComplex conjugate();
    double complexfabs();
    
    CComplex operator + (CComplex pAdd);
    CComplex operator - (CComplex pAdd);
    CComplex operator * (CComplex pMul);
    CComplex operator / (CComplex pDiv);
 
    CComplex uintpower(unsigned int n);
    friend ostream& operator << (ostream &out, const CComplex pVal)
    {
        out<<pVal._re<<(pVal._im < 0 ? " - " : " + ")<<fabs(pVal._im)<<"j";
        return out;
    }
};
 
CComplex::CComplex()
{
    _re = _im = 0;
}
 
CComplex::CComplex(double re, double im)
{
    _re = re;
    _im = im;
}
 
CComplex::CComplex(const CComplex &pCopy)
{
    _re = pCopy._re;
    _im = pCopy._im;
}
 
CComplex
CComplex::conjugate()
{
    CComplex pThis = (*this);
    pThis._im *= -1;
    return pThis;
}
 
double CComplex::complexfabs()
{
    return _re*_re + _im*_im;
}
 
CComplex
CComplex::operator +(CComplex pAdd)
{
    CComplex pThis = (*this);
    pThis._re += pAdd._re;
    pThis._im += pAdd._im;
    return pThis;
}
 
CComplex
CComplex::operator - (CComplex pAdd)
{
    CComplex pThis = (*this);
    pThis._re -= pAdd._re;
    pThis._im -= pAdd._im;
    return pThis;
}
 
CComplex
CComplex::operator *(CComplex pMul)
{
    CComplex pThis = (*this);
    pThis._re = _re*pMul._re - _im*pMul._im;
    pThis._im = _re*pMul._im + _im*pMul._re;
    return pThis;
}
 
CComplex
CComplex::operator / (CComplex pDiv)
{
    CComplex pThis = (*this);
    double divider = pDiv.complexfabs();
    pThis = pThis*pDiv.conjugate();
    pThis._re /= divider;
    pThis._im /= divider;
    return pThis;
}
 
CComplex
CComplex::uintpower(unsigned int n)
{
    CComplex pThis = CComplex(1, 0);
    for(unsigned int i = 0; i < n; i++)
        pThis = pThis*(*this);
    return pThis;
}
main.cpp
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
#include "CComplex.h"
 
template <class T>
bool SafeInput//безопасный ввод
(
    const char * msg,//сообщение которое будет сопутствовать вводу
    T &val
);
//Для вычислений
CComplex  f(CComplex z, unsigned int n);
CComplex df(CComplex z, unsigned int n);
 
int main()
{
    unsigned int n;
    unsigned int i;
    int iChoise= 0;
    bool bWork = true;
    double err = 0;
    CComplex z;
    while( bWork )
    {
        cout<<"\t***MENU***"<<endl;
        cout<<"1 - solve z^n + 1 == 0"<<endl;
        cout<<"0 - exit"<<endl;
        if(!SafeInput("Your choise : ", iChoise))
            cout<<"Incorrect input"<<endl;
        else
        switch( iChoise )
        {
            case 1 :
                cout<<"Enter initial root z value : "<<endl;
                if(!SafeInput("Re : ", z._re))
                    cout<<"Incorrect input"<<endl;
                else
                if(!SafeInput("Im : ", z._im))
                    cout<<"Incorrect input"<<endl;
                else
                if(!SafeInput("Enter power n : ", n))
                    cout<<"Incorrect input"<<endl;
                else
                if(!SafeInput("Calc error : ", err))
                    cout<<"Incorrect input"<<endl;
                else
                {
                    for(i = 0; f(z, n).complexfabs() > err; i++)
                    {
                        z = z - f(z, n) / df(z, n);
                        cout<<"\r iteration : "<<i + 1<<" root : "<<z<<" error : "<<f(z, n).complexfabs();
                    }
                    z = z - f(z, n) / df(z, n);
                    cout<<"\r iteration : "<<i + 1<<" root : "<<z<<" error : "<<f(z, n).complexfabs()<<endl;
                }
                break;
            case 0 :
                bWork = false;
                break;
            default:
                cout<<"Unsupported key"<<endl;
                break;
        }
    }
    return 0;
}
 
template <class T>
bool SafeInput
(
    const char * msg,//сообщение которое будет сопутствовать вводу
    T &val
)
{
    bool bOk = true;//Флаг успешного ввода
    cout<<msg;//Вывод на экран сопутствующего сообщения
    //Проверка на корректный ввод должна содержать не только if(!(cin>>val) )
    //но и проверку на то что строка более не содержит символов т.е cin.get() != '\n'
    if(!(cin>>val) || cin.get() != '\n')
        bOk = false;
    if(!bOk)
    {
        cin.clear();//Сброс флагов ошибок
        cin.sync();//Очистка буфера ввода
    }
    return bOk;
}
 
CComplex f(CComplex z, unsigned int n)
{
    return z.uintpower(n) + CComplex(1, 0);
}
 
CComplex df(CComplex z, unsigned int n)
{
    return CComplex(n, 0)*z.uintpower(n - 1);
}
Миниатюры
Нахождение комплексных корней методом Ньютона  
gaaalim
0 / 0 / 0
Регистрация: 27.04.2013
Сообщений: 9
02.05.2013, 22:44  [ТС]     Нахождение комплексных корней методом Ньютона #6
-=ЮрА=-, Большое спасибо
Yandex
Объявления
02.05.2013, 22:44     Нахождение комплексных корней методом Ньютона
Ответ Создать тему
Опции темы

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