Files Classes Functions Hierarchy
00001 #ifndef MATHLIB_H 00002 #define MATHLIB_H 00003 00004 // Rewrite this file. 00005 // 00006 00007 #include <cassert> 00008 #include <iostream> 00009 #include <string> 00010 #include <vector> 00011 using namespace std; 00012 00013 #include <point.h> 00014 #include <print.h> 00015 #include <typedefs.h> 00016 #include <zero.h> 00017 00018 #define PI 3.1415926535897932384626433 00019 00020 00022 template< typename T > 00023 void unitbound(T & val) 00024 { 00025 if (val<(T)0) 00026 { 00027 val = (T)0; 00028 return; 00029 } 00030 00031 if (val>(T)1.0) 00032 val = (T)1.0; 00033 } 00034 00035 00036 00039 void integersetdiff 00040 ( 00041 vector<uint> & vecnot, 00042 vector<uint> & vec, 00043 uintc N 00044 ); 00045 00047 void mathcombination 00048 ( 00049 double & result, 00050 uintc n, 00051 uintc k 00052 ); 00053 00054 00055 00056 // 00057 // arcos is computed by subtracting arcsin from Pi/2. 00058 // 00059 00060 /* 00061 template<class T> 00062 class arcsin 00063 { 00064 public: 00065 00066 // y = arcsin(x) by k iterations of arcsin power series. 00067 T& operator()(T& y, T const & x, uintc k); 00068 // Provide an error bound for iteration aswell <TODO> 00069 00070 }; 00071 */ 00072 00076 class crossproduct 00077 { 00078 public: 00079 00082 template<class T> 00083 static void eval(T& w, T const & a, T const & b) 00084 { 00085 w[0] = a[1]*b[2]-b[1]*a[2]; 00086 w[1] = a[2]*b[0]-a[0]*b[2]; 00087 w[2] = a[0]*b[1]-a[1]*b[0]; 00088 } 00089 00092 template<class T> 00093 static void evalxyz(T& w, T const & a, T const & b) 00094 { 00095 w.x = a.y*b.z-b.y*a.z; 00096 w.y = a.z*b.x-a.x*b.z; 00097 w.z = a.x*b.y-a.y*b.x; 00098 } 00099 00100 }; 00101 00105 class intervalintersection 00106 { 00107 public: 00108 00110 template<class T> 00111 static boolc unordered 00112 ( 00113 T const a0, 00114 T const a1, 00115 T const b0, 00116 T const b1 00117 ); 00118 00120 template<class T> 00121 static boolc unordered 00122 ( 00123 T & c0, 00124 T & c1, 00125 T const a0, 00126 T const a1, 00127 T const b0, 00128 T const b1 00129 ); 00130 00132 template<class I> 00133 static boolc unordered( I const * i0, I const * i1 ) 00134 { return unordered(i0[0],i0[1],i1[0],i1[1]); } 00135 00140 template<class I> 00141 static boolc unorderedD2( I const * box0, I const * box1 ) 00142 { 00143 if (unordered(box0,box1)==false) 00144 return false; 00145 00146 return unordered(box0+2,box1+2); 00147 } 00148 00149 }; 00150 00160 template<typename T> 00161 class solverInconsistent 00162 { 00163 public: 00164 00166 static boolc d1linearequ 00167 ( 00168 T & x, 00169 T & y, 00170 T const a0, 00171 T const a1, 00172 T const c 00173 ); 00174 00177 static boolc d2linearequ 00178 ( 00179 T & x, 00180 T & y, 00181 T & z, 00182 T const a00, 00183 T const a01, 00184 T const a02, 00185 T const c0, 00186 T const a10, 00187 T const a11, 00188 T const a12, 00189 T const c1 00190 ); 00191 00192 }; 00193 00194 00195 // <TODO> Is this necessary? Doc??? 00196 template<class T> 00197 class surfaceplane 00198 { 00199 public: 00200 00201 void operator()(T & u, T & v, T & temp, T const & w) const; 00202 00203 }; 00204 00205 00206 // <TODO> Find out what this is and fix or delete. 00207 template< typename T > 00208 class convexity 00209 { 00210 public: 00211 00212 // x-axis 00213 T a; 00214 T b; 00215 // y-axis 00216 T af; 00217 T bf; 00218 00219 // Sets 2 points which define the interval. 00220 convexity(T a_, T b_, T af_, T bf_) 00221 : a(a_), b(b_), af(af_), bf(bf_) {} 00222 convexity(); // costruct in bad state. 00223 00224 // Given containers of values, verify the equality against the end points. 00225 void operator () 00226 ( 00227 bool& result, 00228 vector<T> const & x, 00229 vector<T> const & xf 00230 ); 00231 00232 // Samples n points between a and b, testing convexity equality. 00233 template< typename F > // F is the function. 00234 void operator () 00235 ( 00236 bool& result, // Is the data set convex? 00237 F f, // function 00238 uint n, // number of sample points 00239 T const a_, // x value bound lower 00240 T const b_ // x value bound upper 00241 ); 00242 00243 }; 00244 00245 00246 // <TODO> Find out if this is necessary. 00247 /* 00248 \brief Orthogonal projection 00249 00250 Client supplies orthogonal vectors v[i] and inner product. 00251 Calling operator solves a[i] for c. 00252 */ 00253 template 00254 < 00255 typename T, // Data type 00256 typename V, // vector 00257 typename IP, // Inner product functional object: ()(T&,V&,V&) 00258 uint Dim // Dimension 00259 > 00260 class orthoproj 00261 { 00262 public: 00263 00264 T a[Dim]; 00265 V v[Dim]; // Orthogonal vectors 00266 IP p; 00267 00268 void operator()(V const & c); 00269 00270 }; 00271 00272 00274 void tetrahedronvolume 00275 ( 00276 double & vol, 00277 point3<double> const & p0, 00278 point3<double> const & p1, 00279 point3<double> const & p2, 00280 point3<double> const & p3 00281 ); 00282 00283 00286 void polygonconvexarea 00287 ( 00288 double & area, 00289 vector< point2<double> > const & v 00290 ); 00291 00292 00293 //<TODO> Do something with the trianglearea functions. 00294 // Either add to triangle class or creat an area class. 00295 00296 void trianglearea 00297 ( 00298 double & f, 00299 doublec x0, 00300 doublec y0, 00301 doublec x1, 00302 doublec y1, 00303 doublec x2, 00304 doublec y2 00305 ); 00306 00308 void trianglearea 00309 ( 00310 double & f, 00311 point3<double> const & p0, 00312 point3<double> const & p1, 00313 point3<double> const & p2 00314 ); 00315 00316 00320 class determinant 00321 { 00322 public: 00323 00325 template< typename T > 00326 static T const calcD2 00327 ( 00328 T const a00, 00329 T const a01, 00330 T const a10, 00331 T const a11 00332 ) 00333 { return a00*a11-a01*a10; } 00334 00336 template< typename T > 00337 static T const calcD3 00338 ( 00339 T const a00, 00340 T const a01, 00341 T const a02, 00342 T const a10, 00343 T const a11, 00344 T const a12, 00345 T const a20, 00346 T const a21, 00347 T const a22 00348 ) 00349 { return 00350 a00*(a11*a22-a12*a21) - 00351 a01*(a10*a22-a12*a20) + 00352 a02*(a10*a21-a11*a20); } 00353 }; 00354 00355 00356 00357 00358 template< typename T > 00359 class solver 00360 { 00361 public: 00362 00365 template < typename W > 00366 static boolc d2linearequ 00367 ( 00368 W & x, 00369 W const & a0, 00370 W const & a1, 00371 W const & c 00372 ) 00373 { 00374 T det = a0.x*a1.y - a1.x*a0.y; 00375 if (det*det<=zero<T>::val) 00376 return false; 00377 00378 T detInv = (T)1.0/det; 00379 00380 x.x = (c.x*a1.y - c.y*a1.x)*detInv; 00381 x.y = (c.y*a0.x - c.x*a0.y)*detInv; 00382 00383 return true; 00384 } 00385 00387 static boolc d2linearequ 00388 ( 00389 T & x, 00390 T & y, 00391 T const a00, 00392 T const a01, 00393 T const a10, 00394 T const a11, 00395 T const c0, 00396 T const c1 00397 ); 00398 00399 }; 00400 00401 00402 00403 // <TODO> Move the d2/d3 matsolve into solver. 00404 00405 00406 // Solve linear equations for x0,x1. 00407 // 00408 // [ a00 a01 ] [ x0 ] = [ c0 ] 00409 // a10 a11 x1 c1 00410 // Returns false if determinant is equal to zero. 00411 // 00412 // All the vectors are column vectors. 00413 template < typename T > 00414 boolc d2matsolve 00415 ( 00416 T & x, 00417 T const & a0, 00418 T const & a1, 00419 T const & c 00420 ); 00421 00424 template < typename T > 00425 boolc d2matsolve3D 00426 ( 00427 T & x, 00428 T const & a0, 00429 T const & a1, 00430 T const & c 00431 ); 00432 00433 00434 // Solve linear equations for x0,x1. 00435 // 00436 // [ a00 a01 ] [ x0 ] = [ c0 ] 00437 // a10 a11 x1 c1 00438 // Returns false if determinant is equal to zero. 00439 boolc d3matsolve 00440 ( 00441 double & x0, 00442 double & x1, 00443 double & x2, 00444 doublec a00, 00445 doublec a01, 00446 doublec a02, 00447 doublec a10, 00448 doublec a11, 00449 doublec a12, 00450 doublec a20, 00451 doublec a21, 00452 doublec a22, 00453 doublec c0, 00454 doublec c1, 00455 doublec c2 00456 ); 00457 00458 boolc d3matsolve 00459 ( 00460 point3<double> & x, 00461 point3<double> const & a0, // Column vector. 00462 point3<double> const & a1, // Column vector. 00463 point3<double> const & a2, // Column vector. 00464 point3<double> const & c 00465 ); 00466 00467 00468 00469 //<TODO> Integrate lineintersection into line class. 00470 00471 // Solve the intersection of two lines (a,b) and (c,d) 00472 // a + t0(b-a) = c + t1(d-c) 00473 template < typename T, typename D > 00474 boolc lineintersection 00475 ( 00476 D & t0, 00477 D & t1, 00478 T const & a, 00479 T const & b, 00480 T const & c, 00481 T const & d 00482 ); 00483 00485 boolc solvequadratic 00486 ( 00487 double & t0, 00488 double & t1, 00489 doublec a, 00490 doublec b, 00491 doublec c 00492 ); 00493 00494 00495 00496 00497 /* 00498 \brief Rotate a 2D point about the origin. 00499 00500 The point is rotated in an anticlockwise direction. 00501 */ 00502 class transrotate2D 00503 { 00504 point2<double> r1; 00505 point2<double> r2; 00506 public: 00507 00509 transrotate2D(doublec theta); 00510 00512 void eval(point2<double> & p); 00513 00515 void eval(point2<double> & p, point2<double> const & shift); 00516 00517 }; 00518 00519 00520 void matrixmult 00521 ( 00522 point3<double> & y, 00523 doublec * m, 00524 point3<double> const & x 00525 ); 00526 00527 void matrixmult 00528 ( 00529 point3<double> & y, 00530 point3<double> const & r0, 00531 point3<double> const & r1, 00532 point3<double> const & r2, 00533 point3<double> const & x 00534 ); 00535 00536 00537 //<TODO> * Integrate teh lineSegments into the line class. 00538 // * Remove zero and use zero<T>::test instead. 00539 00542 boolc lineSegmentIntersection 00543 ( 00544 point2<double> const & p1, 00545 point2<double> const & p2, 00546 point2<double> const & q1, 00547 point2<double> const & q2, 00548 doublec zero 00549 ); 00550 00551 //<TODO> Remove zero. 00554 boolc lineIntersection 00555 ( 00556 double & tp, 00557 double & tq, 00558 point2<double> const & p1, 00559 point2<double> const & p2, 00560 point2<double> const & q1, 00561 point2<double> const & q2, 00562 doublec zero 00563 ); 00564 00565 00569 boolc lineSegmentIntersection 00570 ( 00571 double & tp, 00572 double & tq, 00573 point2<double> const & p1, 00574 point2<double> const & p2, 00575 point2<double> const & q1, 00576 point2<double> const & q2, 00577 doublec zero 00578 ); 00579 00583 class circleLine 00584 { 00585 public: 00586 00590 template< typename PT, typename PD > 00591 static boolc intersection2D 00592 ( 00593 PT & p0, 00594 PT & p1, 00595 PD const radius, 00596 PT const & q0, 00597 PT const & q1 00598 ); 00599 00600 }; 00601 00602 00603 00604 //---------------------------------------------------------- 00605 // Implementation 00606 00607 00608 template< typename PT, typename PD > 00609 boolc circleLine::intersection2D 00610 ( 00611 PT & p0, 00612 PT & p1, 00613 PD const radius, 00614 PT const & q0, 00615 PT const & q1 00616 ) 00617 { 00618 assert( zero<PD>::test( (q0-q1).dot()) == false ); 00619 00620 // Hard coded type. No templated solvequadratic. 00621 00622 PT B(q1-q0); 00623 00624 doublec a = B.dot(); 00625 doublec b = q0.dot(B)*2.0; 00626 doublec c = q0.dot()-radius*radius; 00627 double t0; 00628 double t1; 00629 bool res; 00630 res = solvequadratic(t0,t1,a,b,c); 00631 if (res==false) 00632 return false; 00633 00634 p0 = q0 + B*t0; 00635 p1 = q0 + B*t1; 00636 00637 return true; 00638 } 00639 00640 // All column implementation. 00641 template < typename T > 00642 boolc d2matsolve 00643 ( 00644 T & x, 00645 T const & a0, 00646 T const & a1, 00647 T const & c 00648 ) 00649 { 00650 doublec det = a0.x*a1.y - a1.x*a0.y; 00651 if (det==0.0) 00652 return false; 00653 00654 doublec detInv = 1.0/det; 00655 00656 x.x = (c.x*a1.y - c.y*a1.x)*detInv; 00657 x.y = (c.y*a0.x - c.x*a0.y)*detInv; 00658 00659 return true; 00660 } 00661 00662 template < typename T > 00663 boolc d2matsolve3D 00664 ( 00665 T & x, 00666 T const & a0, 00667 T const & a1, 00668 T const & c 00669 ) 00670 { 00671 double det = a0.x*a1.y - a1.x*a0.y; 00672 // <TODO> make this test dependent on number. 00673 if (det!=0.0) 00674 { 00675 doublec detInv = 1.0/det; 00676 00677 x.x = (c.x*a1.y - c.y*a1.x)*detInv; 00678 x.y = (c.y*a0.x - c.x*a0.y)*detInv; 00679 00680 return true; 00681 } 00682 00683 det = a0.x*a1.z - a1.x*a0.z; 00684 if (det!=0.0) 00685 { 00686 doublec detInv = 1.0/det; 00687 00688 x.x = (c.x*a1.z - c.z*a1.x)*detInv; 00689 x.y = (c.z*a0.x - c.x*a0.z)*detInv; 00690 00691 return true; 00692 } 00693 00694 det = a0.y*a1.z - a1.y*a0.z; 00695 if (det!=0.0) 00696 { 00697 doublec detInv = 1.0/det; 00698 00699 x.x = (c.y*a1.z - c.z*a1.y)*detInv; 00700 x.y = (c.z*a0.y - c.x*a0.z)*detInv; 00701 00702 return true; 00703 } 00704 00705 return false; 00706 } 00707 00708 00709 00710 template < typename T, typename D > 00711 boolc lineintersection 00712 ( 00713 D & t0, 00714 D & t1, 00715 T const & a, 00716 T const & b, 00717 T const & c, 00718 T const & d 00719 ) 00720 { 00721 T A(b-a); 00722 T B(c-d); 00723 T C(c-a); 00724 00725 T x; 00726 bool res = d2matsolve(x,A,B,C); 00727 t0 = x.x; 00728 t1 = x.y; 00729 00730 return res; 00731 } 00732 00733 00734 00735 00736 00737 template 00738 < 00739 typename T, 00740 typename V, 00741 typename IP, 00742 uint Dim 00743 > 00744 void orthoproj<T,V,IP,Dim>::operator()(V const & c) 00745 { 00746 T t; 00747 for (uint i=0; i<Dim; ++i) 00748 { 00749 p(a[i],c,v[i]); 00750 p(t,v[i],v[i]); 00751 a[i] /= t; 00752 } 00753 } 00754 00755 00756 template<class T> template< typename F > 00757 void convexity<T>::operator () 00758 ( 00759 bool& result, 00760 F f, 00761 uint n, 00762 T const a_, 00763 T const b_ 00764 ) 00765 { 00766 if (n==0) 00767 { 00768 result=false; 00769 return; 00770 } 00771 00772 a = a_; 00773 b = b_; 00774 00775 f(af,a); 00776 f(bf,b); 00777 00778 // cout << "af=" << af << ", bf=" << bf << endl; 00779 00780 T one(1.0); //Unbelievabley (j+1)/(n+1)*(b-a) was somewhere converting to int. 00781 00782 /* 00783 // Building containers and forwarding. 00784 vector<T> x(n); 00785 vector<T> xf(n); 00786 00787 00788 for (uint j=0; j<n; ++j) 00789 { 00790 x[j] = a+(j+one)/(n+one)*(b-a); 00791 f(xf[j],x[j]); 00792 //cout << "x[" << j << "]=" << x[j] << ", xf[" << j << "]=" << xf[j] << endl; 00793 } 00794 operator()(result,x,xf); 00795 */ 00796 00797 T x; 00798 T xf; 00799 T lambda; 00800 00801 for (uint j=0; j<n; ++j) 00802 { 00803 x = a+(j+one)/(n+one)*(b-a); 00804 f(xf,x); 00805 // cout << "x[" << j << "]=" << x << ", xf[" << j << "]=" << xf << endl; 00806 lambda = (x-b)/(a-b); 00807 if ( lambda*af+bf*(one-lambda) < xf ) 00808 { 00809 result = false; 00810 return; 00811 } 00812 } 00813 00814 } 00815 00816 00817 // Call appropriate operator to construct the object. 00818 template<class T> 00819 convexity<T>::convexity() 00820 {} 00821 00822 template<class T> 00823 void convexity<T>::operator() 00824 ( 00825 bool& result, 00826 vector<T> const & x, 00827 vector<T> const & xf 00828 ) 00829 { 00830 result = true; 00831 00832 T one(1.0); 00833 00834 T lambda; 00835 00836 for (uint i=0; i<x.size(); ++i) 00837 { 00838 lambda = (x[i]-b)/(a-b); 00839 if ( lambda*af+bf*(one-lambda) < xf[i] ) 00840 { 00841 result = false; 00842 return; 00843 } 00844 } 00845 } 00846 00847 00848 00849 template<class T> 00850 void surfaceplane<T>::operator()(T & u, T & v, T & temp, T const & w) const 00851 { 00852 // Right shift. 00853 temp[1] = w[0]; 00854 temp[2] = w[1]; 00855 temp[0] = w[2]; 00856 00857 crossproduct::eval(u,w,temp); 00858 crossproduct::eval(v,u,w); 00859 00860 //crossprod<T>()(u,w,temp); 00861 //crossprod<T>()(v,u,w); 00862 } 00863 00864 /* 00865 template<class T> 00866 T& arcsin<T>::operator()(T& y, T const & x, uintc k) 00867 { 00868 T x2 = x * x; 00869 T a; 00870 a = 1.0; // Numerator pattern 1 1.3 1.3.5 1.3.5.7 ... 00871 T b; 00872 b = 2.0; // Denominator pattern 2 2.4 2.4.6 2.4.6.8 ... 00873 T xi = x; // Current power of x 00874 uint c = 2; 00875 00876 // An improvement would be to calculate from the smallest 00877 // magnitude to the largest magnitude, minimising errors from 00878 // largely different magnitudes. 00879 00880 y = x; // First term approximation. 00881 for (uint i=1; i<k; ++i) 00882 { 00883 xi *= x2; 00884 y += xi*a/(b*(c+1)); 00885 c += 2; 00886 a *= (c-1); 00887 b *= c; 00888 } 00889 00890 return y; 00891 } 00892 */ 00893 00894 00895 template<class T> 00896 boolc intervalintersection::unordered 00897 ( 00898 T const a0, 00899 T const a1, 00900 T const b0, 00901 T const b1 00902 ) 00903 { 00904 // Order the points. 00905 T a[2]; 00906 if (a0<a1) 00907 { 00908 a[0] = a0; 00909 a[1] = a1; 00910 } 00911 else 00912 { 00913 a[1] = a0; 00914 a[0] = a1; 00915 } 00916 T b[2]; 00917 if (b0<b1) 00918 { 00919 b[0] = b0; 00920 b[1] = b1; 00921 } 00922 else 00923 { 00924 b[1] = b0; 00925 b[0] = b1; 00926 } 00927 00928 if (a[1]<b[0]) 00929 return false; 00930 00931 if (b[1]<a[0]) 00932 return false; 00933 00934 return true; 00935 } 00936 00937 00938 00939 00940 template<class T> 00941 boolc intervalintersection::unordered 00942 ( 00943 T & c0, 00944 T & c1, 00945 T const a0, 00946 T const a1, 00947 T const b0, 00948 T const b1 00949 ) 00950 { 00951 // Order the points. 00952 T a[2]; 00953 if (a0<a1) 00954 { 00955 a[0] = a0; 00956 a[1] = a1; 00957 } 00958 else 00959 { 00960 a[1] = a0; 00961 a[0] = a1; 00962 } 00963 T b[2]; 00964 if (b0<b1) 00965 { 00966 b[0] = b0; 00967 b[1] = b1; 00968 } 00969 else 00970 { 00971 b[1] = b0; 00972 b[0] = b1; 00973 } 00974 00975 //cout << SHOW(a[0]) << " " << SHOW(a[1]) << endl; 00976 //cout << SHOW(b[0]) << " " << SHOW(b[1]) << endl; 00977 00978 if (a[1]<b[0]) 00979 return false; 00980 00981 if (b[1]<a[0]) 00982 return false; 00983 00984 // Find the intersection interval. 00985 if (a[0]<b[0]) 00986 { 00987 //cout << "a[0]<b[0]" << endl; 00988 if (b[1]<a[1]) 00989 { 00990 //cout << "b[1]<a[1]" << endl; 00991 c0 = b[0]; 00992 c1 = b[1]; 00993 } 00994 else 00995 { 00996 c0 = b[0]; 00997 c1 = a[1]; 00998 } 00999 } 01000 else 01001 { 01002 //cout << "b[0]<a[0]" << endl; 01003 if (a[1]<b[1]) 01004 { 01005 c0 = a[0]; 01006 c1 = a[1]; 01007 } 01008 else 01009 { 01010 c0 = a[0]; 01011 c1 = b[1]; 01012 } 01013 } 01014 01015 return true; 01016 } 01017 01018 01019 template<typename T> 01020 boolc solverInconsistent<T>::d1linearequ 01021 ( 01022 T & x, 01023 T & y, 01024 T const a0, 01025 T const a1, 01026 T const c 01027 ) 01028 { 01029 if (zero<T>::test(a0)) 01030 { 01031 x = 0; 01032 if (zero<T>::test(a1)) 01033 { 01034 y = 0; 01035 return (c==0); 01036 } 01037 y = c/a1; 01038 return true; 01039 } 01040 01041 if (zero<T>::test(a1)) 01042 { 01043 y = 0; 01044 x = c/a0; 01045 return true; 01046 } 01047 01048 x=1.0; 01049 y = (c-a0)/a1; 01050 return true; 01051 } 01052 01053 01054 template<typename T> 01055 boolc solverInconsistent<T>::d2linearequ 01056 ( 01057 T & x, 01058 T & y, 01059 T & z, 01060 T const a00, 01061 T const a01, 01062 T const a02, 01063 T const c0, 01064 T const a10, 01065 T const a11, 01066 T const a12, 01067 T const c1 01068 ) 01069 { 01070 if (zero<T>::test(a00)) 01071 { 01072 if (zero<T>::test(a10)) 01073 { 01074 x=0; 01075 return solver<T>::d2linearequ(y,z,a01,a02,a10,a11,c0,c1); 01076 } 01077 01078 return d2linearequ(x,y,z,a10,a11,a12,c1,a00,a01,a02,c0); 01079 } 01080 01081 T e[3]; 01082 e[0] = a11-a10*a01/a00; 01083 e[1] = a12-a10*a02/a00; 01084 e[2] = c1-a10*c0/a00; 01085 01086 bool res = d1linearequ(y,z,e[0],e[1],e[2]); 01087 if (res==false) 01088 return false; 01089 01090 x = (c0-a01*y-a02*z)/a00; 01091 01092 return true; 01093 } 01094 01095 01096 01097 01098 template< typename T > 01099 boolc solver<T>::d2linearequ 01100 ( 01101 T & x, 01102 T & y, 01103 T const a00, 01104 T const a01, 01105 T const a10, 01106 T const a11, 01107 T const c0, 01108 T const c1 01109 ) 01110 { 01111 T det = a00*a11-a01*a10; 01112 if (det*det<=zero<T>::val) 01113 return false; 01114 01115 T detInv = (T)1.0/det; 01116 01117 x = (c0*a11 - c1*a01)*detInv; 01118 y = (c1*a00 - c0*a10)*detInv; 01119 01120 return true; 01121 } 01122 01123 01124 01125 #endif 01126 01127
1.5.8