Example #1
0
 public void TestInit()
 {
     var matrix = new Matrix<int>(5, 5);
     int[] row = { 2, 2, 2, 2, 2 };
     matrix.Init(2);
     Assert.AreEqual(row, matrix.GetRow(2));
 }
        public void TestInc()
        {
            var matrix = new Matrix<double>(5, 5);
            double[] row = { 1, 2, 3, 4, 5 };
            for (int i = 0; i < 5; i++)
                matrix.SetRow(i, row);
            matrix.Inc(3, 4, 2.5);
            Assert.AreEqual(7.5, matrix[3, 4]);

            var matrix1 = new Matrix<double>(5, 5);
            for (int i = 0; i < 5; i++)
                matrix1.SetRow(i, row);
            var matrix2 = new Matrix<double>(5, 5);
            for (int i = 0; i < 5; i++)
                matrix2.SetRow(i, row);
            double[] testrow = { 2, 4, 6, 8, 10 };
            matrix1.Inc(matrix2);
            Assert.AreEqual(testrow, matrix1.GetRow(2));

            var matrix3 = new Matrix<double>(5, 5);
            for (int i = 0; i < 5; i++)
                matrix3.SetRow(i, row);
            matrix3.Inc(1.0);
            for (int j = 0; j < 5; j++)
                Assert.AreEqual(row[j] + 1, matrix3[1, j]);

            var matrix4 = new Matrix<int>(5, 5);
            int[] int_row = { 1, 2, 3, 4, 5 };
            for (int i = 0; i < 5; i++)
                matrix4.SetRow(i, int_row);
            Assert.AreEqual(matrix4[1, 2], 3);
            matrix4.Inc(1, 2);
            Assert.AreEqual(matrix4[1, 2], 4);
        }
Example #3
0
 public void TestGetSetRow()
 {
     var matrix = new Matrix<int>(5, 5);
     int[] row = { 1, 2, 3, 4, 5 };
     matrix.SetRow(3, row);
     Assert.AreEqual(row, matrix.GetRow(3));
     Assert.AreEqual(0, matrix[0, 0]);
     Assert.AreEqual(1, matrix[3, 0]);
 }
Example #4
0
		[Test()] public void TestSetRowToOneValue()
		{
			var matrix = new Matrix<int>(5, 5);
			int[] row = { 1, 2, 3, 4, 5 };
			for (int i = 0; i < 5; i++)
				matrix.SetRow(i, row);
			matrix.SetRowToOneValue(3, 10);
			int[] testrow = { 10, 10, 10, 10, 10 };
			Assert.AreEqual(testrow, matrix.GetRow(3));
		}
		[Test()] public void TestMultiply()
		{
			var matrix = new Matrix<float>(5, 5);
			float[] row = { 1, 2, 3, 4, 5 };
			for (int i = 0; i < 5; i++)
				matrix.SetRow(i, row);
			matrix.Multiply(2.5f);
			float[] testrow = { 2.5f, 5f, 7.5f, 10f, 12.5f };
			Assert.AreEqual(testrow, matrix.GetRow(3));
		}
Example #6
0
        public void TestInc2()
        {
            var matrix1 = new Matrix<double>(5, 5);
            double[] row = { 1, 2, 3, 4, 5 };
            for (int i = 0; i < 5; i++)
                matrix1.SetRow(i, row);

            var matrix2 = new Matrix<double>(5, 5);
            for (int i = 0; i < 5; i++)
                matrix2.SetRow(i, row);
            double[] testrow = {2, 4, 6, 8, 10};
            MatrixUtils.Inc(matrix1, matrix2);
            Assert.AreEqual(testrow, matrix1.GetRow(2));
        }
Example #7
0
        private bool canBeThere(Matrix m, int row, int column, int digit)
        {
            int[] temp = m.GetRow(row);
            foreach (int i in temp)
                if (i == digit)
                    return false;
            temp = m.GetColumn(column);
            foreach (int i in temp)
                if (i == digit)
                    return false;
            temp = m.GetRegion(row, column);
            foreach (int i in temp)
                if (i == digit)
                    return false;

            return true;
        }
