| 930 | #define Dd( y, x ) ((double*)(dstdata + y*dststep))[x] |
| 931 | |
| 932 | double cv::invert( InputArray _src, OutputArray _dst, int method ) |
| 933 | { |
| 934 | bool result = false; |
| 935 | Mat src = _src.getMat(); |
| 936 | int type = src.type(); |
| 937 | |
| 938 | CV_Assert(type == CV_32F || type == CV_64F); |
| 939 | |
| 940 | size_t esz = CV_ELEM_SIZE(type); |
| 941 | int m = src.rows, n = src.cols; |
| 942 | |
| 943 | if( method == DECOMP_SVD ) |
| 944 | { |
| 945 | int nm = std::min(m, n); |
| 946 | |
| 947 | AutoBuffer<uchar> _buf((m*nm + nm + nm*n)*esz + sizeof(double)); |
| 948 | uchar* buf = alignPtr((uchar*)_buf, (int)esz); |
| 949 | Mat u(m, nm, type, buf); |
| 950 | Mat w(nm, 1, type, u.data + m*nm*esz); |
| 951 | Mat vt(nm, n, type, w.data + nm*esz); |
| 952 | |
| 953 | SVD::compute(src, w, u, vt); |
| 954 | SVD::backSubst(w, u, vt, Mat(), _dst); |
| 955 | return type == CV_32F ? |
| 956 | (((float*)w.data)[0] >= FLT_EPSILON ? |
| 957 | ((float*)w.data)[n-1]/((float*)w.data)[0] : 0) : |
| 958 | (((double*)w.data)[0] >= DBL_EPSILON ? |
| 959 | ((double*)w.data)[n-1]/((double*)w.data)[0] : 0); |
| 960 | } |
| 961 | |
| 962 | CV_Assert( m == n ); |
| 963 | |
| 964 | if( method == DECOMP_EIG ) |
| 965 | { |
| 966 | AutoBuffer<uchar> _buf((n*n*2 + n)*esz + sizeof(double)); |
| 967 | uchar* buf = alignPtr((uchar*)_buf, (int)esz); |
| 968 | Mat u(n, n, type, buf); |
| 969 | Mat w(n, 1, type, u.data + n*n*esz); |
| 970 | Mat vt(n, n, type, w.data + n*esz); |
| 971 | |
| 972 | eigen(src, w, vt); |
| 973 | transpose(vt, u); |
| 974 | SVD::backSubst(w, u, vt, Mat(), _dst); |
| 975 | return type == CV_32F ? |
| 976 | (((float*)w.data)[0] >= FLT_EPSILON ? |
| 977 | ((float*)w.data)[n-1]/((float*)w.data)[0] : 0) : |
| 978 | (((double*)w.data)[0] >= DBL_EPSILON ? |
| 979 | ((double*)w.data)[n-1]/((double*)w.data)[0] : 0); |
| 980 | } |
| 981 | |
| 982 | CV_Assert( method == DECOMP_LU || method == DECOMP_CHOLESKY ); |
| 983 | |
| 984 | _dst.create( n, n, type ); |
| 985 | Mat dst = _dst.getMat(); |
| 986 | |
| 987 | if( n <= 3 ) |
| 988 | { |
| 989 | uchar* srcdata = src.data; |