|
|
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) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /ru.algorithms/106388d149b02.html, оценка из 5, голосов 10
|