include/crbn/solver/cubic.hpp

00001 #ifndef __cubic_hpp__
00002 #define __cubic_hpp__
00003 
00004 #include <crbn/basic/scalar.hpp>
00005 
00006 // Solve cubic equation (only real roots are considered)
00007 inline int cubic_r(const float& a, const float& b, const float& c, const float& d, float& x0, float& x1, float& x2) {
00008   float a0, a1, a2, a3, q, r, d, s, t;
00009 
00010   a3 = a; a2 = b; a1 = c; a0 = d; 
00011 
00012   a2 /= a3;
00013   a1 /= a3;
00014   a0 /= a3;
00015 
00016   q = ((3.0 * a1) - (a2 * a2)) / 9.0;
00017   r = ((9.0 * a1 * a2) - (27.0 * a0) - (2.0 * a2 * a2 * a2)) / 54.0;
00018   
00019   d = (q * q * q) + (r * r); 
00020   
00021   if(d > 0.0f) {
00022       d = sqrt(d);
00023 
00024       s = cbrt(r + d);
00025       t = cbrt(r - d);
00026       
00027       x0 = x1 = x2 = -(a2 / 3.0) + s + t;   
00028       
00029       return 1;
00030   }
00031 
00032   if (d < 0.0f) {
00033     float theta = acos(r / sqrt(-(q * q * q)));
00034     s = 2.0 * sqrt(-q);
00035     x0 = (s * cos(theta / 3.0)) - (a2 / 3.0);
00036     x1 = (s * cos((theta + (2.0 * M_PI)) / 3.0)) - (a2 / 3.0);
00037     x2 = (s * cos((theta - (4.0 * M_PI)) / 3.0)) - (a2 / 3.0);
00038     
00039     if(x0 > x1) {
00040       t = x0;
00041       x0 = x1;
00042       x1 = t;
00043     }
00044     if(x0 > x2) {
00045       t = x0;
00046       x0 = x2;
00047       x2 = t;
00048     }
00049     if(x1 > x2) {
00050       t = x1;
00051       x1 = x2;
00052       x2 = t;
00053     }
00054     
00055     return 3;
00056   }
00057 
00058   s = cbrt(r);
00059   
00060   x0 = -(a2 / 3.0) + (2.0 * s);   
00061   x1 = x2 = -(a2 / 3.0) - s;
00062   
00063   if(x0 > x1) {
00064     x2 = x0;
00065     x0 = x1;
00066     x1 = x2;
00067   }
00068   
00069   return 2;
00070 }
00071 
00072 #endif

Generated on Tue Nov 14 15:40:08 2006 for libcrbn by  doxygen 1.5.0