Консультация № 170749
24.07.2009, 14:31
0.00 руб.
0 7 3
Осенью сдаём курсовой проект. В июле получил задание, а посмотреть решил только сейчас, и ужаснулся. Задание с комплексными числами.
Знаний по этой теме ноль, проходить будем только в сентябре. А курсовой уже к тому времени должен быть готов.
Для начала хотелось бы понять матчасть, то есть что именно тут от меня хотят. Сможет ли кто нибудь помочь разобраться.
Задание такое:

Обсуждение

Неизвестный
24.07.2009, 14:58
общий
Андрей Владимирович Маракулин:
Насчет разобраться советую обратиться на форум математиков. Вроде здесь есть такой.
Статья на Википедии
Неизвестный
24.07.2009, 15:55
общий
это ответ
Здравствуйте, Андрей Владимирович Маракулин.

Тема комплексных чисел много раз затрагивалась на портале, воспользуйтесь поиском. Вот один из вариантов реализации:
Код:
# pragma once
# ifndef COMPLEX_H
# define COMPLEX_H

# include <iostream>
# include <iomanip>
# include <cmath>

//abstract base class
class complex
{
private:
virtual std::istream& set(std::istream& is) = 0;
virtual std::ostream& get(std::ostream& os) const = 0;

public: //virtual destructor
virtual ~complex()
{}

//input-output operators redefinition
friend std::istream& operator>>(std::istream& is,complex& c)
{
return c.set(is);
}

friend std::ostream& operator<<(std::ostream& os,const complex& c)
{
return c.get(os);
}

};

class complex_a; class complex_t;

/* Trigonometrical form.
*
*/

class complex_t: public complex
{
double ro,fi;

public://constructors
complex_t(double _ro,double _fi)
:ro(_ro)
,fi(_fi)
{}

complex_t()
:ro(0)
,fi(0)
{}

complex_t(const complex_t& c)
:ro(c.ro)
,fi(c.fi)
{}

complex_t(const complex_a& c);

~complex_t()
{}

public://interface

const complex_t& operator*=(const complex_t& c);
const complex_t operator* (const complex_t& c) const;
const complex_t& operator/=(const complex_t& c);
const complex_t operator/ (const complex_t& c) const;
const complex_t& operator+=(const complex_t& c);
const complex_t operator+ (const complex_t& c) const;
const complex_t& operator-=(const complex_t& c);
const complex_t operator- (const complex_t& c) const;

const complex_t& operator= (const complex_t& c);
operator complex_a () const;

friend class complex_a;

private:
std::istream& set (std::istream& is);
std::ostream& get (std::ostream& os) const;
};

/* Algebraical form.
*
*/

class complex_a :public complex
{
double im,re;

public://constructors
complex_a(double _re,double _im)
:im(_im)
,re(_re)
{}

complex_a()
:im(0)
,re(0)
{}

complex_a(const complex_a& c)
:im(c.im)
,re(c.re)
{}

complex_a(const complex_t& c)
:re(c.ro * cos(c.fi))
,im(c.ro * sin(c.fi))
{}

~complex_a()
{}

public://interface

const complex_a& operator*=(const complex_a& c);
const complex_a operator* (const complex_a& c) const;
const complex_a& operator/=(const complex_a& c);
const complex_a operator/ (const complex_a& c) const;
const complex_a& operator+=(const complex_a& c);
const complex_a operator+ (const complex_a& c) const;
const complex_a& operator-=(const complex_a& c);
const complex_a operator- (const complex_a& c) const;

const complex_a& operator= (const complex_a& c);
operator complex_t () const;

friend class complex_t;

private:
std::istream& set (std::istream& is);
std::ostream& get (std::ostream& os) const;
};


/*complex_t implementation
*
*
*/
complex_t::complex_t(const complex_a& c)
:ro(sqrt(c.re*c.re + c.im*c.im))
,fi(atan(c.im/c.re))
{}

const complex_t& complex_t::operator *=(const complex_t &c)
{
ro *= c.ro;
fi += c.fi;

return *this;
}

const complex_t complex_t::operator *(const complex_t &c) const
{
complex_t tmp(*this);
return (tmp *= c);
}