Example #8
0
        /*
         * DIST2	Calculates squared distance between two sets of points.
         *
         * Description
         * D = DIST2(X, C) takes two matrices of vectors and calculates the
         * squared Euclidean distance between them.  Both matrices must be of
         * the same column dimension.  If X has M rows and N columns, and C has
         * L rows and N columns, then the result has M rows and L columns.  The
         * I, Jth entry is the  squared distance from the Ith row of X to the
         * Jth row of C.
         *
         * See also
         * GMMACTIV, KMEANS, RBFFWD
         *
         *
         * Copyright (c) Christopher M Bishop, Ian T Nabney (1996, 1997)
         *
         */
        /// <summary>
        /// TODO: 还没验证对不对
        /// </summary>
        public Matrix Dist2(Matrix A, Matrix B)
        {
            int arows = A.Rows, acols = A.Columns,
                brows = B.Rows, bcols = B.Columns;
            if (acols != bcols)
                throw new Exception("Data dimension does not match dimension of centres");

            //var n2 = (ones(ncentres, 1) * sum((x.^2)', 1))' + ...
            //          ones(ndata, 1) * sum((c.^2)',1) - ...
            //          2.*(x*(c'))

            DenseMatrix result = new DenseMatrix(arows, brows);//Zeros(arows, brows);

            for (int i = 0; i < arows; ++i) {
                var arowi = A.GetRow(i);
                for (int j = 0; j < brows; ++j) {
                    //result[i, j] = x.GetRow(i).Sum(xi => xi * xi)
                    //             + c.GetRow(j).Sum(ci => ci * ci)
                    //             - 2 * x.GetRow(i).Select((xi, jj) => xi * c.GetRow(j)[jj]).Sum();
                    var browj = B.GetRow(j);
                    double rij = 0;
                    for (int k = 0; k < acols; ++k) {
                        //double a = A[i, k], b = B[j, k];
                        //double a = arowi[k], b = browj[k];
                        //result[i, j] += (a * a + b * b - 2 * a * b);
                        //rij += (a * a + b * b - 2 * a * b);

                        double d = arowi[k] - browj[k];
                        rij += (d*d);
                    }
                    result[i, j] = rij;

                    // result[i,j] = (Xi^2+Xi^2) + (Xj^2+Xj^2) - 2(Xi*Xj + Xi*Xj)
                    // = (Xi-Xj)^2 + (Yi-Yj)^2
                    //double Xi = x[i, 0], Yi = x[i, 1], Xj = c[j, 0], Yj = c[j, 1];
                    //result[i, j] = (Xi - Xj) * (Xi - Xj) + (Yi - Yj) * (Yi - Yj);
                }
            }
            return result;
        }
Example #9
0
 public static DenseMatrix PointMultiply(this Matrix a, Matrix b)
 {
     var c = new DenseMatrix(a.Rows, a.Columns);
     var rowvec = new double[c.Columns];
     for (int i = 0; i < a.Rows; ++i) {
         var arowi = a.GetRow(i);
         var browi = b.GetRow(i);
         for (int j = 0; j < a.Columns; ++j) {
             rowvec[j] = arowi[j] * browi[j];
         }
         c.SetRow(i, rowvec);
     }
     return c;
 }
Example #10
0
 public void TestMultiply()
 {
     var matrix = new Matrix<double>(5, 5);
     double[] row = { 1, 2, 3, 4, 5 };
     for (int i = 0; i<5; i++)
         matrix.SetRow(i, row);
     MatrixUtils.Multiply(matrix, 2.5);
     double[] testrow = { 2.5, 5, 7.5, 10, 12.5 };
     Assert.AreEqual(testrow, matrix.GetRow(3));
 }
