/// <summary> /// Replaces all cell values of the receiver with the values of another matrix. /// Both matrices must have the same number of Slices, 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 <i>other</i>. /// </summary> /// <param name="source">the source matrix to copy from (may be identical to the receiver).</param> /// <returns><i>this</i> (for convenience only).</returns> /// <exception cref="ArgumentException">if <i>Slices() != source.Slices() || Rows() != source.Rows() || Columns() != source.Columns()</i></exception> public override DoubleMatrix3D Assign(DoubleMatrix3D source) { // overriden for performance only if (!(source is DenseDoubleMatrix3D)) { return(base.Assign(source)); } DenseDoubleMatrix3D other = (DenseDoubleMatrix3D)source; if (other == this) { return(this); } CheckShape(other); if (HaveSharedCells(other)) { DoubleMatrix3D c = other.Copy(); if (!(c is DenseDoubleMatrix3D)) { // should not happen return(base.Assign(source)); } other = (DenseDoubleMatrix3D)c; } if (!this.IsView && !other.IsView) { // quickest Array.Copy(other.Elements, 0, this.Elements, 0, this.Elements.Length); return(this); } return(base.Assign(other)); }
/// <summary> /// Returns <i>true</i> if both matrices share common cells. /// More formally, returns <i>true</i> if <i>other != null</i> and at least one of the following conditions is met /// <ul> /// <li>the receiver is a view of the other matrix /// <li>the other matrix is a view of the receiver /// <li><i>this == other</i> /// </ul> /// </summary> protected new Boolean HaveSharedCellsRaw(DoubleMatrix3D other) { if (other is SelectedDenseDoubleMatrix3D) { SelectedDenseDoubleMatrix3D otherMatrix = (SelectedDenseDoubleMatrix3D)other; return(this.Elements == otherMatrix.Elements); } else if (other is DenseDoubleMatrix3D) { DenseDoubleMatrix3D otherMatrix = (DenseDoubleMatrix3D)other; return(this.Elements == otherMatrix.Elements); } return(false); }
/// <summary> /// 27 neighbor stencil transformation.For efficient finite difference operations. /// Applies a function to a moving<i>3 x 3 x 3</i> window. /// Does nothing if <i>Rows() < 3 || Columns() < 3 || Slices() < 3</i>. /// <pre> /// B[k, i, j] = function.apply( /// A[k - 1, i - 1, j - 1], A[k - 1, i - 1, j], A[k - 1, i - 1, j + 1], /// A[k - 1, i, j - 1], A[k - 1, i, j], A[k - 1, i, j + 1], /// A[k - 1, i + 1, j - 1], A[k - 1, i + 1, j], A[k - 1, i + 1, j + 1], /// /// A[k, i - 1, j - 1], A[k, i - 1, j], A[k, i - 1, j + 1], /// A[k, i, j - 1], A[k, i, j], A[k, i, j + 1], /// A[k, i + 1, j - 1], A[k, i + 1, j], A[k, i + 1, j + 1], /// /// A[k + 1, i - 1, j - 1], A[k + 1, i - 1, j], A[k + 1, i - 1, j + 1], /// A[k + 1, i, j - 1], A[k + 1, i, j], A[k + 1, i, j + 1], /// A[k + 1, i + 1, j - 1], A[k + 1, i + 1, j], A[k + 1, i + 1, j + 1] /// ) /// /// x x x - - x x x - - - - /// x o x - - x o x - - - - /// x x x - - x x x..d - x x x /// - - - - - - - - - x o x /// - - - - - - - - - x x x /// </pre> /// Make sure that cells of<i>this</i> and<i> B</i> do not overlap. /// In case of overlapping views, behaviour is unspecified. /// </pre> /// <p> /// <b>Example:</b> /// <pre> /// double alpha = 0.25; /// double beta = 0.75; /// /// cern.colt.function.Double27Function f = new cern.colt.function.Double27Function() { /// public double apply( /// double a000, double a001, double a002, /// double a010, double a011, double a012, /// double a020, double a021, double a022, /// /// double a100, double a101, double a102, /// double a110, double a111, double a112, /// double a120, double a121, double a122, /// /// double a200, double a201, double a202, /// double a210, double a211, double a212, /// double a220, double a221, double a222) { /// return beta* a111 + alpha* (a000 + ..d + a222); /// } /// }; /// A.zAssign27Neighbors(B, f); /// </pre> /// </summary> /// <param name="B">the matrix to hold the results.</param> /// <param name="function">the function to be applied to the 27 cells.</param> /// <returns></returns> /// <exception cref="NullReferenceException">if <i>function==null</i>.</exception> /// <exception cref="ArgumentException">if <i>Rows() != B.Rows() || Columns() != B.Columns() || Slices() != B.Slices() </i>.</exception> public override void ZAssign27Neighbors(DoubleMatrix3D B, Cern.Colt.Function.Double27Function function) { // overridden for performance only if (!(B is DenseDoubleMatrix3D)) { base.ZAssign27Neighbors(B, function); return; } if (function == null) { throw new NullReferenceException(Cern.LocalizedResources.Instance().Exception_FuncionMustNotBeNull); } CheckShape(B); int r = Rows - 1; int c = Columns - 1; if (Rows < 3 || Columns < 3 || Slices < 3) { return; // nothing to do } DenseDoubleMatrix3D BB = (DenseDoubleMatrix3D)B; int A_ss = SliceStride; int A_rs = RowStride; int B_rs = BB.RowStride; int A_cs = ColumnStride; int B_cs = BB.ColumnStride; double[] elems = this.Elements; double[] B_elems = BB.Elements; if (elems == null || B_elems == null) { throw new NullReferenceException(); } for (int k = 1; k < Slices - 1; k++) { int A_index = Index(k, 1, 1); int B_index = BB.Index(k, 1, 1); for (int i = 1; i < r; i++) { int A002 = A_index - A_ss - A_rs - A_cs; int A012 = A002 + A_rs; int A022 = A012 + A_rs; int A102 = A002 + A_ss; int A112 = A102 + A_rs; int A122 = A112 + A_rs; int A202 = A102 + A_ss; int A212 = A202 + A_rs; int A222 = A212 + A_rs; double a000, a001, a002; double a010, a011, a012; double a020, a021, a022; double a100, a101, a102; double a110, a111, a112; double a120, a121, a122; double a200, a201, a202; double a210, a211, a212; double a220, a221, a222; a000 = elems[A002]; A002 += A_cs; a001 = elems[A002]; a010 = elems[A012]; A012 += A_cs; a011 = elems[A012]; a020 = elems[A022]; A022 += A_cs; a021 = elems[A022]; a100 = elems[A102]; A102 += A_cs; a101 = elems[A102]; a110 = elems[A112]; A112 += A_cs; a111 = elems[A112]; a120 = elems[A122]; A122 += A_cs; a121 = elems[A122]; a200 = elems[A202]; A202 += A_cs; a201 = elems[A202]; a210 = elems[A212]; A212 += A_cs; a211 = elems[A212]; a220 = elems[A222]; A222 += A_cs; a221 = elems[A222]; int B11 = B_index; for (int j = 1; j < c; j++) { // in each step 18 cells can be remembered in registers - they don't need to be reread from slow memory // in each step 9 instead of 27 cells need to be read from memory. a002 = elems[A002 += A_cs]; a012 = elems[A012 += A_cs]; a022 = elems[A022 += A_cs]; a102 = elems[A102 += A_cs]; a112 = elems[A112 += A_cs]; a122 = elems[A122 += A_cs]; a202 = elems[A202 += A_cs]; a212 = elems[A212 += A_cs]; a222 = elems[A222 += A_cs]; B_elems[B11] = function( a000, a001, a002, a010, a011, a012, a020, a021, a022, a100, a101, a102, a110, a111, a112, a120, a121, a122, a200, a201, a202, a210, a211, a212, a220, a221, a222); B11 += B_cs; // move remembered cells a000 = a001; a001 = a002; a010 = a011; a011 = a012; a020 = a021; a021 = a022; a100 = a101; a101 = a102; a110 = a111; a111 = a112; a120 = a121; a121 = a122; a200 = a201; a201 = a202; a210 = a211; a211 = a212; a220 = a221; a221 = a222; } A_index += A_rs; B_index += B_rs; } } }