2016-01-19 3 views
2

Я пытаюсь создать функцию, которая вычисляет 4 корня многочлена 4-й степени с включенными комплексными числами. В моем поиске формулы я натолкнулся на довольно простой, содержащийся в this discussion, описанный Тито Пьезасом III в нижней части страницы.Невозможно вычислить, как вычислить многочлены 4-й степени

Теперь я считаю, что настоящая ошибка на самом деле не является ошибкой в ​​моем коде (поскольку я уверен, что это будет раздражать корректуру), но в моем понимании метода. Моя проблема в том, что квадратичные корни сложны, и я не знаю, как использовать комплексные числа при вычислении квадратичных корней, программно.

Предлагается вывести коренные корни с помощью корней двух квадратичных уравнений. Я попытался подражать формуле, насколько я могу, с моим кодом ниже. Идея состоит в том, что я вычисляю два квадратичных корня (при условии, что они являются положительными только --- я не знаю, как иначе), то, используя эти результаты, я могу вычислить куртические корни, которые затем сохраняю в реальном и сложном значения в x1,x2,x3,x4 в r1,r2,r3,r4,c1,c2,c3,c4 соответственно. Но, вычисляя квадратичные корни, u, значение, используемое позже для вычисления квадратичных корней: комплексно!

Описание: Формула и этапы image. Blow - мой код с надписями на большинстве шагов.

     double a, b, c, d; 
         double c1, c2, c3, c4;  //complex values 
         double r1, r2, r3, r4;  //real values 

         //  x^4+ax^3+bx^2+cx+d=0 
         a = 3;  
         b = 4; 
         c = 5;  //<--- example coefficients 
         d = 6; 
         if (a != 0) { 

          double u,v1,v2;  
          double x,y,z;  //essentially a,b,c that he uses 

          x=1; 
          y= -2*b*b*b+9*a*b*c-27*c*c-27*a*a*d+72*b*d; 
          z= Math.pow((b*b-3*a*c+12*d),3); 

           //calculation of the v roots 
          v1 = -y+(Math.sqrt(y*y-4*x*z))/(2*x); // < negative root 
          v2 = -y-(Math.sqrt(y*y-4*x*z))/(2*x); // < negative root 

       //---calculations after this are invalid since v1 and v2 are NaN---  

          u = (a*a)/4 + ((-2*b+Math.pow(v1,1/3)+Math.pow(v2,1/3))/3); 

          double x12sub,x34sub; 

          x12sub= 3*a*a-8*b-4*u+((-a*a*a+4*a*b-8*c)/(Math.sqrt(u))); 
          x34sub= 3*a*a-8*b-4*u-((-a*a*a+4*a*b-8*c)/(Math.sqrt(u))); 

          r1 = -(1/4)*a +(1/2)*(Math.sqrt(u)); 
          r2 = -(1/4)*a +(1/2)*(Math.sqrt(u)); 
          r3 = -(1/4)*a -(1/2)*(Math.sqrt(u)); 
          r4 = -(1/4)*a -(1/2)*(Math.sqrt(u)); 

         //--casting results into their orderly variables-- 



          if(x12sub<0){ 
           x12sub= x12sub*-1; 
           x12sub = Math.sqrt(x12sub); 
           x12sub = x12sub*(1/4); 
           c1=x12sub; 
           c2=x12sub; 
          } 
          else{ 
           r1=r1+x12sub; 
           r2=r2-x12sub; 
          } 
          if(x34sub<0){ 
           x34sub= x34sub*-1; 
           x34sub = Math.sqrt(x34sub); 
           x34sub = x34sub*(1/4); 
           c3=x34sub; 
           c4=x34sub; 
          } 
          else{ 
           r3=r3+x34sub; 
           r4=r4+x34sub; 
          } 

Я открыт для ЛЮБОГО решения. Даже те, которые связаны с использованием библиотек, которые могут мне помочь. Спасибо за помощь.

+0

[Это] (http://math.stackexchange.com/questions/44406/how-do-i-get-the-square-root-of-a-complex-number) может быть полезно для части вашего проблема. –

+1

Возможный дубликат [Поиск реальных корней уравнения в квартике с использованием метода феррари] (http://stackoverflow.com/questions/27217113/finding-real-roots-of-quartic-equation-using-ferraris-method) – Teepeemm

+0

Вы вероятно, лучше использовать неявный метод, такой как метод Дженкинса-Трауба. Вот [довольно хорошая статья] (http://math-blog.com/2008/03/06/polynomial-root-finding-with-the-jenkins-traub-algorithm/) о методе Дженкинса-Трауба. –

ответ

1

Попробуйте использовать эффективную библиотеку матриц Java. Вы можете скачать банки здесь: https://sourceforge.net/projects/ejml/files/v0.28/

Вы должны иметь этот метод в своем классе:

public static Complex64F[] findRoots(double... coefficients) { 
    int N = coefficients.length-1; 

    // Construct the companion matrix 
    DenseMatrix64F c = new DenseMatrix64F(N,N); 

    double a = coefficients[N]; 
    for(int i = 0; i < N; i++) { 
     c.set(i,N-1,-coefficients[i]/a); 
    } 
    for(int i = 1; i < N; i++) { 
     c.set(i,i-1,1); 
    } 

    // use generalized eigenvalue decomposition to find the roots 
    EigenDecomposition<DenseMatrix64F> evd = DecompositionFactory.eig(N,false); 

    evd.decompose(c); 

    Complex64F[] roots = new Complex64F[N]; 

    for(int i = 0; i < N; i++) { 
     roots[i] = evd.getEigenvalue(i); 
    } 

    return roots; 
} 

Затем вы можете использовать это, чтобы найти, например, корни х^2 + 4x + 4 :

Complex64F[] c = findRoots(4, 4, 1); 
    for(Complex64F f : c) 
     System.out.println(f.toString()); 

Это напечатает:

-2 
-2 

который является желаемым результатом.

+0

Соответствующая вещь - это поставить вопрос, а не опубликовать ссылку. И вы не должны отправлять ссылку только на ответ. – Teepeemm

+0

С сломанной гиперссылкой, не менее. – Teepeemm

+0

Спасибо, это сработало для меня. –

Смежные вопросы