Advertisement
Guest User

Untitled

a guest
Jun 23rd, 2017
67
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Java 7.04 KB | None | 0 0
  1. package de.jtdev.jcurve.ui;
  2.  
  3. public class Solver {
  4.  
  5.     /**
  6.      * Solves the linear equation 0 = c1*x + c0 for x. Result will be stored in
  7.      * the given arrays. The number of found solutions will be returned.
  8.      * @param c0   First parameter of the equation
  9.      * @param c1   Second parameter of the equation
  10.      * @param real Array of doubles with minimum length of 1, which the real
  11.      *             part of the result is stored in
  12.      * @param imag Array of doubles with minimum length of 1, which the
  13.      *             imaginary part of the solution is stored in (will be set to
  14.      *             0.0 if a solution is found).
  15.      * @return If the equation has no solution 0 is returned. In case of
  16.      *         infinit sollutions -1 is returned to distiguish this two cases.
  17.      *         Otherwise 1 to indicate a solution was found.
  18.      */
  19.     public static int solveLinear(double c0, double c1, double[] real, double[] imag) {
  20.         if (c1 == 0.0d) {
  21.             if (c0 == 0.0d) {
  22.                 return -1;
  23.             } else {
  24.                 return 0;
  25.             }
  26.         }
  27.  
  28.         real[0] = -c0 / c1;
  29.         imag[0] = 0.0d;
  30.         return 1;
  31.     }
  32.  
  33.     /**
  34.      * Solves the quadric equation 0 = c2*x^2 + c1*x + c0 for x. Result will be
  35.      * stored in the given arrays, which might be complex. The number of found
  36.      * solutions will be returned.
  37.      *
  38.      * Note: Same solution might be returned twice.
  39.      *
  40.      * @param c0   First parameter of the equation
  41.      * @param c1   Second parameter of the equation
  42.      * @param c2   Third parameter of the equation
  43.      * @param real Array of doubles with minimum length of 2, which the real
  44.      *             part of the result is stored in
  45.      * @param imag Array of doubles with minimum length of 2, which the
  46.      *             imaginary part of the solution is stored in (will be set to
  47.      *             0.0 if a solution is found).
  48.      * @return If the equation has no solution 0 is returned. In case of
  49.      *         infinit sollutions -1 is returned to distiguish this two cases.
  50.      *         Otherwise the number of found sollutions is returned
  51.      */
  52.     public static int solveQuadric(double c0, double c1, double c2, double[] real, double[] imag) {
  53.         if (c2 == 0.0d)
  54.             return solveLinear(c0, c1, real, imag);
  55.  
  56.         double q = c0 / c2;
  57.         double p = c1 / c2;
  58.         double d = p*p / 4.0d - q;
  59.  
  60.         if (d >= 0.0d) {
  61.             real[0] = -p / 2.0d + Math.sqrt(d);
  62.             real[1] = -p / 2.0d - Math.sqrt(d);
  63.             imag[0] = 0.0d;
  64.             imag[1] = 0.0d;
  65.         } else {
  66.             real[0] = -p / 2.0d;
  67.             real[1] = real[0];
  68.             imag[0] = Math.sqrt(-d);
  69.             imag[1] = -imag[0];
  70.         }
  71.         return 2;
  72.     }
  73.  
  74.     /**
  75.      * Solves the cubic equation 0 = c3*x^3 + c2*x^2 + c1*x + c0 for x. Result
  76.      * will be stored in the given arrays, which might be complex. The number
  77.      * of found solutions will be returned.
  78.      *
  79.      * Note: Same solution might be returned multiple times.
  80.      *
  81.      * @param c0   First parameter of the equation
  82.      * @param c1   Second parameter of the equation
  83.      * @param c2   Third parameter of the equation
  84.      * @param c3   Fourth parameter of the equation
  85.      * @param real Array of doubles with minimum length of 3, which the real
  86.      *             part of the result is stored in
  87.      * @param imag Array of doubles with minimum length of 3, which the
  88.      *             imaginary part of the solution is stored in (will be set to
  89.      *             0.0 if a solution is found).
  90.      * @return If the equation has no solution 0 is returned. In case of
  91.      *         infinit sollutions -1 is returned to distiguish this two cases.
  92.      *         Otherwise the number of found sollutions is returned
  93.      */
  94.     public static int solveCubic(double c0, double c1, double c2, double c3, double[] real, double[] imag) {
  95.         if (c3 == 0.0d)
  96.             return solveQuadric(c0, c1, c2, real, imag);
  97.  
  98.         double t = c0 / c3;
  99.         double s = c1 / c3;
  100.         double r = c2 / c3 / 3.0d;
  101.  
  102.         double p = s - 3.0d*r*r;
  103.         double q = 2.0d*r*r*r - r*s + t;
  104.         double d = q*q/4.0d + p*p*p/27.0d;
  105.  
  106.         if (d < 0.0d) { // only real sollution, case d == 0.0d is handled in else
  107.             double R = 2.0d * Math.sqrt(Math.abs(p/3.0d));
  108.             double phi = Math.acos(-4.0d*q/Math.pow(R,3.0d));
  109.             double y1 =  R * Math.cos(phi/3.0d);
  110.             double y2 = -R * Math.cos((phi-Math.PI)/3.0d);
  111.             double y3 = -R * Math.cos((phi+Math.PI)/3.0d);
  112.             real[0] = y1-r;
  113.             real[1] = y2-r;
  114.             real[2] = y3-r;
  115.             imag[0] = 0;
  116.             imag[1] = 0;
  117.             imag[2] = 0;
  118.         } else {
  119.             double h, u, v;
  120.  
  121.             h = -0.5d * q + Math.sqrt(d);
  122.             if (h < 0.0d) {
  123.                 u = -Math.pow(-h, 1.0d/3.0d);
  124.             } else {
  125.                 u =  Math.pow( h, 1.0d/3.0d);
  126.             }
  127.  
  128.             h = -0.5d * q - Math.sqrt(d);
  129.             if (h < 0.0d) {
  130.                 v = -Math.pow(-h, 1.0d/3.0d);
  131.             } else {
  132.                 v =  Math.pow( h, 1.0d/3.0d);
  133.             }
  134.  
  135.             double y1 = u + v;
  136.             double y2 = -y1 / 2.0d;
  137.             double y3 = (v-u) * Math.sqrt(0.75d);
  138.             real[0] = y1-r;
  139.             real[1] = y2-r;
  140.             real[2] = real[1];
  141.             imag[0] = 0;
  142.             imag[1] = y3;
  143.             imag[2] = -imag[1];
  144.         }
  145.         return 3;
  146.     }
  147.    
  148.     /**
  149.      * Solves the cubic equation 0 = c4*x^4 + c3*x^3 + c2*x^2 + c1*x + c0 for
  150.      * x. Result will be stored in the given arrays, which might be complex.
  151.      * The number of found solutions will be returned.
  152.      *
  153.      * Note: Same solution might be returned multiple times.
  154.      *
  155.      * @param c0   First parameter of the equation
  156.      * @param c1   Second parameter of the equation
  157.      * @param c2   Third parameter of the equation
  158.      * @param c3   Fourth parameter of the equation
  159.      * @param c4   Fifth parameter of the equation
  160.      * @param real Array of doubles with minimum length of 4, which the real
  161.      *             part of the result is stored in
  162.      * @param imag Array of doubles with minimum length of 4, which the
  163.      *             imaginary part of the solution is stored in (will be set to
  164.      *             0.0 if a solution is found).
  165.      * @return If the equation has no solution 0 is returned. In case of
  166.      *         infinit sollutions -1 is returned to distiguish this two cases.
  167.      *         Otherwise the number of found sollutions is returned
  168.      */
  169.     public static int solveQuartic(double c0, double c1, double c2, double c3, double c4, double[] real, double[] imag) {
  170.         if (c4 == 0.0d)
  171.             return solveCubic(c0, c1, c2, c3, real, imag);
  172.            
  173.         double d = c0 / c4;
  174.         double c = c1 / c4;
  175.         double b = c2 / c4;
  176.         double a = c3 / c4;
  177.        
  178.         double h1 = 0.25d*a*c - b*b/12.0d - d;
  179.         double h2 = a*b*c/24.0d - 0.125d*c*c - b*b*b/108.0d - 0.125d*a*a*d + b*d/3.0d;
  180.        
  181.         solveCubic(h2, h1, 0.0d, 1.0d, real, imag);
  182.        
  183.         double rl = real[0];
  184.         h1 = 0.25d*a*a - 2.0d*b/3.0d + 2.0d*rl + 1e-15;
  185.         h2 = b*b/36.0d + rl*rl + b*rl/3.0d - d + 1e-15;
  186.  
  187.         if (Math.abs(h1) < 1e-10)
  188.             h1 = 0.0d;
  189.         if (Math.abs(h2) < 1e-10)
  190.             h2 = 0.0d;
  191.        
  192.         double alpha = Math.sqrt(h1);
  193.         double beta = Math.sqrt(h2);
  194.        
  195.         double probe = 2.0d*alpha*beta - (a*b/6.0d + a*rl - c);
  196.         if (Math.abs(probe) > 0.000001) {
  197.             alpha = -alpha;
  198.             probe = 2.0d*alpha*beta - (a*b/6.0d + a*rl - c);
  199.         }
  200.        
  201.         h1 = 0.5d*a + alpha;
  202.         h2 = b/6.0d + rl + beta;
  203.         solveQuadric(h2, h1, 1.0d, real, imag);
  204.  
  205.         real[2] = real[0];
  206.         imag[2] = imag[0];
  207.         real[3] = real[1];
  208.         imag[3] = imag[1];
  209.  
  210.         h1 = 0.5d*a - alpha;
  211.         h2 = b/6.0d + rl - beta;
  212.         solveQuadric(h2, h1, 1.0d, real, imag);
  213.         return 4;
  214.     }
  215.  
  216. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement