| 1798 | GaussElimination(phi, a, NQ); |
| 1799 | |
| 1800 | delete [] a[0]; |
| 1801 | |
| 1802 | return; |
| 1803 | } |
| 1804 | |
| 1805 | void findCanonicalForm( double *const PHI, const double *const phi ) |
| 1806 | { |
| 1807 | const double &a = phi[0]; const double &b = phi[1]; const double &c = phi[2]; |
| 1808 | const double &d = phi[3]; const double &e = phi[4]; const double &f = phi[5]; |
| 1809 | |
| 1810 | // phi(x,y) = a*x*x + b*x*y + c*y*y + d*x + e*y + f |
| 1811 | // = [x,y][ a, b/2; b/2, c ][x;y] + [d,e][x;y] + f |
| 1812 | // = [x,y]P P^T [ a, b/2; b/2, c ]P P^T[x;y] + [d,e]P P^T[x;y] + f |
| 1813 | // = [X,Y] [lambda1,0;0,lambda2] [X;Y] + [D,E][X;Y] + f |
| 1814 | // = lambda1*X*X + lambda2*Y*Y + D*X + E*Y + f |
| 1815 | // = lambda1 * (X + D/(2*lambda1))^2 + lambda2 * (Y + E/(2*lambda2))^2 |
| 1816 | // + ( -D*D/(4*lambda1) - E*E/(4*lambda2) + f ) |
| 1817 | // = PHI(X,Y) |
| 1818 | // where |
| 1819 | // v1 = [v1x;v1y] (resp. v2 = [v2x;v2y]) is an eigenvector of lambda1 (resp. lambda2) |
| 1820 | // P = [v1x, v2x; v1y, v2y], satisfying P^T P = I <=> || v1 || = || v2 || = 1, v1 \perp v2 = 0 |
| 1821 | // [X;Y] = P^T[x;y] <=> [x;y] = P[X;Y] |
| 1822 | // [D;E] = P^T[d;e] <=> [d;e] = P[D;E] |
| 1823 | |
| 1824 | const double det = (a-c)*(a-c)+b*b; |
| 1825 | const double sqdet = sqrt( det ); |
| 1826 | |
| 1827 | // eigenvalues of [ a, b /2; b/2, c] |
| 1828 | double &lambda1 = PHI[0]; double &lambda2 = PHI[1]; |
| 1829 | lambda1 = ( (a+c) + sqdet ) / 2; |
| 1830 | lambda2 = ( (a+c) - sqdet ) / 2; |
| 1831 | |
| 1832 | // corresponding eivenvectors |
| 1833 | double &v1x = PHI[2]; double &v1y= PHI[3]; |
| 1834 | double &v2x = PHI[4]; double &v2y= PHI[5]; |
| 1835 | |
| 1836 | if( a < c ){ |
| 1837 | |
| 1838 | const double n = sqrt( 2*det - 2*(a-c)*sqdet ); |
| 1839 | v1x = b / n; |
| 1840 | v1y = (-(a-c)+sqdet) / n; |
| 1841 | v2x = (a-c-sqdet) / n; |
| 1842 | v2y = b / n; |
| 1843 | |
| 1844 | } else if( a > c ){ |
| 1845 | |
| 1846 | const double n = sqrt( 2*det + 2*(a-c)*sqdet ); |
| 1847 | v1x = (a-c+sqdet) / n; |
| 1848 | v1y = b / n; |
| 1849 | v2x = b / n; |
| 1850 | v2y = (-(a-c)-sqdet) / n; |
| 1851 | |
| 1852 | } else { // a == c |
| 1853 | |
| 1854 | lambda1 = (2*a+b)/2; |
| 1855 | lambda2 = (2*a-b)/2; |
| 1856 | v1x = v1y = v2x = v2y = 1/sqrt(static_cast<double>(2)); v2y *= -1; |
| 1857 | } |
no test coverage detected