const complex_t& complex_t::operator /=(const complex_t &c)
{
ro /= (c.ro != 0)? c.ro : 1;
fi -= c.fi;

return *this;
}

const complex_t complex_t::operator /(const complex_t &c) const
{
complex_t tmp(*this);
return (tmp /= c);
}

const complex_t& complex_t::operator +=(const complex_t &c)
{
complex_a z1(*this),z2(c);
*this = complex_t(z1+z2);

return *this;
}

const complex_t complex_t::operator +(const complex_t &c) const
{
complex_a z1(*this),z2(c);

return (complex_t)(z1+z2);
}

const complex_t& complex_t::operator -=(const complex_t &c)
{
complex_a z1(*this),z2(c);
*this = complex_t(z1-z2);

return *this;
}

const complex_t complex_t::operator -(const complex_t &c) const
{
complex_a z1(*this),z2(c);
return (complex_t)(z1-z2);
}

const complex_t& complex_t::operator =(const complex_t &c)
{
ro = c.ro; fi = c.fi;
return *this;
}

complex_t::operator complex_a() const
{
complex_a tmp(*this);
return tmp;
}

std::istream& complex_t::set(std::istream& is)
{
std::cout << "ro:"; is>> ro;
std::cout << "fi:"; is>> fi;

return is;
}

std::ostream& complex_t::get(std::ostream &os) const
{
os << "ro:" << std::setw(8) << ro <<
"\tfi:" << std::setw(8) << fi << std::endl;
return os;
}

/*complex_a implementation
*
*
*/
const complex_a& complex_a::operator *=(const complex_a &c)
{
complex_t z1(*this),z2(c);
*this = complex_a(z1*z2);

return *this;
}

const complex_a complex_a::operator *(const complex_a &c) const
{
complex_t z1(*this),z2(c);
return complex_a(z1*z2);
}

const complex_a& complex_a::operator /=(const complex_a &c)
{
complex_t z1(*this),z2(c);
*this = complex_a(z1/z2);

return *this;
}

const complex_a complex_a::operator /(const complex_a &c) const
{
complex_t z1(*this),z2(c);
return complex_a(z1/z2);
}

const complex_a& complex_a::operator +=(const complex_a &c)
{
re += c.re;
im += c.im;

return *this;
}

const complex_a complex_a::operator +(const complex_a &c) const
{
complex_a tmp(*this);
return (tmp += c);
}

const complex_a& complex_a::operator -=(const complex_a &c)
{
re -= c.re;
im -= c.im;

return *this;}

const complex_a complex_a::operator -(const complex_a &c) const
{
complex_a tmp(*this);
return (tmp -= c);
}

const complex_a& complex_a::operator =(const complex_a &c)
{
re = c.re; im = c.im;
return *this;
}

complex_a::operator complex_t() const
{
complex_t tmp(*this);
return tmp;
}

std::istream& complex_a::set(std::istream& is)
{
std::cout << "re:"; is>> re;
std::cout << "im:"; is>> im;

return is;
}

std::ostream& complex_a::get(std::ostream &os) const
{
os << "re:" << std::setw(8) << re <<
"\tim:" << std::setw(8) << im << std::endl;
return os;
}

# endif //COMPLEX_H


По методу Ньютона лучше обратиться к Википедии. Можно глянуть еще на http://algolist.manual.ru/.
Неизвестный
24.07.2009, 17:15
общий
это ответ
Здравствуйте, Андрей Владимирович Маракулин.

Ну, для начала матчасть по комплексным числам.
Вот информация по комплексным числам на Википедии
Если рассказывать кратко, то комплексные числа есть расширение вещественных путем введения числа [$8730$](-1), обозначаемого [b]i[/b].
Любое комплексное число может быть представлено в виде z=a+b[b]i[/b], где a и b - вещественные числа.
Обычные вещественные числа могут быть записаны в виде z=a+0*[b]i[/b], т.е. вещественные числа являются частью комплексных.

Далее определяем операции над ними:
Пусть:
z1=a1+b1[b]i[/b]
z2=a2+b2[b]i[/b]

