public override DoubleMatrix2D ForEachNonZero(Cern.Colt.Function.IntIntDoubleFunction function)
        {
            int[]    idx  = Indexes.ToArray();
            double[] vals = Values.ToArray();

            for (int i = Starts.Length - 1; --i >= 0;)
            {
                int low = Starts[i];
                for (int k = Starts[i + 1]; --k >= low;)
                {
                    int    j     = idx[k];
                    double value = vals[k];
                    double r     = function(i, j, value);
                    if (r != value)
                    {
                        vals[k] = r;
                    }
                }
            }
            return(this);
        }
        public override DoubleMatrix2D ForEachNonZero(Cern.Colt.Function.IntIntDoubleFunction function)
        {
            for (int kind = 0; kind <= 2; kind++)
            {
                int i = 0, j = 0;
                switch (kind)
                {
                case 0:
                    i = 1;      // lower
                                // case 1: {   } // diagonal
                    break;

                case 2:
                    j = 1;      // upper
                    break;
                }
                int low  = dims[kind];
                int high = dims[kind + 1];

                for (int k = low; k < high; k++, i++, j++)
                {
                    double value = values[k];
                    if (value != 0)
                    {
                        double r = function(i, j, value);
                        if (r != value)
                        {
                            if (r == 0)
                            {
                                dims[kind + NONZERO]++;         // one non zero more
                            }
                            values[k] = r;
                        }
                    }
                }
            }
            return(this);
        }