Example #11
0
        private Matrix Hminired(Matrix A)
        {
            //function A=hminired(A)
            //%HMINIRED Initial reduction of cost matrix for the Hungarian method.
            //%
            //%B=assredin(A)
            //%A - the unreduced cost matris.
            //%B - the reduced cost matrix with linked zeros in each row.

            //% v1.0  96-06-13. Niclas Borlin, [email protected]

            //[m,n]=size(A);
            int m = A.Rows, n = A.Columns;

            //% Subtract column-minimum values from each column.
            //colMin=min(A);
            var colMin = new DenseVector(A.GetColumns().Select(col => col.Min()).ToArray());
            //A=A-colMin(ones(n,1),:);
            for (int i = 0; i < A.Rows; ++i) {
                A.SetRow(i, A.GetRow(i) - colMin);
            }

            //% Subtract row-minimum values from each row.
            //rowMin=min(A')';
            var rowMin = new DenseVector(A.GetRows().Select(row => row.Min()).ToArray());
            //A=A-rowMin(:,ones(1,n));
            for (int j = 0; j < A.Rows; ++j) {
                A.SetColumn(j, A.GetColumn(j) - rowMin);
            }

            //% Get positions of all zeros.
            //[i,j]=find(A==0);
            List<int> ilist = new List<int>();
            List<int> jlist = new List<int>();
            A.EachT((v, i, j) => {
                if (v == 0) {
                    ilist.Add(i);
                    jlist.Add(j);
                }
            });

            //% Extend A to give room for row zero list header column.
            //A(1,n+1)=0;
            Matrix tmp = Zeros(n, n + 1);
            tmp.SetSubMatrix(0, n, 0, n, A);
            //for k=1:n
            for (int k = 0; k < n; ++k) {
                //    % Get all column in this row.
                //    cols=j(k==i)';
                var cols = new List<int>();
                cols.Add(n);
                for (int i = 0; i < ilist.Count; ++i) {
                    if (ilist[i] == k) {
                        cols.Add(jlist[i]);
                    }
                }
                cols.Add(-1);

                //    % Insert pointers in matrix.
                //    A(k,[n+1 cols])=[-cols 0];
                for (int i = 0; i < cols.Count - 1; ++i) {
                    tmp[k, cols[i]] = -(cols[i + 1]) - 1;
                } // TODO 不知道对不对了
                //result[k, cols[cols.Count - 1]] = 0;
                //end
            }
            var result = tmp.Each(v => {
                if (v < 0) return v + 1;
                else if (v == 0) return NoMatch;
                else return v;
            });

            return result;
        }
Example #12
0
        private void Hmflip(Matrix A, ref int[] C, ref int[] U, int[] LC, int[] LR, int l, int r)
        {
            //function [A,C,U]=hmflip(A,C,LC,LR,U,l,r)
            //%HMFLIP Flip assignment state of all zeros along a path.
            //%
            //%[A,C,U]=hmflip(A,C,LC,LR,U,l,r)
            //%Input:
            //%A   - the cost matrix.
            //%C   - the assignment vector.
            //%LC  - the column label vector.
            //%LR  - the row label vector.
            //%U   - the
            //%r,l - position of last zero in path.
            //%Output:
            //%A   - updated cost matrix.
            //%C   - updated assignment vector.
            //%U   - updated unassigned row list vector.

            //% v1.0  96-06-14. Niclas Borlin, [email protected]

            //n=size(A,1);
            int n = A.Rows;

            //while (1)
            while (true) {
                //    % Move assignment in column l to row r.
                //    C(l)=r;
                C[l] = r;

                //    % Find zero to be removed from zero list..

                //    % Find zero before this.
                //    m=find(A(r,:)==-l);
                int[] m = A.GetRow(r).FindIdxBy(v => v == -l);

                //    % Link past this zero.
                //    A(r,m)=A(r,l);
                for (int i = 0; i < m.Length; ++i) {
                    A[r, m[i]] = A[r, l];
                }

                //    A(r,l)=0;
                A[r, l] = NoMatch;

                //    % If this was the first zero of the path..
                //    if (LR(r)<0)
                if (LR[r] <= 0 && isNotNoMatch(LR[r])) { // TODO <=0不确定
                    //        ...remove row from unassigned row list and return.
                    //        U(n+1)=U(r);
                    U[n] = U[r];
                    //        U(r)=0;
                    U[r] = NoMatch;
                    //        return;
                    return;
                    //    else
                } else {

                    //        % Move back in this row along the path and get column of next zero.
                    //        l=LR(r);
                    l = LR[r];

                    //        % Insert zero at (r,l) first in zero list.
                    //        A(r,l)=A(r,n+1);
                    A[r, l] = A[r, n];
                    //        A(r,n+1)=-l;
                    A[r, n] = -l;

                    //        % Continue back along the column to get row of next zero in path.
                    //        r=LC(l);
                    r = LC[l];
                    //    end
                }
                //end
            }
        }
