Отправляет email-рассылки с помощью сервиса Sendsay
  Все выпуски  

RFpro.ru: Программирование на C / C++


Хостинг портала RFpro.ru:
Московский хостер
Профессиональный платный хостинг на базе Windows 2008

РАССЫЛКИ ПОРТАЛА RFPRO.RU

Чемпионы рейтинга экспертов в этой рассылке

_Ayl_
Статус: Студент
Рейтинг: 917
∙ повысить рейтинг >>
Micren
Статус: Практикант
Рейтинг: 461
∙ повысить рейтинг >>
Серг aka umbSSE
Статус: 10-й класс
Рейтинг: 236
∙ повысить рейтинг >>

∙ / КОМПЬЮТЕРЫ И ПО / Языки программирования / C/C++

Выпуск № 1362 от 29.07.2009, 14:35
Администратор рассылки: Dr_Andrew, Модератор
В рассылке: подписчиков - 637, экспертов - 157
В номере: вопросов - 1, ответов - 3

Нам очень важно Ваше мнение об этом выпуске рассылки. Вы можете оценить этот выпуск по пятибалльной шкале, пройдя по ссылке:
оценить выпуск >>

Вопрос № 170749: Осенью сдаём курсовой проект. В июле получил задание, а посмотреть решил только сейчас, и ужаснулся. Задание с комплексными числами. Знаний по этой теме ноль, проходить будем только в сентябре. А курсовой уже к тому времени должен быть готов. Д...



Вопрос № 170749:

Осенью сдаём курсовой проект. В июле получил задание, а посмотреть решил только сейчас, и ужаснулся. Задание с комплексными числами.
Знаний по этой теме ноль, проходить будем только в сентябре. А курсовой уже к тому времени должен быть готов.
Для начала хотелось бы понять матчасть, то есть что именно тут от меня хотят. Сможет ли кто нибудь помочь разобраться.
Задание такое:

Отправлен: 24.07.2009, 14:31
Вопрос задал: Андрей Владимирович Маракулин, Посетитель
Всего ответов: 3
Страница вопроса >>


Отвечает Ross, Практикант :
Здравствуйте, Андрей Владимирович Маракулин.

Тема комплексных чисел много раз затрагивалась на портале, воспользуйтесь поиском. Вот один из вариантов реализации:
Код:
# 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 co mplex_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/.

-----
Good judgement comes from experience, and experience comes from bad judgement.

Ответ отправил: Ross, Практикант
Ответ отправлен: 24.07.2009, 15:55

Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 252567 на номер 1151 (Россия) | Еще номера >>
  • Отправить WebMoney:
  • Вам помогли? Пожалуйста, поблагодарите эксперта за это!
    Отвечает _Ayl_, Студент :
    Здравствуйте, Андрей Владимирович Маракулин.

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

    Далее определяем операции над ними:
    Пусть:
    z1=a1+b1i
    z2=a2+b2i

    Тогда:
    z = a+bi = z1 + z2 ⇔ {a = a1 + a2; b = b1+b2}
    z = a+bi = z1 * z2 ⇔ {a = a1*a2 - b1*b2; b = a1*b2+a2*b1}

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

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

    r = √(a2+b2)
    tgφ = b/a при a≠0; φ = pi/2 при a=0 и b>0; φ = 3*pi/2 (или -pi/2) при a=0 и b<0

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

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

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

    Метод Ньютона позволяет определить корень функции.

    Ответ отправил: _Ayl_, Студент
    Ответ отправлен: 24.07.2009, 17:15

    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 252571 на номер 1151 (Россия) | Еще номера >>
  • Отправить WebMoney:
  • Вам помогли? Пожалуйста, поблагодарите эксперта за это!
    Отвечает Micren, Практикант :
    Здравствуйте, Андрей Владимирович Маракулин.
    Вот программа.

    Код:

    #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=_coefficie nts.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 endr egion 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)

    Ответ отправил: Micren, Практикант
    Ответ отправлен: 24.07.2009, 22:08

    Как сказать этому эксперту "спасибо"?
  • Отправить SMS #thank 252583 на номер 1151 (Россия) | Еще номера >>
  • Отправить WebMoney:
  • Вам помогли? Пожалуйста, поблагодарите эксперта за это!


    Нам очень важно Ваше мнение об этом выпуске рассылки. Вы можете оценить этот выпуск по пятибалльной шкале, пройдя по ссылке:
    оценить выпуск >>

    подать вопрос экспертам этой рассылки >>

    Скажите "спасибо" эксперту, который помог Вам!

    Отправьте СМС-сообщение с тестом #thank НОМЕР_ОТВЕТА
    на короткий номер 1151 (Россия)

    Номер ответа и конкретный текст СМС указан внизу каждого ответа.

    Полный список номеров >>

    * Стоимость одного СМС-сообщения от 7.15 руб. и зависит от оператора сотовой связи. (полный список тарифов)
    ** При ошибочном вводе номера ответа или текста #thank услуга считается оказанной, денежные средства не возвращаются.
    *** Сумма выплаты эксперту-автору ответа расчитывается из суммы перечислений на портал от биллинговой компании.


    © 2001-2009, Портал RFpro.ru, Россия
    Авторское право: ООО "Мастер-Эксперт Про"
    Автор: Калашников О.А. | Программирование: Гладенюк А.Г.
    Хостинг: Компания "Московский хостер"
    Версия системы: 2009.6.6 от 21.07.2009

    В избранное