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); }
/// <summary> /// Linear algebraic matrix-vector multiplication; <tt>z = alpha * A * y + beta*z</tt>. /// </summary> /// <param name="y"> /// The ource vector. /// </param> /// <param name="z"> /// The vector where results are to be stored. Set this parameter to <tt>null</tt> to indicate that a new result vector shall be constructed. /// </param> /// <param name="alpha"> /// The alpha. /// </param> /// <param name="beta"> /// The beta. /// </param> /// <param name="transposeA"> /// Whether A must be transposed. /// </param> /// <returns> /// z (for convenience only). /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// If <tt>A.columns() != y.size() || A.rows() > z.size())</tt>. /// </exception> public override DoubleMatrix1D ZMult(DoubleMatrix1D y, DoubleMatrix1D z, double alpha, double beta, bool transposeA) { if (transposeA) { return(ViewDice().ZMult(y, z, alpha, beta, false)); } if (z == null) { z = new DenseDoubleMatrix1D(Rows); } if (!(y is DenseDoubleMatrix1D) && z is DenseDoubleMatrix1D) { return(base.ZMult(y, z, alpha, beta, false)); } if (Columns != y.Size || Rows > z.Size) { throw new ArgumentException("Incompatible args: " + this + ", " + y + ", " + z); } var yy = (DenseDoubleMatrix1D)y; var zz = (DenseDoubleMatrix1D)z; double[] aElems = Elements; double[] yElems = yy.Elements; double[] zElems = zz.Elements; if (aElems == null || yElems == null || zElems == null) { throw new ApplicationException(); } int _as = ColumnStride; int ys = yy.Stride; int zs = zz.Stride; int indexA = Index(0, 0); int indexY = yy.Index(0); int indexZ = zz.Index(0); int cols = Columns; for (int row = Rows; --row >= 0;) { double sum = 0; /* * // not loop unrolled * for (int i=indexA, j=indexY, column=columns; --column >= 0;) { * sum += AElems[i] * yElems[j]; * i += As; * j += ys; * } */ // loop unrolled int i = indexA - _as; int j = indexY - ys; for (int k = cols % 4; --k >= 0;) { sum += aElems[i += _as] * yElems[j += ys]; } for (int k = cols / 4; --k >= 0;) { sum += (aElems[i += _as] * yElems[j += ys]) + (aElems[i += _as] * yElems[j += ys]) + (aElems[i += _as] * yElems[j += ys]) + (aElems[i += _as] * yElems[j += ys]); } zElems[indexZ] = (alpha * sum) + (beta * zElems[indexZ]); indexA += RowStride; indexZ += zs; } 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); }