Example #13
0
      public void TestSubMatrix()
      {
         Matrix<float> mat = new Matrix<float>(30, 40);
         mat.SetRandUniform(new MCvScalar(0), new MCvScalar(255));
         Matrix<float> submat = mat.GetSubRect(new Rectangle(5, 5, 15, 15));
         for (int i = 0; i < 15; i++)
            for (int j = 0; j < 15; j++)
               EmguAssert.AreEqual(mat[i + 5, j + 5], submat[i, j]);

         Matrix<float> secondRow = mat.GetRow(1);
         for (int i = 0; i < mat.Cols; i++)
         {
            EmguAssert.AreEqual(mat[1, i], secondRow[0, i]);
         }

         Matrix<float> thirdCol = mat.GetCol(2);
         for (int i = 0; i < mat.Rows; i++)
         {
            EmguAssert.AreEqual(mat[i, 2], thirdCol[i, 0]);
         }

         Matrix<float> diagonal = mat.GetDiag();
         for (int i = 0; i < Math.Min(mat.Rows, mat.Cols); i++)
         {
            EmguAssert.AreEqual(diagonal[i, 0], mat[i, i]);
         }
      }
Example #14
0
      public void TestGetDiagColRow()
      {
         Matrix<double> m = new Matrix<double>(new double[,] { {1, 2}, {3, 4}});
         Matrix<double> diag = m.GetDiag();
         EmguAssert.IsTrue(diag[0, 0] == 1);
         EmguAssert.IsTrue(diag[1, 0] == 4);
         EmguAssert.IsTrue(diag.Sum == m.Trace.V0);

         Matrix<double> col1 = m.GetCol(1);
         EmguAssert.IsTrue(col1[0, 0] == 2);
         EmguAssert.IsTrue(col1[1, 0] == 4);
         EmguAssert.IsTrue(col1.Sum == 2 + 4);

         Matrix<double> row1 = m.GetRow(1);
         EmguAssert.IsTrue(row1[0, 0] == 3);
         EmguAssert.IsTrue(row1[0, 1] == 4);
         EmguAssert.IsTrue(row1.Sum == 3 + 4);
      }
