/// <summary> /// Apply filter. /// </summary> /// <param name="data">Matrix</param> public void Apply(Complex32[,] data) { // forward pyramid transform Complex32[][,] pA = lap.Forward(data); int r = data.GetLength(0), c = data.GetLength(1); int nlev = pA.Length - 1, i, j; for (i = 0; i < nlev; i++) { pA[i] = Matrice.Mul(pA[i], 1.0 + this.factor); } // backward pyramid transform Complex32[,] dummy = lap.Backward(pA); for (i = 0; i < r; i++) { for (j = 0; j < c; j++) { data[i, j] = dummy[i, j]; } } return; }
/// <summary> /// Forward Fourier transform. /// </summary> /// <param name="A">Matrix</param> /// <returns>Matrix</returns> public Complex32[,] Forward(Complex32[,] A) { int N = A.GetLength(0), M = A.GetLength(1); Complex32[,] U = FourierTransform.Matrix(N); Complex32[,] V = FourierTransform.Matrix(M); Complex32[,] B; if (direction == Direction.Both) { B = U.Dot(A).Dot(V.Hermitian()); B = normalized ? B.Div(Math.Sqrt(N * M)) : B; } else if (direction == Direction.Vertical) { B = U.Dot(A); B = normalized ? B.Div(Math.Sqrt(N)) : B; } else { B = A.Dot(V.Hermitian()); B = normalized ? B.Div(Math.Sqrt(M)) : B; } return(B); }
/// <summary> /// Backward Fourier transform. /// </summary> /// <param name="B">Matrix</param> /// <returns>Matrix</returns> public Complex32[,] Backward(Complex32[,] B) { int N = B.GetLength(0), M = B.GetLength(1); Complex32[,] U = FourierTransform.Matrix(N); Complex32[,] V = FourierTransform.Matrix(M); Complex32[,] A; if (direction == Direction.Both) { A = U.Hermitian().Dot(B).Dot(V); A = normalized ? A.Div(Math.Sqrt(N * M)) : A; } else if (direction == Direction.Vertical) { A = U.Hermitian().Dot(B); A = normalized ? A.Div(Math.Sqrt(N)) : A; } else { A = B.Dot(V); A = normalized ? A.Div(Math.Sqrt(M)) : A; } return(A); }
/// <summary> /// Apply filter. /// </summary> /// <param name="data">Matrix</param> public void Apply(Complex32[,] data) { // enhancement or not? if (this.factor != 0) { // params int l0 = data.GetLength(0); int l1 = data.GetLength(1); int i, j; // guided filter Complex32[,] copy = (Complex32[, ])data.Clone(); GuidedFilter.guidedfilter(copy, this.radius, this.eps); // process for (i = 0; i < l0; i++) { for (j = 0; j < l1; j++) { data[i, j] = (1.0 + this.factor) * (data[i, j] - copy[i, j]) + copy[i, j]; } } } return; }
/// <summary> /// Apply filter. /// </summary> /// <param name="data">Matrix</param> public void Apply(Complex32[,] data) { // enhancement or not? if (this.factor != 0) { // params int l0 = data.GetLength(0); int l1 = data.GetLength(1); int i, j; // guided filter Complex32[,] copy = (Complex32[, ])data.Clone(); DomainTransformFilter.domainfilter(copy, this.sigma_s, this.sigma_r, this.iterations); // process for (i = 0; i < l0; i++) { for (j = 0; j < l1; j++) { data[i, j] = (1.0 + this.factor) * (data[i, j] - copy[i, j]) + copy[i, j]; } } } return; }
/// <summary> /// Transformed domain recursive filter (vertical). /// </summary> /// <param name="F">Input signal</param> /// <param name="D">Difference</param> /// <param name="sigma">Sigma</param> internal static void tdrf_v(Complex32[,] F, Complex32[,] D, float sigma) { // params float a = Maths.Exp(-Maths.Sqrt2 / sigma); Complex32[,] V = Matrice.Pow(a, D); int h = F.GetLength(0); int w = F.GetLength(1); int i, j; // Left -> Right filter. for (i = 1; i < h; i++) { for (j = 0; j < w; j++) { F[i, j] = F[i, j] + V[i, j] * (F[i - 1, j] - F[i, j]); } } // Right -> Left filter. for (i = h - 2; i >= 0; i--) { for (j = 0; j < w; j++) { F[i, j] = F[i, j] + V[i + 1, j] * (F[i + 1, j] - F[i, j]); } } return; }
/// <summary> /// Determines eigenvectors by undoing the symmetric tridiagonalize transformation /// </summary> /// <param name="matrixA">Previously tridiagonalized matrix by <see cref="SymmetricTridiagonalize"/>.</param> /// <param name="tau">Contains further information about the transformations</param> /// <param name="order">Input matrix order</param> /// <remarks>This is derived from the Algol procedures HTRIBK, by /// by Smith, Boyle, Dongarra, Garbow, Ikebe, Klema, Moler, and Wilkinson, Handbook for /// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding /// Fortran subroutine in EISPACK.</remarks> static void SymmetricUntridiagonalize(Matrix <Complex32> eigenVectors, Complex32[,] matrixA, Complex32[] tau, int order) { for (var i = 0; i < order; i++) { for (var j = 0; j < order; j++) { eigenVectors.At(i, j, eigenVectors.At(i, j).Real *tau[i].Conjugate()); } } // Recover and apply the Householder matrices. for (var i = 1; i < order; i++) { var h = matrixA[i, i].Imaginary; if (h != 0) { for (var j = 0; j < order; j++) { var s = Complex32.Zero; for (var k = 0; k < i; k++) { s += eigenVectors.At(k, j) * matrixA[i, k]; } s = (s / h) / h; for (var k = 0; k < i; k++) { eigenVectors.At(k, j, eigenVectors.At(k, j) - s * matrixA[i, k].Conjugate()); } } } } }
/// <summary> /// Apply filter. /// </summary> /// <param name="data">Matrix</param> public void Apply(Complex32[,] data) { int height = data.GetLength(0); int width = data.GetLength(1); int hh = height >> 1; int hw = width >> 1; int min = frequencyRange.Min; int max = frequencyRange.Max; int i, j, x, y, d; for (i = 0; i < height; i++) { y = i - hh; for (j = 0; j < width; j++) { x = j - hw; d = (int)Math.Sqrt(x * x + y * y); if ((d > max) || (d < min)) { data[i, j].Real = 0; data[i, j].Imag = 0; } } } return; }
/// <summary> /// Backward wavelet decomposition. /// </summary> /// <param name="B">Matrix</param> /// <returns>Matrix</returns> public Complex32[,] Backward(Complex32[][,] B) { // params int nLevels = B.Length; Complex32[,] A = B[nLevels - 1]; // backward multi-scale wavelet decomposition for (int i = nLevels - 2; i >= 0; i--) { var b = B[i]; var col = b.GetLength(0); var row = b.GetLength(1); for (int y = 0; y < col; y++) { for (int x = 0; x < row; x++) { A[y, x] = b[y, x]; } } } return(WaveletTransform.Backward(A)); }
/// <summary> /// Determines eigenvectors by undoing the symmetric tridiagonalize transformation /// </summary> /// <param name="dataEv">Data array of matrix V (eigenvectors)</param> /// <param name="matrixA">Previously tridiagonalized matrix by <see cref="SymmetricTridiagonalize"/>.</param> /// <param name="tau">Contains further information about the transformations</param> /// <param name="order">Input matrix order</param> /// <remarks>This is derived from the Algol procedures HTRIBK, by /// by Smith, Boyle, Dongarra, Garbow, Ikebe, Klema, Moler, and Wilkinson, Handbook for /// Auto. Comp., Vol.ii-Linear Algebra, and the corresponding /// Fortran subroutine in EISPACK.</remarks> private static void SymmetricUntridiagonalize(Complex32[] dataEv, Complex32[,] matrixA, Complex32[] tau, int order) { for (var i = 0; i < order; i++) { for (var j = 0; j < order; j++) { dataEv[(j * order) + i] = dataEv[(j * order) + i].Real * tau[i].Conjugate(); } } // Recover and apply the Householder matrices. for (var i = 1; i < order; i++) { var h = matrixA[i, i].Imaginary; if (h != 0) { for (var j = 0; j < order; j++) { var s = Complex32.Zero; for (var k = 0; k < i; k++) { s += dataEv[(j * order) + k] * matrixA[i, k]; } s = (s / h) / h; for (var k = 0; k < i; k++) { dataEv[(j * order) + k] -= s * matrixA[i, k].Conjugate(); } } } } }
/// <summary> /// Forward wavelet decomposition. /// </summary> /// <param name="A">Matrix</param> /// <returns>Matrix</returns> public Complex32[][,] Forward(Complex32[,] A) { // params int N = A.GetLength(0); int M = A.GetLength(1); int nLevels = (int)Math.Min(Math.Min(Maths.Log2(N), WaveletTransform.Levels), M); Complex32[,] B = WaveletTransform.Forward(A); Complex32[][,] C = new Complex32[nLevels + 1][, ]; // forward multi-scale wavelet decomposition for (int i = 0, k1 = 0, k2 = 0; i <= nLevels; i++) { var bound1 = N >> (nLevels - i); var bound2 = M >> (nLevels - i); var count1 = bound1 - k1; var count2 = bound2 - k2; C[i] = new Complex32[count1, count2]; for (int y = 0; y < count1; y++) { for (int x = 0; x < count2; x++) { C[i][y, x] = B[y + k1, x + k2]; B[y + k1, x + k2] = 0; } } //k1 = bound1; // not actual for 2D decomposition //k2 = bound2; } return(C); }
/// <summary> /// Backward Walsh-Hadamard transform. /// </summary> /// <param name="B">Matrix</param> /// <returns>Matrix</returns> public Complex32[,] Backward(Complex32[,] B) { int N = B.GetLength(0), M = B.GetLength(1); if (!Maths.IsPower(N, 2) || !Maths.IsPower(M, 2)) { throw new Exception("Dimension of the signal must be a power of 2"); } float[,] U = WalshHadamardTransform.Matrix((int)Maths.Log2(N)); float[,] V = WalshHadamardTransform.Matrix((int)Maths.Log2(M)); Complex32[,] A; if (direction == Direction.Both) { A = U.Transponate().Dot(B).Dot(V); A = normalized ? A.Div(Math.Sqrt(N * M)) : A; } else if (direction == Direction.Vertical) { A = U.Transponate().Dot(B); A = normalized ? A.Div(Math.Sqrt(N)) : A; } else { A = B.Dot(V); A = normalized ? A.Div(Math.Sqrt(M)) : A; } return(A); }
/// <summary> /// Backward Weyl-Heisenberg transform. /// </summary> /// <param name="B">Array</param> /// <returns>Array</returns> public Complex32[] Backward(Complex32[] B) { int N = B.Length; Complex32[,] U = WeylHeisenbergTransform.Matrix(this.window, N, this.m, true); Complex32[] A = Matrice.Dot(B, U); return(A); }
/// <summary> /// Forward Weyl-Heisenberg transform. /// </summary> /// <param name="A">Array</param> /// <returns>Array</returns> public Complex32[] Forward(Complex32[] A) { int N = A.Length; Complex32[,] U = WeylHeisenbergTransform.Matrix(this.window, N, this.m, true); Complex32[] B = Matrice.Dot(A, U.Hermitian()); return(B); }
/// <summary> /// Forward wavelet transform. /// </summary> /// <param name="A">Matrix</param> /// <returns>Matrix</returns> public Complex32[,] Forward(Complex32[,] A) { // params int Bound1, Bound2, i, j; int DataLen1 = A.GetLength(0); int DataLen2 = A.GetLength(1); Complex32[,] output = (Complex32[, ])A.Clone(); Complex32[] buff2 = new Complex32[DataLen2]; Complex32[] buff1 = new Complex32[DataLen1]; int nLevels = (int)Math.Min(Math.Min(Maths.Log2(DataLen1), this.levels), DataLen2); // do job for (int lev = 0; lev < nLevels; lev++) { Bound1 = DataLen1 >> lev; Bound2 = DataLen2 >> lev; if (!Maths.IsEven(Bound1) && Bound1 < DataLen1) { Bound1--; } if (!Maths.IsEven(Bound2) && Bound2 < DataLen2) { Bound2--; } for (i = 0; i < Bound1; i++) { for (j = 0; j < Bound2; j++) { buff2[j] = output[i, j]; } buff2 = this.dwt(buff2, lev); for (j = 0; j < Bound2; j++) { output[i, j] = buff2[j]; } } for (j = 0; j < Bound2; j++) { for (i = 0; i < Bound1; i++) { buff1[i] = output[i, j]; } buff1 = this.dwt(buff1, lev); for (i = 0; i < Bound1; i++) { output[i, j] = buff1[i]; } } } return(output); }
/// <summary> /// Apply filter. /// </summary> /// <param name="data">Matrix</param> public void Apply(Complex32[,] data) { int width = data.GetLength(1); int height = data.GetLength(0); int i, j; if (this.type == ThresholdType.Abs) { for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { if (Maths.Abs(data[i, j]) < threshold) { data[i, j] = 0; } } } } else if (this.type == ThresholdType.Over) { for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { if (data[i, j].Real > threshold) { data[i, j] = 0; } if (data[i, j].Imag > threshold) { data[i, j] = 0; } } } } else { for (i = 0; i < height; i++) { for (j = 0; j < width; j++) { if (data[i, j].Real < threshold) { data[i, j] = 0; } if (data[i, j].Imag < threshold) { data[i, j] = 0; } } } } return; }
/// <summary> /// Domain transform filter. /// </summary> /// <param name="I">Input signal</param> /// <param name="sigma_s">High sigma</param> /// <param name="sigma_r">Low sigma</param> /// <param name="iterations">Number of iterations</param> internal static void domainfilter(Complex32[,] I, float sigma_s, float sigma_r, int iterations = 3) { // params int h = I.GetLength(0); int w = I.GetLength(1); float sigma_H_i; int i, j; // get differences Complex32[,] dIcdx = Matrice.Diff(I, 1, Direction.Horizontal); Complex32[,] dIcdy = Matrice.Diff(I, 1, Direction.Vertical); // shift patterns Complex32[,] dIdx = new Complex32[h, w]; Complex32[,] dIdy = new Complex32[h, w]; for (i = 0; i < h; i++) { for (j = 1; j < w; j++) { dIdx[i, j] = Maths.Abs(dIcdx[i, j - 1]); } } for (i = 1; i < h; i++) { for (j = 0; j < w; j++) { dIdy[i, j] = Maths.Abs(dIcdy[i - 1, j]); } } // sigma patterns and result image for (i = 0; i < h; i++) { for (j = 0; j < w; j++) { dIdx[i, j] = 1 + sigma_s / sigma_r * dIdx[i, j]; dIdy[i, j] = 1 + sigma_s / sigma_r * dIdy[i, j]; } } // iterations for (i = 0; i < iterations; i++) { sigma_H_i = sigma_s * Maths.Sqrt(3) * Maths.Pow(2, (iterations - (i + 1))) / Maths.Sqrt(Maths.Pow(4, iterations) - 1); // 2D filter tdrf_h(I, dIdx, sigma_H_i); tdrf_v(I, dIdy, sigma_H_i); } return; }
/// <summary> /// Initializes a new instance of the <see cref="DenseMatrix"/> class from a 2D array. This constructor /// will allocate a completely new memory block for storing the dense matrix. /// </summary> /// <param name="array">The 2D array to create this matrix from.</param> public DenseMatrix(Complex32[,] array) : this(array.GetLength(0), array.GetLength(1)) { for (var i = 0; i < _rowCount; i++) { for (var j = 0; j < _columnCount; j++) { _data[(j * _rowCount) + i] = array[i, j]; } } }
/// <summary> /// Backward Laplacian pyramid transform. /// </summary> /// <param name="pyramid">Pyramid</param> /// <returns>Matrix</returns> public Complex32[,] Backward(Complex32[][,] pyramid) { int nlev = pyramid.Length - 1; Complex32[,] I = pyramid[nlev]; for (int i = nlev - 1; i >= 0; i--) { I = GaussianPyramidTransform.add(pyramid[i], GaussianPyramidTransform.upsample(I, this.radius)); } return(I); }
/// <summary> /// Guided filer function. /// </summary> /// <param name="input">Input signal</param> /// <param name="r">Filter size</param> /// <param name="eps">Epsilon (0, 1)</param> internal static void guidedfilter(Complex32[,] input, int r, float eps) { // Input signal properties: int l0 = input.GetLength(0), l1 = input.GetLength(1), i, j; // Calculating μ(I) and μ(I^2): Complex32[,] x = (Complex32[, ])input.Clone(); Complex32[,] y = Matrice.Pow(input, 2.0f); // Applying fast box filter: x = x.Mean(r, r); y = y.Mean(r, r); // Calculating cov(I): // This is the covariance of input in each local patch: Complex32[,] c = new Complex32[l0, l1]; for (i = 0; i < l0; i++) { for (j = 0; j < l1; j++) { c[i, j] = y[i, j] - x[i, j] * x[i, j]; } } // Calculating μ(a) and μ(b): Complex32[,] a = new Complex32[l0, l1]; Complex32[,] b = new Complex32[l0, l1]; for (i = 0; i < l0; i++) { for (j = 0; j < l1; j++) { a[i, j] = c[i, j] / (c[i, j] + eps); b[i, j] = x[i, j] - a[i, j] * x[i, j]; } } // Applying fast box filter: a = a.Mean(r, r); b = b.Mean(r, r); // Calculating μ(a) * I + μ(b): for (i = 0; i < l0; i++) { for (j = 0; j < l1; j++) { input[i, j] = a[i, j] * input[i, j] + b[i, j]; } } return; }
/// <summary> /// Initializes a new instance of the <see cref="DenseMatrix"/> class from a 2D array. This constructor /// will allocate a completely new memory block for storing the dense matrix. /// </summary> /// <param name="array">The 2D array to create this matrix from.</param> public DenseMatrix(Complex32[,] array) : base(array.GetLength(0), array.GetLength(1)) { _rowCount = array.GetLength(0); _columnCount = array.GetLength(1); Data = new Complex32[_rowCount * _columnCount]; for (var i = 0; i < _rowCount; i++) { for (var j = 0; j < _columnCount; j++) { Data[(j * _rowCount) + i] = array[i, j]; } } }
/// <summary> /// Forward Fourier transform. /// </summary> /// <param name="A">Array</param> /// <returns>Array</returns> public Complex32[] Forward(Complex32[] A) { int N = A.Length; Complex32[,] U = FourierTransform.Matrix(N); Complex32[] B = Matrice.Dot(A, U); if (normalized) { B = Matrice.Div(B, Math.Sqrt(N)); } return(B); }
/// <summary> /// Backward Fourier transform. /// </summary> /// <param name="B">Array</param> /// <returns>Array</returns> public Complex32[] Backward(Complex32[] B) { int N = B.Length; Complex32[,] U = FourierTransform.Matrix(N); Complex32[] A = Matrice.Dot(B, U.Hermitian()); if (normalized) { A = Matrice.Div(A, Math.Sqrt(N)); } return(A); }
/// <summary> /// Implements a wavelet filter. /// </summary> /// <param name="data">Matrix</param> public void Apply(Complex32[,] data) { var B = WaveletDecomposition.Forward(data); int n, m; for (int i = 1; i < B.Length; i++) { var b = B[i]; n = b.GetLength(0); m = b.GetLength(1); if (!Maths.IsEven(n)) { n--; // ? } if (!Maths.IsEven(m)) { m--; // ? } // visu_shrink var bb = Matrice.Reshape(b, b.Length).ToAbs(); Array.Sort(bb); var median = Math.Sqrt(bb[bb.Length / 2]) * Math.Sqrt(Maths.Log2(n * m)); for (int y = 0; y < n; y++) { for (int x = 0; x < m; x++) { b[y, x] = Maths.Abs(b[y, x]) > median ? b[y, x] : 0; } } B[i] = b; } var output = WaveletDecomposition.Backward(B); float factor = 1 + Factor; n = data.GetLength(0); m = data.GetLength(1); for (int y = 0; y < n; y++) { for (int x = 0; x < m; x++) { // pass filtering data[y, x] = output[y, x] + factor * (data[y, x] - output[y, x]); } } }
/// <summary> /// Initializes a new instance of the <see cref="DenseMatrix"/> class from a 2D array. This constructor /// will allocate a completely new memory block for storing the dense matrix. /// </summary> /// <param name="array">The 2D array to create this matrix from.</param> public DenseMatrix(Complex32[,] array) : base(array.GetLength(0), array.GetLength(1)) { var rows = array.GetLength(0); var columns = array.GetLength(1); Data = new Complex32[rows * columns]; for (var i = 0; i < rows; i++) { for (var j = 0; j < columns; j++) { Data[(j * rows) + i] = array[i, j]; } } }
/// <summary> /// Backward wavelet transform. /// </summary> /// <param name="B">Matrix</param> /// <returns>Matrix</returns> public Complex32[,] Backward(Complex32[,] B) { // params int Bound1, Bound2, i, j; int DataLen1 = B.GetLength(0); int DataLen2 = B.GetLength(1); Complex32[,] output = (Complex32[, ])B.Clone(); Complex32[] buff1 = new Complex32[DataLen1]; Complex32[] buff2 = new Complex32[DataLen2]; int nLevels = (int)Math.Min(Math.Min(Maths.Log2(DataLen1), this.levels), DataLen2); // do job for (int lev = nLevels; lev > 0; lev--) { Bound1 = DataLen1 >> lev; Bound2 = DataLen2 >> lev; for (i = 0; i < Bound1 << 1; i++) { for (j = 0; j < Bound2 << 1; j++) { buff2[j] = output[i, j]; } buff2 = this.idwt(buff2, lev); for (j = 0; j < Bound2 << 1; j++) { output[i, j] = buff2[j]; } } for (j = 0; j < Bound2 << 1; j++) { for (i = 0; i < Bound1 << 1; i++) { buff1[i] = output[i, j]; } buff1 = this.idwt(buff1, lev); for (i = 0; i < Bound1 << 1; i++) { output[i, j] = buff1[i]; } } } return(output); }
/// <summary> /// /// </summary> /// <param name="m">Matrix</param> /// <param name="n">Matrix</param> /// <returns>Matrix</returns> internal static Complex32[,] sub(Complex32[,] m, Complex32[,] n) { int ml = (int)Math.Min(m.GetLength(0), n.GetLength(0)); int mr = (int)Math.Min(m.GetLength(1), n.GetLength(1)); Complex32[,] H = new Complex32[ml, mr]; int i, j; for (i = 0; i < ml; i++) { for (j = 0; j < mr; j++) { H[i, j] = m[i, j] - n[i, j]; } } return(H); }
/// <summary> /// Forward Gaussian pyramid transform. /// </summary> /// <param name="data">Matrix</param> /// <returns>Pyramid</returns> public Complex32[][,] Forward(Complex32[,] data) { int r = data.GetLength(0), c = data.GetLength(1); int nlev = (int)Math.Min((Math.Log(Math.Min(r, c)) / Math.Log(2)), levels); Complex32[][,] pyr = new Complex32[nlev][, ]; Complex32[,] dummy = (Complex32[, ])data.Clone(); for (int i = 0; i < nlev; i++) { pyr[i] = dummy; dummy = downsample(dummy, this.radius); } return(pyr); }
/// <summary> /// Backward sine transform. /// </summary> /// <param name="B">Matrix</param> /// <returns>Matrix</returns> public Complex32[,] Backward(Complex32[,] B) { int N = B.GetLength(0), M = B.GetLength(1); float[,] U = SineTransform.Matrix(N); float[,] V = SineTransform.Matrix(M); if (direction == Direction.Both) { return(U.Transponate().Dot(B).Dot(V)); } else if (direction == Direction.Vertical) { return(U.Transponate().Dot(B)); } return(B.Dot(V)); }
/// <summary> /// Forward sine transform. /// </summary> /// <param name="A">Matrix</param> /// <returns>Matrix</returns> public Complex32[,] Forward(Complex32[,] A) { int N = A.GetLength(0), M = A.GetLength(1); float[,] U = SineTransform.Matrix(N); float[,] V = SineTransform.Matrix(M); if (direction == Direction.Both) { return(U.Dot(A).Dot(V.Transponate())); } else if (direction == Direction.Vertical) { return(U.Dot(A)); } return(A.Dot(V.Transponate())); }
/// <summary> /// Initializes a new instance of the <see cref="UserDefinedMatrix"/> class. This matrix is square with a given size. /// </summary> /// <param name="order">the size of the square matrix.</param> public UserDefinedMatrix(int order) : base(order, order) { _data = new Complex32[order, order]; }
/// <summary> /// Initializes a new instance of the <see cref="UserDefinedMatrix"/> class. /// </summary> /// <param name="rows">The number of rows.</param> /// <param name="columns">The number of columns.</param> public UserDefinedMatrix(int rows, int columns) : base(rows, columns) { _data = new Complex32[rows, columns]; }
/// <summary> /// Initializes a new instance of the <see cref="UserDefinedMatrix"/> class from a 2D array. /// </summary> /// <param name="data">The 2D array to create this matrix from.</param> public UserDefinedMatrix(Complex32[,] data) : base(data.GetLength(0), data.GetLength(1)) { _data = (Complex32[,])data.Clone(); }