Главная страница


ru.algorithms

 
 - RU.ALGORITHMS ----------------------------------------------------------------
 From : Artem Gubenkov                       2:5020/400     07 Feb 2002  14:35:16
 To : Eduard Vatutin
 Subject : Re: Решение уравнения
 -------------------------------------------------------------------------------- 
 
 Hello, Eduard!
 You wrote to Zapadinsky Anatoly \(ZAB\) on Wed, 06 Feb 2002 01:16:50:
 
  EV>>> Возникла необходимость решать уравнения вида
  EV>>>     A*x^n + B*x^(n-1) + ... + Z = 0
  EV>>> У такого уравнения, согласно основной теореме алгебры, должно быть
  EV>>> n корней.
  EV>>> Hеобходимо найти все его действительные корни. Выручайте...
 
 "Примерные" исходники на BC++B для n==10:
 
 #define K 10 //на сколько частей делим радиус
 #define N 10 //на сколько частей делим угол
 #define EX 0.000001 //погрешность округления
 
 void main()
 {
 double a[11]; complex<double> x[10]; inuse=0;
 double r=0, //внутренний радиус
        R=0; //внешний радиус
 //----------
  //задание коэффициентов
  a[0]=Edit0->Text.ToDouble();
 - ---skiped----
  a[10]=Edit10->Text.ToDouble();
  //проверка коэффициентов
  if(!a[0]) a[0]=1;
 //----------
  //определение границ
  double maxa=fabs(a[0]);
  for(int i=1;i<9;i++)
   if(maxa<fabs(a[i])) maxa=fabs(a[i]);
  r=fabs(a[9])/(fabs(a[9])+maxa);
 
  maxa=fabs(a[1]);
  for(int i=2;i<10;i++)
   if(maxa<fabs(a[i])) maxa=fabs(a[i]);
  R=(fabs(a[0])+maxa)/fabs(a[0]);
 //----------
  //основной цикл
  double k_step=(R-r)/K,  //шаг по радиусу
         n_step=2*3.14159265358979/N; //шаг по углу
 
  for(int l=0; l<K; l++)
   for(int m=0; m<N; m++)
   {
    if(inuse>=10) break;
    //формирование приближенного решения
 complex<double>
 zatravka((r+l*k_step)*sin(m*n_step),(r+l*k_step)*cos(m*n_step));
    //нахождение почти точного решения
    complex<double> radical=FindRadical(zatravka);
    //проверка на присутствие этого решения в уже найденных
    if(!inuse)
     x[inuse++]=radical; //если первый найденный корень
    else
    {
     bool find=false;
     for(int i=0;i<inuse;i++)
      if(abs(x[i]-radical)<EX)
      {
       find=true;
       break;
      }
     if(!find) //если нет, то добавим
      x[inuse++]=radical;
    }
   }
 }
 //----------
 complex<double> FindRadical(complex<double> zatravka)
 {
  complex<double> x(zatravka),x_prev(zatravka);
  do
  {
   x_prev=x;
   x=x_prev-F(x_prev)/F_p1(x_prev);
  }
  while(fabs(abs(x)-abs(x_prev))>EX);
  return x;
 }
 //----------
 complex<double> F(complex<double> x)
 {
  return a[0]*pow(x,10)+a[1]*pow(x,9)+a[2]*pow(x,8)+a[3]*pow(x,7)+
         a[4]*pow(x,6)+a[5]*pow(x,5)+a[6]*pow(x,4)+a[7]*pow(x,3)+
         a[8]*pow(x,2)+a[9]*x+a[10];
 }
 //----------
 complex<double> F_p1(complex<double> x)
 {
  return 10*a[0]*pow(x,9)+9*a[1]*pow(x,8)+8*a[2]*pow(x,7)+
         7*a[3]*pow(x,6)+6*a[4]*pow(x,5)+5*a[5]*pow(x,4)+
         4*a[6]*pow(x,3)+3*a[7]*pow(x,2)+2*a[8]*x+a[9];
 }
 
 P.S. Вспомнил как корни называются - сопряженные
 те корни, у которых мнимая часть < E-10 - действительные
 и лучше использовать long double
 
 With best regards, Artem Gubenkov.
 --- ifmail v.2.15dev5
  * Origin: News Server of JSC Saratov-Mobile (2:5020/400)
 
 

Вернуться к списку тем, сортированных по: возрастание даты  уменьшение даты  тема  автор 

 Тема:    Автор:    Дата:  
 Re: Решение уравнения   Artem Gubenkov   07 Feb 2002 14:35:16 
Архивное /ru.algorithms/106388d149b02.html, оценка 2 из 5, голосов 10
Яндекс.Метрика
Valid HTML 4.01 Transitional