# 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
#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)
Если Вы уже зарегистрированы на Портале - войдите в систему, если Вы еще не регистрировались - пройдите простую процедуру регистрации.