static int MatDecompose(cv.Mat m, out cv.Mat lum, out int[] perm) { // Crout's LU decomposition for matrix determinant and inverse // stores combined lower & upper in lum[][] // stores row permuations into perm[] // returns +1 or -1 according to even or odd number of row permutations // lower gets dummy 1.0s on diagonal (0.0s above) // upper gets lum values on diagonal (0.0s below) int toggle = +1; // even (+1) or odd (-1) row permutatuions int n = m.Rows; // make a copy of m[][] into result lum[][] lum = m.Clone(); // make perm[] perm = new int[n]; for (int i = 0; i < n; ++i) { perm[i] = i; } for (int j = 0; j < n - 1; ++j) // process by column. note n-1 { double max = Math.Abs(lum.At <double>(j, j)); int piv = j; for (int i = j + 1; i < n; ++i) // find pivot index { double xij = Math.Abs(lum.At <double>(i, j)); if (xij > max) { max = xij; piv = i; } } // i if (piv != j) { cv.Mat tmp = lum.Row(piv).Clone(); // swap rows j, piv lum.Row(j).CopyTo(lum.Row(piv)); tmp.CopyTo(lum.Row(j)); int t = perm[piv]; // swap perm elements perm[piv] = perm[j]; perm[j] = t; toggle = -toggle; } double xjj = lum.At <double>(j, j); if (xjj != 0.0) { for (int i = j + 1; i < n; ++i) { double xij = lum.At <double>(i, j) / xjj; lum.Set <double>(i, j, xij); for (int k = j + 1; k < n; ++k) { lum.Set <double>(i, k, lum.At <double>(i, k) - xij * lum.At <double>(j, k)); } } } } return(toggle); // for determinant }