Esempio n. 1
0
        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
        }