Тогда:
z = a+b[b]i[/b] = z1 + z2 [$8660$] {a = a1 + a2; b = b1+b2}
z = a+b[b]i[/b] = z1 * z2 [$8660$] {a = a1*a2 - b1*b2; b = a1*b2+a2*b1}

Более сложные операции (возведение в степень, вычисление корня n-ой степени и т.д.) лучше выполнять не в алгебраической нотации, а, например, в тригонометрической.

Любое комплексное число может быть представлено в тригонометрической форме:
z = r * (Cos[$966$] + [b]i[/b]*Sin[$966$]), где r - модуль комплексного числа, а [$966$] - аргумент. Данные величины определяются по алгебраической записи следующим образом:

r = [$8730$](a2+b2)
tg[$966$] = b/a при a[$8800$]0; [$966$] = pi/2 при a=0 и b>0; [$966$] = 3*pi/2 (или -pi/2) при a=0 и b<0

При такой записи комплексных чисел вычисления степеней и корней производятся очень просто согласно формулам Муавра:
zn = rn * (Cos(n*[$966$])+[i]i[/i]*Sin(n*[$966$]))
z1/n = r1/n * (Cos(([$966$]+2*pi*k)/n)+[i]i[/i]*Sin(([$966$]+2*pi*k)/n)), где k = 0, 1, ..., n-1

Следствие из основной теоремы алгебры утверждает, что любой многочлен степени n с действительными коэффициентами имеет ровно n комплексных корней (возможно, кратных).

В вашем проекте вам требуется определить все эти корни.

Метод Ньютона позволяет определить корень функции.
давно
Мастер-Эксперт
17387
18345
24.07.2009, 18:10
общий
Андрей Владимирович Маракулин:
Здравствуйте!

Не может быть, чтобы курсовой проект (скорее, курсовая работа, судя по тематике) должен быть выполнен до прохождения курса лекций. В каком вузе такие порядки?

И еще, неужели в школе Вам не преподавали элементарные сведения о комплексных числах?

Как все запущено!

С уважением.
Об авторе:
Facta loquuntur.
Неизвестный
24.07.2009, 22:08
общий
это ответ
Здравствуйте, Андрей Владимирович Маракулин.
Вот программа.
Код:

#include <complex>
#include <valarray>
#include <iostream>
#include <iomanip>
#include <stdexcept>
#include <sstream>
#include <locale>
#include <limits>
#include <string>

// Тип с которым будем работать - комплексное число
typedef std::complex<double> value_type;

// Класс-полином для хранения коэффициентов
class polynom
{
// Тип-массив для хранения коэффициентов
typedef std::valarray<value_type> array_type;
public:
// Конструктор
// num - количество коэффициентов
explicit polynom(size_t num);
explicit polynom(array_type coefficients);
// Индексаторы
value_type& operator[](size_t index);
value_type operator[](size_t index) const;
// Возвращает производную
static polynom diff(const polynom& p);
polynom diff() const;
// Вычисляет значение полинома
// value - аргумент
value_type operator()(value_type value) const;
// Возвращает количество коэффициентов
size_t size() const;
private:
array_type _coefficients;
};

template<class _Elem,class _Traits> std::basic_ostream<_Elem,_Traits>& operator<<(std::basic_ostream<_Elem,_Traits>& stream,const polynom& right);

value_type find_root(const polynom& p,const value_type& first,double eps);
template<class T> T input(std::string message);

int main()
{
using std::cout;
using std::endl;

setlocale(LC_ALL,"russian_russia");

size_t pow=input<size_t>("Введите степень полинома:");
polynom f(pow+1);

// Вводим коэффициенты
do
{
std::stringstream str;
str<<"Введите коэффициент при степени "<<pow<<":";
f[pow]=input<value_type>(str.str());
} while (pow--);

cout<<"Исходный полином:"<<endl<<f<<endl;

value_type z=input<value_type>("Начальное приближение:");

double eps=input<double>("Погрешность:");

try
{
value_type root=find_root(f,z,eps);
cout<<"Найден корень:"<<root<<endl;
}
catch (std::runtime_error e)
{
cout<<e.what()<<endl;
}
system("PAUSE");
return 0;
}

