public DoubleMatrix2D Assign(DoubleMatrix2D matrixY, Cern.Colt.Function.DoubleDoubleFunction function, Double x = 0, Double y = 0)
        {
            CheckShape(matrixY);

            if (Cern.Jet.Math.Functions.EvaluateDoubleDoubleFunctionEquality(function, F2.PlusMult(x)))
            {
                double alpha = x;

                //if (function is Cern.Jet.Math.PlusMult) { // x[i] = x[i] + alpha*y[i]
                //double alpha = ((Cern.Jet.Math.PlusMult)function).multiplicator;
                if (alpha == 0)
                {
                    return(this);            // nothing to do
                }
                matrixY.ForEachNonZero(
                    new Cern.Colt.Function.IntIntDoubleFunction((i, j, value) =>
                {
                    this[i, j] = this[i, j] + alpha * value;
                    return(value);
                }
                                                                ));
                return(this);
            }

            //if (function==Cern.Jet.Math.Functions.mult) { // x[i] = x[i] * y[i]
            var mult = F2.Mult(x, y);

            if (Cern.Jet.Math.Functions.EvaluateFunctionEquality(function.Method, F2.Mult.Method))
            {
                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];
                        vals[k] *= matrixY[i, j];
                        if (vals[k] == 0)
                        {
                            Remove(i, j);
                        }
                    }
                }
                return(this);
            }

            if (Cern.Jet.Math.Functions.EvaluateFunctionEquality(function.Method, F2.Div.Method))
            {
                //	if (function==Cern.Jet.Math.Functions.Div) { // x[i] = x[i] / y[i]
                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];
                        vals[k] /= matrixY[i, j];
                        if (vals[k] == 0)
                        {
                            Remove(i, j);
                        }
                    }
                }
                return(this);
            }

            return(base.Assign(matrixY, function));
        }