public override DoubleMatrix1D ZMult(DoubleMatrix1D y, DoubleMatrix1D z, double alpha, double beta, Boolean transposeA)
        {
            int m = Rows;
            int n = Columns;

            if (transposeA)
            {
                m = Columns;
                n = Rows;
            }

            Boolean ignore = (z == null);

            if (z == null)
            {
                z = new DenseDoubleMatrix1D(m);
            }

            if (!(!this.IsView && y is DenseDoubleMatrix1D && z is DenseDoubleMatrix1D))
            {
                return(base.ZMult(y, z, alpha, beta, transposeA));
            }

            if (n != y.Size || m > z.Size)
            {
                throw new ArgumentException(String.Format(Cern.LocalizedResources.Instance().Exception_IncompatibleArgs, ((transposeA ? ViewDice() : this).ToStringShort()), y.ToStringShort(), z.ToStringShort()));
            }

            if (!ignore)
            {
                z.Assign(F1.Mult(beta / alpha));
            }

            DenseDoubleMatrix1D zz = (DenseDoubleMatrix1D)z;

            double[] zElements = zz.Elements;
            int      zStride   = zz.Stride;
            int      zi        = z.Index(0);

            DenseDoubleMatrix1D yy = (DenseDoubleMatrix1D)y;

            double[] yElements = yy.Elements;
            int      yStride   = yy.Stride;
            int      yi        = y.Index(0);

            if (yElements == null || zElements == null)
            {
                throw new NullReferenceException();
            }

            ForEachNonZero(
                new Cern.Colt.Function.IntIntDoubleFunction((i, j, value) =>
            {
                if (transposeA)
                {
                    int tmp = i; i = j; j = tmp;
                }
                zElements[zi + zStride * i] += value * yElements[yi + yStride * j];
                //z.setQuick(row,z.getQuick(row) + value * y.getQuick(column));
                //Console.WriteLine("["+i+","+j+"]-->"+value);
                return(value);
            }
                                                            ));

            if (alpha != 1)
            {
                z.Assign(F1.Mult(alpha));
            }
            return(z);
        }
        public override DoubleMatrix1D ZMult(DoubleMatrix1D y, DoubleMatrix1D z, double alpha, double beta, Boolean transposeA)
        {
            int m = Rows;
            int n = Columns;

            if (transposeA)
            {
                m = Columns;
                n = Rows;
            }

            Boolean ignore = (z == null || !transposeA);

            if (z == null)
            {
                z = new DenseDoubleMatrix1D(m);
            }

            if (!(y is DenseDoubleMatrix1D && z is DenseDoubleMatrix1D))
            {
                return(base.ZMult(y, z, alpha, beta, transposeA));
            }

            if (n != y.Size || m > z.Size)
            {
                throw new ArgumentException("Incompatible args: " + ((transposeA ? ViewDice() : this).ToStringShort()) + ", " + y.ToStringShort() + ", " + z.ToStringShort());
            }

            DenseDoubleMatrix1D zz = (DenseDoubleMatrix1D)z;

            double[] zElements = zz.Elements;
            int      zStride   = zz.Stride;
            int      zi        = z.Index(0);

            DenseDoubleMatrix1D yy = (DenseDoubleMatrix1D)y;

            double[] yElements = yy.Elements;
            int      yStride   = yy.Stride;
            int      yi        = y.Index(0);

            if (yElements == null || zElements == null)
            {
                throw new NullReferenceException();
            }

            /*
             * forEachNonZero(
             *  new Cern.Colt.Function.IntIntDoubleFunction() {
             *      public double apply(int i, int j, double value) {
             *          zElements[zi + zStride*i] += value * yElements[yi + yStride*j];
             *          //z.SetQuick(row,z.getQuick(row) + value * y.getQuick(column));
             *          //Console.WriteLine("["+i+","+j+"]-->"+value);
             *          return value;
             *      }
             *  }
             * );
             */


            int[]    idx  = Indexes.ToArray();
            double[] vals = Values.ToArray();
            int      s    = Starts.Length - 1;

            if (!transposeA)
            {
                for (int i = 0; i < s; i++)
                {
                    int    high = Starts[i + 1];
                    double sum  = 0;
                    for (int k = Starts[i]; k < high; k++)
                    {
                        int j = idx[k];
                        sum += vals[k] * yElements[yi + yStride * j];
                    }
                    zElements[zi] = alpha * sum + beta * zElements[zi];
                    zi           += zStride;
                }
            }
            else
            {
                if (!ignore)
                {
                    z.Assign(F1.Mult(beta));
                }
                for (int i = 0; i < s; i++)
                {
                    int    high  = Starts[i + 1];
                    double yElem = alpha * yElements[yi + yStride * i];
                    for (int k = Starts[i]; k < high; k++)
                    {
                        int j = idx[k];
                        zElements[zi + zStride * j] += vals[k] * yElem;
                    }
                }
            }

            return(z);
        }