/// <summary> /// Constructs a diagonal block matrix from the given parts. /// </summary> /// <param name="a"> /// The matrix A. /// </param> /// <param name="b"> /// The matrix B. /// </param> /// <param name="c"> /// The matrix C. /// </param> /// <returns> /// A diagonal block matrix. /// </returns> public DoubleMatrix2D ComposeDiagonal(DoubleMatrix2D a, DoubleMatrix2D b, DoubleMatrix2D c) { DoubleMatrix2D diag = Make(a.Rows + b.Rows + c.Rows, a.Columns + b.Columns + c.Columns); diag.ViewPart(0, 0, a.Rows, a.Columns).Assign(a); diag.ViewPart(a.Rows, a.Columns, b.Rows, b.Columns).Assign(b); diag.ViewPart(a.Rows + b.Rows, a.Columns + b.Columns, c.Rows, c.Columns).Assign(c); return(diag); }
/// <summary> /// Constructs an identity matrix (having ones on the diagonal and zeros elsewhere). /// </summary> /// <param name="rowsAndColumns"> /// The rows and columns. /// </param> /// <returns> /// An identity matrix. /// </returns> public DoubleMatrix2D Identity(int rowsAndColumns) { DoubleMatrix2D matrix = Make(rowsAndColumns, rowsAndColumns); for (int i = rowsAndColumns; --i >= 0;) { matrix[i, i] = 1; } return(matrix); }
/// <summary> /// Constructs a new vector consisting of the diagonal elements of <tt>A</tt>. /// Cells values are copied. The new vector is not a view. /// </summary> /// <param name="a"> /// The amatrix, need not be square. /// </param> /// <returns> /// A new vector. /// </returns> public DoubleMatrix1D Diagonal(DoubleMatrix2D a) { int min = Math.Min(a.Rows, a.Columns); DoubleMatrix1D diag = make1D(min); for (int i = min; --i >= 0;) { diag[i] = a[i, i]; } return(diag); }
/// <summary> /// Constructs a new diagonal matrix whose diagonal elements are the elements of <tt>vector</tt>. /// Cells values are copied. The new matrix is not a view. /// </summary> /// <param name="vector"> /// The vector. /// </param> /// <returns> /// A new matrix. /// </returns> public DoubleMatrix2D Diagonal(DoubleMatrix1D vector) { int size = vector.Size; DoubleMatrix2D diag = Make(size, size); for (int i = size; --i >= 0;) { diag[i, i] = vector[i]; } return(diag); }
/// <summary> /// Constructs a diagonal block matrix from the given parts (the <i>direct sum</i> of two matrices). /// </summary> /// <param name="a"> /// The matrix A. /// </param> /// <param name="b"> /// The matrix B. /// </param> /// <returns> /// A diagonal block matrix. /// </returns> public DoubleMatrix2D ComposeDiagonal(DoubleMatrix2D a, DoubleMatrix2D b) { int ar = a.Rows; int ac = a.Columns; int br = b.Rows; int bc = b.Columns; DoubleMatrix2D sum = Make(ar + br, ac + bc); sum.ViewPart(0, 0, ar, ac).Assign(a); sum.ViewPart(ar, ac, br, bc).Assign(b); return(sum); }
/// <summary> /// Returns <tt>true</tt> if both matrices share at least one identical cell. /// </summary> /// <param name="other"> /// The other matrix. /// </param> /// <returns> /// <tt>true</tt> if both matrices share at least one identical cell. /// </returns> protected bool HaveSharedCells(DoubleMatrix2D other) { if (other == null) { return(false); } if (this == other) { return(true); } return(GetContent().HaveSharedCellsRaw(other.GetContent())); }
/// <summary> /// Assigns the result of a function to each cell; <tt>x[row,col] = function(x[row,col],y[row,col])</tt>. /// </summary> /// <param name="y"> /// The secondary matrix to operate on. /// </param> /// <param name="function"> /// The function taking as first argument the current cell's value of <tt>this</tt>, /// and as second argument the current cell's value of <tt>y</tt>. /// </param> /// <returns> /// <tt>this</tt> (for convenience only). /// </returns> /// <exception cref="ArgumentException"> /// If <tt>columns() != other.columns() || rows() != other.rows()</tt> /// </exception> public virtual DoubleMatrix2D Assign(DoubleMatrix2D y, DoubleDoubleFunction function) { CheckShape(y); for (int row = Rows; --row >= 0;) { for (int column = Columns; --column >= 0;) { this[row, column] = function(this[row, column], y[row, column]); } } return(this); }
/// <summary> /// Constructs a matrix with cells having descending values. /// For debugging purposes. /// </summary> /// <param name="rows"> /// The number of rows. /// </param> /// <param name="columns"> /// The number of columns. /// </param> /// <returns> /// A matrix with cells having descending values. /// </returns> public DoubleMatrix2D Descending(int rows, int columns) { DoubleMatrix2D matrix = Make(rows, columns); int v = 0; for (int row = rows; --row >= 0;) { for (int column = columns; --column >= 0;) { matrix[row, column] = v++; } } return(matrix); }
/// <summary> /// Constructs a new matrix which is duplicated both along the row and column dimension. /// </summary> /// <param name="a"> /// The matrix to duplicate. /// </param> /// <param name="rowRepeat"> /// The number of row repetitions. /// </param> /// <param name="columnRepeat"> /// The number of column repetitions. /// </param> /// <returns> /// A matrix. /// </returns> public DoubleMatrix2D Repeat(DoubleMatrix2D a, int rowRepeat, int columnRepeat) { int r = a.Rows; int c = a.Columns; DoubleMatrix2D matrix = Make(r * rowRepeat, c * columnRepeat); for (int i = rowRepeat; --i >= 0;) { for (int j = columnRepeat; --j >= 0;) { matrix.ViewPart(r * i, c * j, r, c).Assign(a); } } return(matrix); }
/// <summary> /// Linear algebraic matrix-matrix multiplication; <tt>C = alpha * A x B + beta*C</tt>. /// </summary> /// <param name="b"> /// The second source matrix. /// </param> /// <param name="c"> /// The matrix where results are to be storedd Set this parameter to <tt>null</tt> to indicate that a new result matrix 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> /// <param name="transposeB"> /// Whether B must be transposed. /// </param> /// <returns> /// C (for convenience only). /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// If <tt>B.rows() != A.columns()</tt>. /// </exception> /// <exception cref="ArgumentException"> /// If <tt>C.rows() != A.rows() || C.columns() != B.columns()</tt>. /// </exception> /// <exception cref="ArithmeticException"> /// If <tt>A == C || B == C</tt>. /// </exception> public virtual DoubleMatrix2D ZMult(DoubleMatrix2D b, DoubleMatrix2D c, double alpha, double beta, bool transposeA, bool transposeB) { if (transposeA) { return(ViewDice().ZMult(b, c, alpha, beta, false, transposeB)); } if (transposeB) { return(ZMult(b.ViewDice(), c, alpha, beta, false, false)); } int m = Rows; int n = Columns; int p = b.Columns; if (c == null) { c = new DenseDoubleMatrix2D(m, p); } if (b.Rows != n) { throw new ArgumentOutOfRangeException("b", String.Format(Cern.LocalizedResources.Instance().Exception_Matrix2DInnerDimensionMustAgree, this, b)); } if (c.Rows != m || c.Columns != p) { throw new ArgumentException(String.Format(Cern.LocalizedResources.Instance().Exception_IncompatibleResultMatrix, this, b, c)); } if (this == c || b == c) { throw new ArithmeticException(Cern.LocalizedResources.Instance().Exception_MatricesMustNotBeIdentical); } for (int j = p; --j >= 0;) { for (int i = m; --i >= 0;) { double s = 0; for (int k = n; --k >= 0;) { s += this[i, k] * b[k, j]; } c[i, j] = (alpha * s) + (beta * c[i, j]); } } return(c); }
/// <summary> /// Linear algebraic matrix-matrix multiplication; <tt>C = alpha * A x B + beta*C</tt>. /// </summary> /// <param name="b"> /// The second source matrix. /// </param> /// <param name="c"> /// The matrix where results are to be storedd Set this parameter to <tt>null</tt> to indicate that a new result matrix 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> /// <param name="transposeB"> /// Whether B must be transposed. /// </param> /// <returns> /// C (for convenience only). /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// If <tt>B.rows() != A.columns()</tt>. /// </exception> /// <exception cref="ArgumentException"> /// If <tt>C.rows() != A.rows() || C.columns() != B.columns()</tt>. /// </exception> /// <exception cref="ArithmeticException"> /// If <tt>A == C || B == C</tt>. /// </exception> public virtual DoubleMatrix2D ZMult(DoubleMatrix2D b, DoubleMatrix2D c, double alpha, double beta, bool transposeA, bool transposeB) { if (transposeA) { return(ViewDice().ZMult(b, c, alpha, beta, false, transposeB)); } if (transposeB) { return(ZMult(b.ViewDice(), c, alpha, beta, false, false)); } int m = Rows; int n = Columns; int p = b.Columns; if (c == null) { c = new DenseDoubleMatrix2D(m, p); } if (b.Rows != n) { throw new ArgumentOutOfRangeException("b", "Matrix2D inner dimensions must agree:" + this + ", " + b); } if (c.Rows != m || c.Columns != p) { throw new ArgumentException("Incompatible result matrix: " + this + ", " + b + ", " + c); } if (this == c || b == c) { throw new ArithmeticException("Matrices must not be identical"); } for (int j = p; --j >= 0;) { for (int i = m; --i >= 0;) { double s = 0; for (int k = n; --k >= 0;) { s += this[i, k] * b[k, j]; } c[i, j] = (alpha * s) + (beta * c[i, j]); } } return(c); }
/// <summary> /// Modifies the given matrix to be a randomly sampled matrix. /// Randomly picks exactly <i>System.Math.Round(rows*columns*nonZeroFraction)</i> cells and initializes them to <i>value</i>, all the rest will be initialized to zero. /// Note that this is not the same as setting each cell with probability <i>nonZeroFraction</i> to <i>value</i>. /// Note: The random seed is a constant. /// </summary> /// <param name="factory"></param> /// <param name="matrix"></param> /// <param name="value"></param> /// <param name="nonZeroFraction"></param> /// <returns></returns> /// <exception cref="ArgumentException">if nonZeroFraction < 0 || nonZeroFraction > 1.</exception> /// <see cref="Cern.Jet.Random.Sampling.RandomSamplingAssistant"/> public static DoubleMatrix2D Sample(this DoubleFactory2D factory, DoubleMatrix2D matrix, double value, double nonZeroFraction) { int rows = matrix.Rows; int columns = matrix.Columns; double epsilon = 1e-09; if (nonZeroFraction < 0 - epsilon || nonZeroFraction > 1 + epsilon) { throw new ArgumentException(); } if (nonZeroFraction < 0) { nonZeroFraction = 0; } if (nonZeroFraction > 1) { nonZeroFraction = 1; } matrix.Assign(0); int size = rows * columns; int n = (int)System.Math.Round(size * nonZeroFraction); if (n == 0) { return(matrix); } var sampler = new Cern.Jet.Random.Sampling.RandomSamplingAssistant(n, size, new Cern.Jet.Random.Engine.MersenneTwister()); for (int i = 0; i < size; i++) { if (sampler.SampleNextElement()) { int row = (int)(i / columns); int column = (int)(i % columns); matrix[row, column] = value; } } return(matrix); }
/// <summary> /// 8 neighbor stencil transformationd For efficient finite difference operations. /// Applies a function to a moving <tt>3 x 3</tt> window. /// Does nothing if <tt>rows() < 3 || columns() < 3</tt>. /// </summary> /// <param name="b"> /// The matrix to hold the results. /// </param> /// <param name="function"> /// The function to be applied to the 9 cells. /// </param> /// <exception cref="ArgumentNullException"> /// If <tt>function==null</tt>. /// </exception> /// <exception cref="ArgumentOutOfRangeException"> /// If <tt>rows() != B.rows() || columns() != B.columns()</tt>. /// </exception> public virtual void ZAssign8Neighbors(DoubleMatrix2D b, Double9Function function) { if (function == null) { throw new ArgumentNullException("function", Cern.LocalizedResources.Instance().Exception_FuncionMustNotBeNull); } CheckShape(b); if (Rows < 3 || Columns < 3) { return; // nothing to do } int r = Rows - 1; int c = Columns - 1; for (int i = 1; i < r; i++) { double a00 = this[i - 1, 0]; double a01 = this[i - 1, 1]; double a10 = this[i, 0]; double a11 = this[i, 1]; double a20 = this[i + 1, 0]; double a21 = this[i + 1, 1]; for (int j = 1; j < c; j++) { // in each step six cells can be remembered in registers - they don't need to be reread from slow memory // in each step 3 instead of 9 cells need to be read from memory. double a02 = this[i - 1, j + 1]; double a12 = this[i, j + 1]; double a22 = this[i + 1, j + 1]; b[i, j] = function(a00, a01, a02, a10, a11, a12, a20, a21, a22); a00 = a01; a10 = a11; a20 = a21; a01 = a02; a11 = a12; a21 = a22; } } }
/// <summary> /// Construct a matrix from a one-dimensional column-major packed array, ala Fortran. /// </summary> /// <param name="values"> /// One-dimensional array of doubles, packed by columns (ala Fortran). /// </param> /// <param name="rows"> /// The number of rows. /// </param> /// <returns> /// A matrix. /// </returns> /// <exception cref="ArgumentException"> /// <tt>values.length</tt> must be a multiple of <tt>rows</tt>. /// </exception> public DoubleMatrix2D Make(double[] values, int rows) { int columns = rows != 0 ? values.Length / rows : 0; if (rows * columns != values.Length) { throw new ArgumentException(Cern.LocalizedResources.Instance().Exception_ArrayLengthMustBeAMultipleOfM); } DoubleMatrix2D matrix = Make(rows, columns); for (int row = 0; row < rows; row++) { for (int column = 0; column < columns; column++) { matrix[row, column] = values[row + (column * rows)]; } } return(matrix); }
/// <summary> /// Construct a matrix from a one-dimensional column-major packed array, ala Fortran. /// </summary> /// <param name="values"> /// One-dimensional array of doubles, packed by columns (ala Fortran). /// </param> /// <param name="rows"> /// The number of rows. /// </param> /// <returns> /// A matrix. /// </returns> /// <exception cref="ArgumentException"> /// <tt>values.length</tt> must be a multiple of <tt>rows</tt>. /// </exception> public DoubleMatrix2D Make(double[] values, int rows) { int columns = rows != 0 ? values.Length / rows : 0; if (rows * columns != values.Length) { throw new ArgumentException("Array length must be a multiple of m."); } DoubleMatrix2D matrix = Make(rows, columns); for (int row = 0; row < rows; row++) { for (int column = 0; column < columns; column++) { matrix[row, column] = values[row + (column * rows)]; } } return(matrix); }
/// <summary> /// Applies a function to each corresponding cell of two matrices and aggregates the results. /// </summary> /// <param name="other"> /// The other. /// </param> /// <param name="aggr"> /// An aggregation function taking as first argument the current aggregation and as second argument the transformed current cell values. /// </param> /// <param name="f"> /// A function transforming the current cell values. /// </param> /// <returns> /// The aggregated measure. /// </returns> /// <exception cref="ArgumentException"> /// If <tt>columns() != other.columns() || rows() != other.rows()</tt> /// </exception> public double Aggregate(DoubleMatrix2D other, DoubleDoubleFunction aggr, DoubleDoubleFunction f) { CheckShape(other); if (Size == 0) { return(double.NaN); } double a = f(this[Rows - 1, Columns - 1], other[Rows - 1, Columns - 1]); int d = 1; // last cell already done for (int row = Rows; --row >= 0;) { for (int column = Columns - d; --column >= 0;) { a = aggr(a, f(this[row, column], other[row, column])); } d = 0; } return(a); }
/// <summary> /// Replaces all cell values of the receiver with the values of another matrix. /// Both matrices must have the same number of rows and columns. /// If both matrices share the same cells (as is the case if they are views derived from the same matrix) and intersect in an ambiguous way, then replaces <i>as if</i> using an intermediate auxiliary deep copy of <tt>other</tt>. /// </summary> /// <param name="other"> /// The source matrix to copy from (may be identical to the receiver). /// </param> /// <returns> /// <tt>this</tt> (for convenience only). /// </returns> /// <exception cref="ArgumentException"> /// If <tt>columns() != other.columns() || rows() != other.rows()</tt> /// </exception> public virtual DoubleMatrix2D Assign(DoubleMatrix2D other) { if (other == this) { return(this); } CheckShape(other); if (HaveSharedCells(other)) { other = other.Copy(); } for (int row = Rows; --row >= 0;) { for (int column = Columns; --column >= 0;) { this[row, column] = other[row, column]; } } return(this); }
/// <summary> /// C = A||B; Constructs a new matrix which is the row-wise concatenation of two other matrices. /// </summary> /// <param name="a"> /// The matrix A. /// </param> /// <param name="b"> /// The matrix B. /// </param> /// <returns> /// A new matrix which is the row-wise concatenation of A and B. /// </returns> public DoubleMatrix2D AppendRows(DoubleMatrix2D a, DoubleMatrix2D b) { // force both to have maximal shared number of columns. if (b.Columns > a.Columns) { b = b.ViewPart(0, 0, b.Rows, a.Columns); } else if (b.Columns < a.Columns) { a = a.ViewPart(0, 0, a.Rows, b.Columns); } // concatenate int ar = a.Rows; int br = b.Rows; int c = a.Columns; DoubleMatrix2D matrix = Make(ar + br, c); matrix.ViewPart(0, 0, ar, c).Assign(a); matrix.ViewPart(ar, 0, br, c).Assign(b); return(matrix); }
/// <summary> /// C = A||B; Constructs a new matrix which is the column-wise concatenation of two other matrices. /// </summary> /// <param name="a"> /// The matrix A. /// </param> /// <param name="b"> /// The matrix B. /// </param> /// <returns> /// The column-wise concatenation of A and B. /// </returns> public DoubleMatrix2D AppendColumns(DoubleMatrix2D a, DoubleMatrix2D b) { // force both to have maximal shared number of rows. if (b.Rows > a.Rows) { b = b.ViewPart(0, 0, a.Rows, b.Columns); } else if (b.Rows < a.Rows) { a = a.ViewPart(0, 0, b.Rows, a.Columns); } // concatenate int ac = a.Columns; int bc = b.Columns; int r = a.Rows; DoubleMatrix2D matrix = Make(r, ac + bc); matrix.ViewPart(0, 0, r, ac).Assign(a); matrix.ViewPart(0, ac, r, bc).Assign(b); return(matrix); }
/// <summary> /// Returns <tt>true</tt> if both matrices share at least one identical cell. /// </summary> /// <param name="other"> /// The other matrix. /// </param> /// <returns> /// <tt>true</tt> if both matrices share at least one identical cell. /// </returns> protected virtual bool HaveSharedCellsRaw(DoubleMatrix2D other) { return(false); }
/// <summary> /// Constructs a block matrix made from the given parts. /// <para> /// All matrices of a given column within <tt>parts</tt> must have the same number of columns. /// All matrices of a given row within <tt>parts</tt> must have the same number of rows. /// Otherwise an <tt>IllegalArgumentException</tt> is thrown. /// <tt>null</tt>s within <tt>parts[row,col]</tt> are an exception to this rule: they are ignored. /// Cells are copied. /// </para> /// </summary> /// <param name="parts"> /// The parts. /// </param> /// <returns> /// A block matrix. /// </returns> /// <exception cref="ArgumentOutOfRangeException"> /// If the parts are not subject to the conditions outlined above. /// </exception> public DoubleMatrix2D Compose(DoubleMatrix2D[][] parts) { checkRectangularShape(parts); int rows = parts.Length; int columns = 0; if (parts.Length > 0) { columns = parts[0].Length; } DoubleMatrix2D empty = Make(0, 0); if (rows == 0 || columns == 0) { return(empty); } // determine maximum column width of each column var maxWidths = new int[columns]; for (int column = columns; --column >= 0;) { int maxWidth = 0; for (int row = rows; --row >= 0;) { DoubleMatrix2D part = parts[row][column]; if (part != null) { int width = part.Columns; if (maxWidth > 0 && width > 0 && width != maxWidth) { throw new ArgumentOutOfRangeException("parts", "Different number of columns."); } maxWidth = Math.Max(maxWidth, width); } } maxWidths[column] = maxWidth; } // determine row height of each row var maxHeights = new int[rows]; for (int row = rows; --row >= 0;) { int maxHeight = 0; for (int column = columns; --column >= 0;) { DoubleMatrix2D part = parts[row][column]; if (part != null) { int height = part.Rows; if (maxHeight > 0 && height > 0 && height != maxHeight) { throw new ArgumentOutOfRangeException("parts", "Different number of rows."); } maxHeight = Math.Max(maxHeight, height); } } maxHeights[row] = maxHeight; } // shape of result int resultRows = 0; for (int row = rows; --row >= 0;) { resultRows += maxHeights[row]; } int resultCols = 0; for (int column = columns; --column >= 0;) { resultCols += maxWidths[column]; } DoubleMatrix2D matrix = Make(resultRows, resultCols); // copy int r = 0; for (int row = 0; row < rows; row++) { int c = 0; for (int column = 0; column < columns; column++) { DoubleMatrix2D part = parts[row][column]; if (part != null) { matrix.ViewPart(r, c, part.Rows, part.Columns).Assign(part); } c += maxWidths[column]; } r += maxHeights[row]; } return(matrix); }
/// <summary> /// Splits a block matrix into its constituent blocks; Copies blocks of a matrix into the given parts. /// <para> /// All matrices of a given column within <tt>parts</tt> must have the same number of columns. /// All matrices of a given row within <tt>parts</tt> must have the same number of rows. /// Otherwise an <tt>IllegalArgumentException</tt> is thrown. /// <tt>null</tt>s within <tt>parts[row,col]</tt> are an exception to this rule: they are ignored. /// Cells are copied. /// </para> /// </summary> /// <param name="parts"> /// The parts. /// </param> /// <param name="matrix"> /// The matrix. /// </param> /// <exception cref="ArgumentException"> /// subject to the conditions outlined above. /// </exception> public void Decompose(DoubleMatrix2D[][] parts, DoubleMatrix2D matrix) { checkRectangularShape(parts); int rows = parts.Length; int columns = 0; if (parts.Length > 0) { columns = parts[0].Length; } if (rows == 0 || columns == 0) { return; } // determine maximum column width of each column var maxWidths = new int[columns]; for (int column = columns; --column >= 0;) { int maxWidth = 0; for (int row = rows; --row >= 0;) { DoubleMatrix2D part = parts[row][column]; if (part != null) { int width = part.Columns; if (maxWidth > 0 && width > 0 && width != maxWidth) { throw new ArgumentException("Different number of columns."); } maxWidth = Math.Max(maxWidth, width); } } maxWidths[column] = maxWidth; } // determine row height of each row var maxHeights = new int[rows]; for (int row = rows; --row >= 0;) { int maxHeight = 0; for (int column = columns; --column >= 0;) { DoubleMatrix2D part = parts[row][column]; if (part != null) { int height = part.Rows; if (maxHeight > 0 && height > 0 && height != maxHeight) { throw new ArgumentException("Different number of rows."); } maxHeight = Math.Max(maxHeight, height); } } maxHeights[row] = maxHeight; } // shape of result parts int resultRows = 0; for (int row = rows; --row >= 0;) { resultRows += maxHeights[row]; } int resultCols = 0; for (int column = columns; --column >= 0;) { resultCols += maxWidths[column]; } if (matrix.Rows < resultRows || matrix.Columns < resultCols) { throw new ArgumentException("Parts larger than matrix."); } // copy int r = 0; for (int row = 0; row < rows; row++) { int c = 0; for (int column = 0; column < columns; column++) { DoubleMatrix2D part = parts[row][column]; if (part != null) { part.Assign(matrix.ViewPart(r, c, part.Rows, part.Columns)); } c += maxWidths[column]; } r += maxHeights[row]; } }
/// <summary> /// Linear algebraic matrix-matrix multiplication; <tt>C = A x B</tt>. /// </summary> /// <param name="b"> /// The matrix B. /// </param> /// <param name="c"> /// The matrix C. /// </param> /// <returns> /// The matrix C (for convenience only). /// </returns> public DoubleMatrix2D ZMult(DoubleMatrix2D b, DoubleMatrix2D c) { return(ZMult(b, c, 1, (c == null ? 1 : 0), false, false)); }
/// <summary> /// Constructs a randomly sampled matrix with the given shape. /// Randomly picks exactly<tt>Math.round(rows* columns* nonZeroFraction)</tt> cells and initializes them to<tt> value</tt>, all the rest will be initialized to zero. /// Note that this is not the same as setting each cell with probability<tt> nonZeroFraction</tt> to<tt> value</tt>. /// Note: The random seed is a constant. /// </summary> /// <param name="factory"></param> /// <param name="rows"></param> /// <param name="columns"></param> /// <param name="value"></param> /// <param name="nonZeroFraction"></param> /// <returns></returns> /// <exception cref="ArgumentException">if nonZeroFraction < 0 || nonZeroFraction > 1.</exception> /// <see cref="Cern.Jet.Random.Sampling.RandomSamplingAssistant"/> public static DoubleMatrix2D Sample(this DoubleFactory2D factory, int rows, int columns, double value, double nonZeroFraction) { DoubleMatrix2D matrix = factory.Make(rows, columns); return(Sample(factory, matrix, value, nonZeroFraction)); }