Example #15
0
        /*
        function [BH,mean_dist]=sc_compute(Bsamp,Tsamp,mean_dist,nbins_theta,nbins_r,r_inner,r_outer,out_vec);
        % [BH,mean_dist]=sc_compute(Bsamp,Tsamp,mean_dist,nbins_theta,nbins_r,r_inner,r_outer,out_vec);
        %
        % compute (r,theta) histograms for points along boundary
        %
        % Bsamp is 2 x nsamp (x and y coords.)
        % Bsamp是2n长的数组,提供x,y
        % Tsamp is 1 x nsamp (tangent theta)
        % Tsamp是n长的数组,提供tan(theta)
        % out_vec is 1 x nsamp (0 for inlier, 1 for outlier)
        % out_vec是n长的数组,表示是否野点
        %
        % mean_dist is the mean distance, used for length normalization
        % mean_dist是平均距离,用来归一化
        % if it is not supplied, then it is computed from the data
        %
        % outliers are not counted in the histograms, but they do get
        % assigned a histogram
        %
        end
         */
        public Matrix ComputeSC(Matrix Bsamp, Matrix Tsamp, double? mean_dist, out double mean_dist_out, bool[] out_vec)
        {
            //nsamp=size(Bsamp,2);
            //% 求n长
            //int nsamp = Bsamp.Columns;

            //in_vec=out_vec==0;
            //% 初始化野点标记数组吧?
            var in_vec = Utils.InitArray<bool>(nsamp, true);
            out_vec.FillArray(false);

            //% compute r,theta arrays 计算r和t的数组
            //r_array=real(sqrt(dist2(Bsamp',Bsamp'))); % real is needed to
            //                                          % prevent bug in Unix version
            //% r_array是Bsamp的转置和Bsamp的转置之间的dist2
            //% 应该是个n*n的数组了
            var Bsampt = Bsamp.Transpose();
            var r_array = Dist2(Bsampt, Bsampt).Each(Math.Sqrt);

            //theta_array_abs=atan2(Bsamp(2,:)'*ones(1,nsamp)-ones(nsamp,1)*Bsamp(2,:),Bsamp(1,:)'*ones(1,nsamp)-ones(nsamp,1)*Bsamp(1,:))';
            var theta_array_abs = new DenseMatrix(nsamp, nsamp);
            var x_array = Bsamp.GetRow(0);
            var y_array = Bsamp.GetRow(1);
            for (int i = 0; i < nsamp; ++i) {
                for (int j = 0; j < nsamp; ++j) {
                    double xi = x_array[i], yi = y_array[i],
                           xj = x_array[j], yj = y_array[j];
                    theta_array_abs[j, i] = Math.Atan2(yi - yj, xi - xj);
                }
            }

            var Tsampt = Tsamp.Transpose();

            //theta_array=theta_array_abs-Tsamp'*ones(1,nsamp);
            //% 不知道这里是干什么,但是theta_array应该是theta的二维数组
            var theta_array = theta_array_abs - Tsampt * Ones(1, nsamp);

            //% create joint (r,theta) histogram by binning r_array and
            //% theta_array
            //% 通过对r_array和theta_array插槽来求直方图

            //% normalize distance by mean, ignoring outliers
            //% 通过均值来归一化距离参数,忽略野点
            //if isempty(mean_dist)
            if (mean_dist == null) {
                //   tmp=r_array(in_vec,:);
                //   tmp=tmp(:,in_vec);
                //   mean_dist=mean(tmp(:));
                //end
                double mean_sum = 0;
                int mean_count = 0;
                for (int i = 0; i < r_array.Rows; ++i) {
                    for (int j = 0; j < r_array.Columns; ++j) {
                        if (in_vec[i] && in_vec[j]) {
                            mean_sum += r_array[i, j];
                            ++mean_count;
                        }
                    }
                }
                mean_dist_out = mean_sum / mean_count;
            } else {
                mean_dist_out = mean_dist.Value;
            }
            //% 看不懂,但是应该是求非野点的平均值吧,结果存在mean_dist中
            //r_array_n=r_array/mean_dist;
            //% r_array_n是规范化结果,用均值规范化,而不是用最大值,难道我错了?
            var r_array_n = r_array / mean_dist_out;

            //% use a log. scale for binning the distances
            //r_bin_edges=logspace(log10(r_inner),log10(r_outer),5);
            var r_bin_edges = Utils.LogSpace(Math.Log10(r_inner), Math.Log10(r_outer), nbins_r);

            //r_array_q=zeros(nsamp,nsamp);
            var r_array_q = Zeros(nsamp, nsamp);

            //for m=1:nbins_r %m从1循环到r槽数
            for (int i = 0; i < nbins_r; ++i) {
                //   r_array_q=r_array_q+(r_array_n<r_bin_edges(m)); % r_array_q = r_array_q + (r_array_n < r_bin_edges(m))
                r_array_q = r_array_q + r_array_n.Each(v => v < r_bin_edges[i] ? 1 : 0);
                //   % 这个代码的意思应该是说r_array_q中下标小于m的项统统加上r_array_n中小于r_bin_edges(m)的项目数
                //end
            }
            //fz=r_array_q>0; % flag all points inside outer boundary
            //% fz为r_array_q中大于0的项目标记(这应该是个数组)
            var fz = r_array_q.Each(v => v > 0 ? 1 : 0);

            //% put all angles in [0,2pi) range
            //theta_array_2 = rem(rem(theta_array,2*pi)+2*pi,2*pi);
            //% 将所有方向角都弄到[0,2pi)范围内,看不懂
            //% 猜测theta_array_2 = theta_array.Select(t => (t % (2*pi) + (2*pi)) % (2*pi))
            var theta_array_2 = theta_array.Each(t => (t % (2 * Math.PI) + 2 * Math.PI) % (2 * Math.PI));

            //% quantize to a fixed set of angles (bin edges lie on 0,(2*pi)/k,...2*pi
            //% 将方向角量化到固定的角度
            //theta_array_q = 1+floor(theta_array_2/(2*pi/nbins_theta));
            //% theta_array_q = theta_array_2.Select(t => floor(t / (2*pi/nbins_theta)) + 1)
            //% 这是以1为起点的吧
            var theta_array_q = theta_array_2.Each(t => (int)(t / (2 * Math.PI / nbins_theta)));

            //nbins=nbins_theta*nbins_r;
            int nbins = nbins_theta * nbins_r;
            //% 不用说
            //BH=zeros(nsamp,nbins);

            var BH = Zeros(nsamp, nbins);

            //% BH应该就是最后的直方图
            //for n=1:nsamp % n从1循环到nsamp
            for (int i = 0; i < nsamp; ++i) {
                //   fzn=fz(n,:)&in_vec;
                //   Sn=sparse(theta_array_q(n,fzn), r_array_q(n,fzn), 1, nbins_theta, nbins_r);
                //   % sparse这里貌似是生成稀疏矩阵的,Sn应该是用于计算匹配代价的直方图,而BH是包含野点的
                //   BH(n,:)=Sn(:)'; % 转置
                for (int j = 0; j < nsamp; ++j) {
                    int tq = (int)theta_array_q[i, j], tr = (int)r_array_q[i, j];
                    if (tr > 0) {
                        tr--;
                        ++BH[i, tr * nbins_theta + tq];
                    }
                }
            }

            return BH;
        }