// Ищет корень
// p - полином
// first - первое приближение
// eps - погрешность
value_type find_root(const polynom& p,const value_type& first,double eps)
{
value_type result;
// Производная
polynom d=polynom::diff(p);
value_type z=first;
while(true)
{
// Считаем значение производной
value_type dz=d(z);
// Проверяем деление на 0
if(dz!=static_cast<value_type>(0))
{
// Считаем следующее значение
result=z-p(z)/dz;
// Проверяем погрешность
if(abs(result-z)<=eps)break;
z=result;
}
else
{
throw std::runtime_error("Деление на ноль. Производная равна нулю.");
}
}
return result;
}

// Функция для ввода с подсказкой
template<class T>
T input(std::string message)
{
using std::cin;
using std::cout;
using std::numeric_limits;
using std::streamsize;

T result;
while(true)
{
cout<<message;
cin>>result;
if(cin.fail())
{
cout<<"Ошибка ввода"<<std::endl;
cin.clear();
cin.ignore(numeric_limits<streamsize>::max(),'\n');
}
else
{
cin.ignore(numeric_limits<streamsize>::max(),'\n');
break;
}
}
return result;
}

#pragma region class polynom

polynom::polynom( size_t num ) :_coefficients(0,num)
{
}

polynom::polynom( array_type coefficients )
{
_coefficients=coefficients;
}

inline value_type& polynom::operator[]( size_t index )
{
return _coefficients[index];
}

inline value_type polynom::operator[]( size_t index ) const
{
return _coefficients[index];
}

inline polynom polynom::diff( const polynom& p )
{
return p.diff();
}

polynom polynom::diff() const
{
size_t size=_coefficients.size();
if(size>0)
{
polynom result(size-1);
for(size_t i=1;i<size;++i)
{
result._coefficients[i-1]=_coefficients[i]*static_cast<value_type>(i);
}
return result;
}
else
{
throw std::runtime_error("Количество коэффициентов полинома должно быть больше нуля");
}
}

value_type polynom::operator()( value_type value ) const
{
value_type result(0,0);
size_t i=_coefficients.size();
while(i)
{
--i;
result=result*value+_coefficients[i];
}
return result;
}

inline size_t polynom::size() const
{
return _coefficients.size();
}

template<class _Elem,class _Traits>
std::basic_ostream<_Elem,_Traits>& operator<<(std::basic_ostream<_Elem,_Traits>& stream,const polynom& right)
{
const std::ctype<_Elem>& fac=std::use_facet<std::ctype<_Elem> >(stream.getloc());
std::basic_stringstream<_Elem,_Traits> str;
str.imbue(stream.getloc());
str.precision(stream.precision());
str.width(stream.width());
str.flags(stream.flags());
size_t i=right.size();
while(i)
{
--i;
str<<right[i];
if(i)
{
str<<fac.widen('*')<<fac.widen('Z')<<fac.widen('^')<<i<<fac.widen('+');
}
}
return stream<<str.str();
}

#pragma endregion class polynom

Пример работы:
Код:

Введите степень полинома:4
Введите коэффициент при степени 4:(-1,-5)
Введите коэффициент при степени 3:(2,9)
Введите коэффициент при степени 2:2
Введите коэффициент при степени 1:-8
Введите коэффициент при степени 0:(8,-1)
Исходный полином:
(-1,-5)*Z^4+(2,9)*Z^3+(2,0)*Z^2+(-8,0)*Z^1+(8,-1)
Начальное приближение:1
Погрешность:0.00001
Найден корень:(0.797467,0.380048)
Неизвестный
21.08.2009, 15:06
общий
Гордиенко Андрей Владимирович, очень даже может быть. Вот так вот у нас устроено ускоренное заочное обучение. Название ВУЗа, разуммется, написать не могу... Да и имеет ли это какое то значение..

Уважаемый Micren, спасибо, будем разбираться
Неизвестный
21.08.2009, 18:27
общий
Гордиенко Андрей Владимирович:
В каком вузе такие порядки?

Почти во всехПричем, не только в бывших республиках такое. Логика преподавателя бывает очень альтернативной. В Германии мне тоже приходилось посещать пару предметов, где домашнее задание надо было сдавать ПЕРЕД началом лекции по соответствующей теме.
Форма ответа