| 853 | m(0,2)*((double)m(1,0)*m(2,1) - (double)m(1,1)*m(2,0))) |
| 854 | |
| 855 | double cv::determinant( InputArray _mat ) |
| 856 | { |
| 857 | Mat mat = _mat.getMat(); |
| 858 | double result = 0; |
| 859 | int type = mat.type(), rows = mat.rows; |
| 860 | size_t step = mat.step; |
| 861 | const uchar* m = mat.data; |
| 862 | |
| 863 | CV_Assert( mat.rows == mat.cols && (type == CV_32F || type == CV_64F)); |
| 864 | |
| 865 | #define Mf(y, x) ((float*)(m + y*step))[x] |
| 866 | #define Md(y, x) ((double*)(m + y*step))[x] |
| 867 | |
| 868 | if( type == CV_32F ) |
| 869 | { |
| 870 | if( rows == 2 ) |
| 871 | result = det2(Mf); |
| 872 | else if( rows == 3 ) |
| 873 | result = det3(Mf); |
| 874 | else if( rows == 1 ) |
| 875 | result = Mf(0,0); |
| 876 | else |
| 877 | { |
| 878 | size_t bufSize = rows*rows*sizeof(float); |
| 879 | AutoBuffer<uchar> buffer(bufSize); |
| 880 | Mat a(rows, rows, CV_32F, (uchar*)buffer); |
| 881 | mat.copyTo(a); |
| 882 | |
| 883 | result = LU((float*)a.data, a.step, rows, 0, 0, 0); |
| 884 | if( result ) |
| 885 | { |
| 886 | for( int i = 0; i < rows; i++ ) |
| 887 | result *= ((const float*)(a.data + a.step*i))[i]; |
| 888 | result = 1./result; |
| 889 | } |
| 890 | } |
| 891 | } |
| 892 | else |
| 893 | { |
| 894 | if( rows == 2 ) |
| 895 | result = det2(Md); |
| 896 | else if( rows == 3 ) |
| 897 | result = det3(Md); |
| 898 | else if( rows == 1 ) |
| 899 | result = Md(0,0); |
| 900 | else |
| 901 | { |
| 902 | size_t bufSize = rows*rows*sizeof(double); |
| 903 | AutoBuffer<uchar> buffer(bufSize); |
| 904 | Mat a(rows, rows, CV_64F, (uchar*)buffer); |
| 905 | mat.copyTo(a); |
| 906 | |
| 907 | result = LU((double*)a.data, a.step, rows, 0, 0, 0); |
| 908 | if( result ) |
| 909 | { |
| 910 | for( int i = 0; i < rows; i++ ) |
| 911 | result *= ((const double*)(a.data + a.step*i))[i]; |
| 912 | result = 1./result; |