Example #16
0
 public void GetRows()
 {
     var matrix1 = new Matrix(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15);
     Assert.AreEqual(new Vector(0, 1, 2), matrix1.GetRow(0));
     Assert.AreEqual(new Vector(4, 5, 6), matrix1.GetRow(1));
     Assert.AreEqual(new Vector(8, 9, 10), matrix1.GetRow(2));
     Assert.AreEqual(new Vector(12, 13, 14), matrix1.GetRow(3));
     Assert.Throws<IndexOutOfRangeException>(() => matrix1.GetRow(-1));
 }
Example #17
0
        private void Hmreduce(Matrix A, ref int[] CH, ref int[] RH, int[] LC, int[] LR, List<int> SLC, List<int> SLR)
        {
            //function [A,CH,RH]=hmreduce(A,CH,RH,LC,LR,SLC,SLR)
            //%HMREDUCE Reduce parts of cost matrix in the Hungerian method.
            //%
            //%[A,CH,RH]=hmreduce(A,CH,RH,LC,LR,SLC,SLR)
            //%Input:
            //%A   - Cost matrix.
            //%CH  - vector of column of 'next zeros' in each row.
            //%RH  - vector with list of unexplored rows.
            //%LC  - column labels.
            //%RC  - row labels.
            //%SLC - set of column labels.
            //%SLR - set of row labels.
            //%
            //%Output:
            //%A   - Reduced cost matrix.
            //%CH  - Updated vector of 'next zeros' in each row.
            //%RH  - Updated vector of unexplored rows.

            //% v1.0  96-06-14. Niclas Borlin, [email protected]

            //n=size(A,1);
            int n = A.Rows;

            //% Find which rows are covered, i.e. unlabelled.
            //coveredRows=LR==0;
            var coveredRows = LR.Select(v => isNoMatch(v)).ToArray();

            //% Find which columns are covered, i.e. labelled.
            //coveredCols=LC~=0;
            var coveredCols = LC.Select(v => isNotNoMatch(v)).ToArray();

            //r=find(~coveredRows);
            var r = coveredRows.Select((v, i) => new { Val = v, Idx = i })
                               .Where(v => !v.Val)
                               .Select(v => v.Idx)
                               .ToArray();
            //c=find(~coveredCols);
            var c = coveredCols.Select((v, i) => new { Val = v, Idx = i })
                               .Where(v => !v.Val)
                               .Select(v => v.Idx)
                               .ToArray();

            //% Get minimum of uncovered elements.
            //m=min(min(A(r,c)));
            double m = double.MaxValue;
            foreach (int i in r) {
                foreach (int j in c) {
                    var val = A[i, j];
                    if (val < m) m = val;
                }
            }

            //% Subtract minimum from all uncovered elements.
            //A(r,c)=A(r,c)-m;
            foreach (int i in r) {
                foreach (int j in c) {
                    A[i, j] -= m;
                }
            }

            //% Check all uncovered columns..
            //for j=c
            foreach (int j in c) {
                //    % ...and uncovered rows in path order..
                //    for i=SLR
                foreach (int i in SLR) {
                    //        % If this is a (new) zero..
                    //        if (A(i,j)==0)
                    if (isNoMatch(A[i, j])) {
                        //            % If the row is not in unexplored list..
                        //            if (RH(i)==0)
                        if (isNoMatch(RH[i])) {
                            //                % ...insert it first in unexplored list.
                            //                RH(i)=RH(n+1);
                            RH[i] = RH[n];
                            //                RH(n+1)=i;
                            RH[n] = i;
                            //                % Mark this zero as "next free" in this row.
                            //                CH(i)=j;
                            CH[i] = j;
                            //            end
                        }
                        //            % Find last unassigned zero on row I.
                        //            row=A(i,:);
                        var row = A.GetRow(i);
                        //            colsInList=-row(row<0);
                        var colsInList = row.Where(v => v <= 0 && isNotNoMatch(v)).Select(v => -v).ToArray(); // TODO <=0不确定
                        int l = NoMatch;
                        //            if (length(colsInList)==0)
                        if (colsInList.Length == 0) {
                            //                % No zeros in the list.
                            //                l=n+1;
                            l = n;
                        } else {
                            //            else
                            //                l=colsInList(row(colsInList)==0);
                            /*
                             * row=[2 -5 0 -3 6 -1];
                             * cil=-row(row<0);     5   3   1
                             * row(cil)==0;         0   1   0
                             * cil(row(cil)==0);    3
                             * */
                            foreach (int col in colsInList) {
                                if (isNoMatch(row[col])) {
                                    l = col;
                                    A[i, l] = -j; // TODO:这样不知道对不对
                                }
                            }
                            //            end
                        }
                        //            % Append this zero to end of list.
                        //            A(i,l)=-j;
                        A[i, l] = -j;
                        //        end
                    }
                    //    end
                }
                //end
            }

            //% Add minimum to all doubly covered elements.
            //r=find(coveredRows);
            r = coveredRows.Select((v, i) => new { Val = v, Idx = i })
                           .Where(v => v.Val)
                           .Select(v => v.Idx)
                           .ToArray();
            //c=find(coveredCols);
            c = coveredCols.Select((v, i) => new { Val = v, Idx = i })
                           .Where(v => v.Val)
                           .Select(v => v.Idx)
                           .ToArray();

            //% Take care of the zeros we will remove.
            //[i,j]=find(A(r,c)<=0);
            var ilist = new List<int>();
            var jlist = new List<int>();
            foreach (int i in r) {
                foreach (int j in c) {
                    if (A[i, j] <= 0) { // TODO <=0不知道对不对
                        ilist.Add(i);
                        jlist.Add(j);
                    }
                }
            }

            //i=r(i);
            //j=c(j);
            // TODO 不知道干嘛,似乎我上面的循环已经包含了这个功能

            //for k=1:length(i)
            for (int k = 0; k < ilist.Count; ++k) {
                //    % Find zero before this in this row.
                //    lj=find(A(i(k),:)==-j(k));
                var ljlist = A.GetRow(ilist[k]).FindIdxBy(d => d != -jlist[k]);
                //    % Link past it.
                //    A(i(k),lj)=A(i(k),j(k));
                foreach (var lj in ljlist) {
                    A[ilist[k], lj] = A[ilist[k], jlist[k]];
                }
                //    % Mark it as assigned.
                //    A(i(k),j(k))=0;
                A[ilist[k], jlist[k]] = NoMatch;
                //end
            }

            //A(r,c)=A(r,c)+m;
            foreach (int i in r) {
                foreach (int j in c) {
                    A[i, j] += m;
                }
            }
        }