public static double Compute(Complex a, Complex b) { Complex temp = a * ComplexMath.Conjugate(a); temp += (b * ComplexMath.Conjugate(b)); double ret = ComplexMath.Absolute(temp); return(System.Math.Sqrt(ret)); }
public static float Compute(ComplexFloat a, ComplexFloat b) { ComplexFloat temp = a * ComplexMath.Conjugate(a); temp += (b * ComplexMath.Conjugate(b)); float ret = ComplexMath.Absolute(temp); return((float)System.Math.Sqrt(ret)); }
public void SquareDecomp() { ComplexFloatMatrix a = new ComplexFloatMatrix(3); a[0, 0] = new ComplexFloat(1.1f, 1.1f); a[0, 1] = new ComplexFloat(2.2f, -2.2f); a[0, 2] = new ComplexFloat(3.3f, 3.3f); a[1, 0] = new ComplexFloat(4.4f, -4.4f); a[1, 1] = new ComplexFloat(5.5f, 5.5f); a[1, 2] = new ComplexFloat(6.6f, -6.6f); a[2, 0] = new ComplexFloat(7.7f, 7.7f); a[2, 1] = new ComplexFloat(8.8f, -8.8f); a[2, 2] = new ComplexFloat(9.9f, 9.9f); ComplexFloatQRDecomp qrd = new ComplexFloatQRDecomp(a); ComplexFloatMatrix qq = qrd.Q.GetConjugateTranspose() * qrd.Q; ComplexFloatMatrix qr = qrd.Q * qrd.R; ComplexFloatMatrix I = ComplexFloatMatrix.CreateIdentity(3); // determine the maximum relative error double MaxError = 0.0; for (int i = 0; i < 3; i++) { for (int j = 0; i < 3; i++) { double E = ComplexMath.Absolute((qq[i, j] - I[i, j])); if (E > MaxError) { MaxError = E; } } } Assert.IsTrue(MaxError < 1.0E-6); MaxError = 0.0; for (int i = 0; i < 3; i++) { for (int j = 0; i < 3; i++) { double E = ComplexMath.Absolute((qr[i, j] - a[i, j]) / a[i, j]); if (E > MaxError) { MaxError = E; } } } Assert.IsTrue(MaxError < 2.4E-6); }
public static ComplexDoubleVector GenerateRow(IComplexDoubleMatrix A, int r, int c1, int c2) { int cu = c2 - c1 + 1; ComplexDoubleVector u = new ComplexDoubleVector(cu); for (int j = c1; j <= c2; j++) { u[j - c1] = A[r, j]; A[r, j] = Complex.Zero; } double norm = u.GetNorm(); if (c1 == c2 || norm == 0) { A[r, c1] = new Complex(-u[0].Real, -u[0].Imag); u[0] = System.Math.Sqrt(2); return(u); } Complex scale = new Complex(1 / norm); Complex t = Complex.Zero; Complex t1 = Complex.Zero; if (u[0].Real != 0 || u[0].Imag != 0) { t = u[0]; t1 = ComplexMath.Conjugate(u[0]); t = ComplexMath.Absolute(t); t = t1 / t; scale = scale * t; } A[r, c1] = -Complex.One / scale; for (int j = 0; j < cu; j++) { u[j] *= scale; } u[0] = new Complex(u[0].Real + 1); double s = System.Math.Sqrt(1 / u[0].Real); for (int j = 0; j < cu; j++) { u[j] = new Complex(s * u[j].Real, -s * u[j].Imag); } return(u); }
///<summary>Compute the Infinity Norm of this <c>ComplexFloatVector</c></summary> ///<returns><c>float</c> results from norm.</returns> public float GetInfinityNorm() { float ret = 0; for (int i = 0; i < data.Length; i++) { float tmp = ComplexMath.Absolute(data[i]); if (tmp > ret) { ret = tmp; } } return(ret); }
public static ComplexFloatVector GenerateColumn(IComplexFloatMatrix A, int r1, int r2, int c) { int ru = r2 - r1 + 1; ComplexFloatVector u = new ComplexFloatVector(r2 - r1 + 1); for (int i = r1; i <= r2; i++) { u[i - r1] = A[i, c]; A[i, c] = ComplexFloat.Zero; } float norm = u.GetNorm(); if (r1 == r2 || norm == 0) { A[r1, c] = new ComplexFloat(-u[0]); u[0] = (float)System.Math.Sqrt(2); return(u); } ComplexFloat scale = new ComplexFloat(1 / norm, 0); ComplexFloat t = ComplexFloat.Zero; ComplexFloat t1 = ComplexFloat.Zero; if (u[0].Real != 0 || u[0].Imag != 0) { t = u[0]; t1 = ComplexMath.Conjugate(u[0]); t = ComplexMath.Absolute(t); t = t1 / t; scale = scale * t; } A[r1, c] = -ComplexFloat.One / scale; for (int i = 0; i < ru; i++) { u[i] = u[i] * scale; } u[0] = new ComplexFloat(u[0].Real + 1, 0); float s = (float)System.Math.Sqrt(1 / u[0].Real); for (int i = 0; i < ru; i++) { u[i] = new ComplexFloat(s * u[i].Real, s * u[i].Imag); } return(u); }
public void SquareDecomp() { ComplexDoubleMatrix a = new ComplexDoubleMatrix(3); a[0, 0] = new Complex(1.1, 1.1); a[0, 1] = new Complex(2.2, -2.2); a[0, 2] = new Complex(3.3, 3.3); a[1, 0] = new Complex(4.4, -4.4); a[1, 1] = new Complex(5.5, 5.5); a[1, 2] = new Complex(6.6, -6.6); a[2, 0] = new Complex(7.7, 7.7); a[2, 1] = new Complex(8.8, -8.8); a[2, 2] = new Complex(9.9, 9.9); ComplexDoubleQRDecomp qrd = new ComplexDoubleQRDecomp(a); ComplexDoubleMatrix qq = qrd.Q.GetConjugateTranspose() * qrd.Q; ComplexDoubleMatrix qr = qrd.Q * qrd.R; ComplexDoubleMatrix I = ComplexDoubleMatrix.CreateIdentity(3); // determine the maximum relative error double MaxError = 0.0; for (int i = 0; i < 3; i++) { for (int j = 0; i < 3; i++) { double E = ComplexMath.Absolute((qq[i, j] - I[i, j])); if (E > MaxError) { MaxError = E; } } } Assert.IsTrue(MaxError < 1.0E-14); MaxError = 0.0; for (int i = 0; i < 3; i++) { for (int j = 0; i < 3; i++) { double E = ComplexMath.Absolute((qr[i, j] - a[i, j]) / a[i, j]); if (E > MaxError) { MaxError = E; } } } Assert.IsTrue(MaxError < 1.0E-14); }
///<summary>Compute the P Norm of this <c>ComplexFloatVector</c></summary> ///<returns><c>float</c> results from norm.</returns> ///<remarks>p > 0, if p < 0, ABS(p) is used. If p = 0, the infinity norm is returned.</remarks> public float GetNorm(double p) { if (p == 0) { return(GetInfinityNorm()); } if (p < 0) { p = -p; } double ret = 0; for (int i = 0; i < data.Length; i++) { ret += System.Math.Pow(ComplexMath.Absolute(data[i]), p); } return((float)System.Math.Pow(ret, 1 / p)); }
public void Test() { DoubleMatrix test = svd.U * svd.W * svd.V.GetTranspose(); double e; double me = 0; for (int i = 0; i < test.RowLength; i++) { for (int j = 0; j < test.ColumnLength; j++) { e = ComplexMath.Absolute((a[i, j] - test[i, j]) / a[i, j]); if (e > me) { me = e; } } } Assert.IsTrue(me < TOLERENCE, "Maximum Error = " + me.ToString()); }
public void WTest() { FloatMatrix test = wsvd.U * wsvd.W * wsvd.V.GetTranspose(); float e; float me = 0; for (int i = 0; i < test.RowLength; i++) { for (int j = 0; j < test.ColumnLength; j++) { e = ComplexMath.Absolute((wa[i, j] - test[i, j]) / wa[i, j]); if (e > me) { me = e; } } } Assert.IsTrue(me < TOLERENCE, "Maximum Error = " + me.ToString()); }
internal static double Compute(int n, Complex[] X, int incx) { ArgumentCheck(n, X, X.Length, ref incx); double ret = 0; #if MANAGED var temp = new Complex(0); int ix = 0; for (int i = 0; i < n; ++i) { temp += (X[ix] * ComplexMath.Conjugate(X[ix])); ix += incx; } ret = System.Math.Sqrt(ComplexMath.Absolute(temp)); #else ret = dna_blas_dznrm2(n, X, incx); #endif return(ret); }
internal static float Compute(int n, ComplexFloat[] X, int incx) { ArgumentCheck(n, X, X.Length, ref incx); float ret = 0; #if MANAGED ComplexFloat temp = new ComplexFloat(0); int ix = 0; for (int i = 0; i < n; ++i) { temp += (X[ix] * ComplexMath.Conjugate(X[ix])); ix += incx; } ret = (float)System.Math.Sqrt(ComplexMath.Absolute(temp)); #else ret = dna_blas_scnrm2(n, X, incx); #endif return(ret); }
public void Absolute() { Complex cd1 = new Complex(1.1, -2.2); Complex cd2 = new Complex(0, -2.2); Complex cd3 = new Complex(1.1, 0); Complex cd4 = new Complex(-1.1, 2.2); ComplexFloat cf1 = new ComplexFloat(1.1f, -2.2f); ComplexFloat cf2 = new ComplexFloat(0, -2.2f); ComplexFloat cf3 = new ComplexFloat(1.1f, 0); ComplexFloat cf4 = new ComplexFloat(-1.1f, 2.2f); Assert.AreEqual(ComplexMath.Absolute(cd1), 2.460, TOLERENCE); Assert.AreEqual(ComplexMath.Absolute(cd2), 2.2, TOLERENCE); Assert.AreEqual(ComplexMath.Absolute(cd3), 1.1, TOLERENCE); Assert.AreEqual(ComplexMath.Absolute(cd4), 2.460, TOLERENCE); Assert.AreEqual(ComplexMath.Absolute(cf1), 2.460, TOLERENCE); Assert.AreEqual(ComplexMath.Absolute(cf2), 2.2, TOLERENCE); Assert.AreEqual(ComplexMath.Absolute(cf3), 1.1, TOLERENCE); Assert.AreEqual(ComplexMath.Absolute(cf4), 2.460, TOLERENCE); }
private static ComplexFloat csign(ComplexFloat z1, ComplexFloat z2) { ComplexFloat ret = ComplexMath.Absolute(z1) * (z2 / ComplexMath.Absolute(z2)); return(ret); }
/// <summary>Performs the LU factorization.</summary> protected override void InternalCompute() { #if MANAGED factor = new ComplexDoubleMatrix(matrix).data; int m = matrix.RowLength; int n = matrix.ColumnLength; pivots = new int[m]; for (int i = 0; i < m; i++) { pivots[i] = i; } sign = 1; Complex[] LUrowi; Complex[] LUcolj = new Complex[m]; // Outer loop. for (int j = 0; j < n; j++) { // Make a copy of the j-th column to localize references. for (int i = 0; i < m; i++) { LUcolj[i] = factor[i][j]; } // Apply previous transformations. for (int i = 0; i < m; i++) { LUrowi = factor[i]; // Most of the time is spent in the following dot product. int kmax = System.Math.Min(i, j); Complex s = Complex.Zero; for (int k = 0; k < kmax; k++) { s += LUrowi[k] * LUcolj[k]; } LUrowi[j] = LUcolj[i] -= s; } // Find pivot and exchange if necessary. int p = j; for (int i = j + 1; i < m; i++) { if (ComplexMath.Absolute(LUcolj[i]) > ComplexMath.Absolute(LUcolj[p])) { p = i; } } if (p != j) { for (int k = 0; k < n; k++) { Complex t = factor[p][k]; factor[p][k] = factor[j][k]; factor[j][k] = t; } int r = pivots[p]; pivots[p] = pivots[j]; pivots[j] = r; sign = -sign; } // Compute multipliers. if (j < m & factor[j][j] != Complex.Zero) { for (int i = j + 1; i < m; i++) { factor[i][j] /= factor[j][j]; } } } #else factor = new Complex[matrix.data.Length]; Array.Copy(matrix.data, factor, matrix.data.Length); Lapack.Getrf.Compute(order, order, factor, order, out pivots); GetSign(); #endif SetLU(); this.singular = false; for (int j = 0; j < u.RowLength; j++) { if (u[j, j] == 0) { this.singular = true; break; } } }
///<summary>Computes the algorithm.</summary> protected override void InternalCompute() { rows = matrix.RowLength; cols = matrix.ColumnLength; int mm = System.Math.Min(rows + 1, cols); s = new DoubleVector(mm); // singular values #if MANAGED // Derived from LINPACK code. // Initialize. u = new DoubleMatrix(rows, rows); // left vectors v = new DoubleMatrix(cols, cols); // right vectors DoubleVector e = new DoubleVector(cols); DoubleVector work = new DoubleVector(rows); int i, iter, j, k, kase, l, lp1, ls = 0, lu, m, nct, nctp1, ncu, nrt, nrtp1; double b, c, cs = 0.0, el, emm1, f, g, scale, shift, sl, sm, sn = 0.0, smm1, t1, test, ztest, xnorm, enorm; double t, r; ncu = rows; // reduce matrix to bidiagonal form, storing the diagonal elements // in s and the super-diagonal elements in e. int info = 0; nct = System.Math.Min(rows - 1, cols); nrt = System.Math.Max(0, System.Math.Min(cols - 2, rows)); lu = System.Math.Max(nct, nrt); for (l = 0; l < lu; l++) { lp1 = l + 1; if (l < nct) { // compute the transformation for the l-th column and // place the l-th diagonal in s[l]. xnorm = dnrm2Column(matrix, l, l); s[l] = xnorm; if (s[l] != 0.0) { if (matrix[l, l] != 0.0) { s[l] = dsign(s[l], matrix[l, l]); } dscalColumn(matrix, l, l, 1.0 / s[l]); matrix[l, l] = 1.0 + matrix[l, l]; } s[l] = -s[l]; } for (j = lp1; j < cols; j++) { if (l < nct) { if (s[l] != 0.0) { // apply the transformation. t = -ddot(matrix, l, j, l) / matrix[l, l]; for (int ii = l; ii < matrix.RowLength; ii++) { matrix[ii, j] += t * matrix[ii, l]; } } } //place the l-th row of matrix into e for the //subsequent calculation of the row transformation. e[j] = matrix[l, j]; } if (computeVectors && l < nct) { // place the transformation in u for subsequent back multiplication. for (i = l; i < rows; i++) { u[i, l] = matrix[i, l]; } } if (l < nrt) { // compute the l-th row transformation and place the l-th super-diagonal in e(l). enorm = dnrm2Vector(e, lp1); e[l] = enorm; if (e[l] != 0.0) { if (e[lp1] != 0.0) { e[l] = dsign(e[l], e[lp1]); } dscalVector(e, lp1, 1.0 / e[l]); e[lp1] = 1.0 + e[lp1]; } e[l] = -e[l]; if (lp1 < rows && e[l] != 0.0) { // apply the transformation. for (i = lp1; i < rows; i++) { work[i] = 0.0; } for (j = lp1; j < cols; j++) { for (int ii = lp1; ii < matrix.RowLength; ii++) { work[ii] += e[j] * matrix[ii, j]; } } for (j = lp1; j < cols; j++) { double ww = -e[j] / e[lp1]; for (int ii = lp1; ii < matrix.RowLength; ii++) { matrix[ii, j] += ww * work[ii]; } } } if (computeVectors) { // place the transformation in v for subsequent back multiplication. for (i = lp1; i < cols; i++) { v[i, l] = e[i]; } } } } // set up the final bidiagonal matrix or order m. m = System.Math.Min(cols, rows + 1); nctp1 = nct + 1; nrtp1 = nrt + 1; if (nct < cols) { s[nctp1 - 1] = matrix[nctp1 - 1, nctp1 - 1]; } if (rows < m) { s[m - 1] = 0.0; } if (nrtp1 < m) { e[nrtp1 - 1] = matrix[nrtp1 - 1, m - 1]; } e[m - 1] = 0.0; // if required, generate u. if (computeVectors) { for (j = nctp1 - 1; j < ncu; j++) { for (i = 0; i < rows; i++) { u[i, j] = 0.0; } u[j, j] = 1.0; } for (l = nct - 1; l >= 0; l--) { if (s[l] != 0.0) { for (j = l + 1; j < ncu; j++) { t = -ddot(u, l, j, l) / u[l, l]; for (int ii = l; ii < u.RowLength; ii++) { u[ii, j] += t * u[ii, l]; } } dscalColumn(u, l, l, -1.0); u[l, l] = 1.0 + u[l, l]; for (i = 0; i < l; i++) { u[i, l] = 0.0; } } else { for (i = 0; i < rows; i++) { u[i, l] = 0.0; } u[l, l] = 1.0; } } } // if it is required, generate v. if (computeVectors) { for (l = cols - 1; l >= 0; l--) { lp1 = l + 1; if (l < nrt) { if (e[l] != 0.0) { for (j = lp1; j < cols; j++) { t = -ddot(v, l, j, lp1) / v[lp1, l]; for (int ii = l; ii < v.RowLength; ii++) { v[ii, j] += t * v[ii, l]; } } } } for (i = 0; i < cols; i++) { v[i, l] = 0.0; } v[l, l] = 1.0; } } // transform s and e so that they are double . for (i = 0; i < m; i++) { if (s[i] != 0.0) { t = s[i]; r = s[i] / t; s[i] = t; if (i < m - 1) { e[i] = e[i] / r; } if (computeVectors) { dscalColumn(u, i, 0, r); } } // ...exit if (i == m - 1) { break; } if (e[i] != 0.0) { t = e[i]; r = t / e[i]; e[i] = t; s[i + 1] = s[i + 1] * r; if (computeVectors) { dscalColumn(v, i + 1, 0, r); } } } // main iteration loop for the singular values. mm = m; iter = 0; while (m > 0) { // quit if all the singular values have been found. // if too many iterations have been performed, set // flag and return. if (iter >= MAXITER) { info = m; // ......exit break; } // this section of the program inspects for // negligible elements in the s and e arrays. on // completion the variables kase and l are set as follows. // kase = 1 if s[m] and e[l-1] are negligible and l < m // kase = 2 if s[l] is negligible and l < m // kase = 3 if e[l-1] is negligible, l < m, and // s[l, ..., s[m] are not negligible (qr step). // kase = 4 if e[m-1] is negligible (convergence). for (l = m - 2; l >= 0; l--) { test = ComplexMath.Absolute(s[l]) + ComplexMath.Absolute(s[l + 1]); ztest = test + ComplexMath.Absolute(e[l]); if (ztest == test) { e[l] = 0.0; break; } } if (l == m - 2) { kase = 4; } else { for (ls = m - 1; ls > l; ls--) { test = 0.0; if (ls != m - 1) { test = test + ComplexMath.Absolute(e[ls]); } if (ls != l + 1) { test = test + ComplexMath.Absolute(e[ls - 1]); } ztest = test + ComplexMath.Absolute(s[ls]); if (ztest == test) { s[ls] = 0.0; break; } } if (ls == l) { kase = 3; } else if (ls == m - 1) { kase = 1; } else { kase = 2; l = ls; } } l = l + 1; // perform the task indicated by kase. switch (kase) { // deflate negligible s[m]. case 1: f = e[m - 2]; e[m - 2] = 0.0; for (k = m - 2; k >= 0; k--) { t1 = s[k]; drotg(ref t1, ref f, ref cs, ref sn); s[k] = t1; if (k != l) { f = -sn * e[k - 1]; e[k - 1] = cs * e[k - 1]; } if (computeVectors) { drot(v, k, m - 1, cs, sn); } } break; // split at negligible s[l]. case 2: f = e[l - 1]; e[l - 1] = 0.0; for (k = l; k < m; k++) { t1 = s[k]; drotg(ref t1, ref f, ref cs, ref sn); s[k] = t1; f = -sn * e[k]; e[k] = cs * e[k]; if (computeVectors) { drot(u, k, l - 1, cs, sn); } } break; // perform one qr step. case 3: // calculate the shift. scale = 0.0; scale = System.Math.Max(scale, ComplexMath.Absolute(s[m - 1])); scale = System.Math.Max(scale, ComplexMath.Absolute(s[m - 2])); scale = System.Math.Max(scale, ComplexMath.Absolute(e[m - 2])); scale = System.Math.Max(scale, ComplexMath.Absolute(s[l])); scale = System.Math.Max(scale, ComplexMath.Absolute(e[l])); sm = s[m - 1] / scale; smm1 = s[m - 2] / scale; emm1 = e[m - 2] / scale; sl = s[l] / scale; el = e[l] / scale; b = ((smm1 + sm) * (smm1 - sm) + emm1 * emm1) / 2.0; c = (sm * emm1) * (sm * emm1); shift = 0.0; if (b != 0.0 || c != 0.0) { shift = System.Math.Sqrt(b * b + c); if (b < 0.0) { shift = -shift; } shift = c / (b + shift); } f = (sl + sm) * (sl - sm) + shift; g = sl * el; // chase zeros. for (k = l; k < m - 1; k++) { drotg(ref f, ref g, ref cs, ref sn); if (k != l) { e[k - 1] = f; } f = cs * s[k] + sn * e[k]; e[k] = cs * e[k] - sn * s[k]; g = sn * s[k + 1]; s[k + 1] = cs * s[k + 1]; if (computeVectors) { drot(v, k, k + 1, cs, sn); } drotg(ref f, ref g, ref cs, ref sn); s[k] = f; f = cs * e[k] + sn * s[k + 1]; s[k + 1] = -sn * e[k] + cs * s[k + 1]; g = sn * e[k + 1]; e[k + 1] = cs * e[k + 1]; if (computeVectors && k < rows) { drot(u, k, k + 1, cs, sn); } } e[m - 2] = f; iter = iter + 1; break; // convergence. case 4: // make the singular value positive if (s[l] < 0.0) { s[l] = -s[l]; if (computeVectors) { dscalColumn(v, l, 0, -1.0); } } // order the singular value. while (l != mm - 1) { if (s[l] >= s[l + 1]) { break; } t = s[l]; s[l] = s[l + 1]; s[l + 1] = t; if (computeVectors && l < cols) { dswap(v, l, l + 1); } if (computeVectors && l < rows) { dswap(u, l, l + 1); } l = l + 1; } iter = 0; m = m - 1; break; } } // make matrix w from vector s // there is no constructor, creating diagonal matrix from vector // doing it ourselves mm = System.Math.Min(matrix.RowLength, matrix.ColumnLength); #else u = new DoubleMatrix(rows); v = new DoubleMatrix(cols); double[] a = new double[matrix.data.Length]; Array.Copy(matrix.data, a, matrix.data.Length); Lapack.Gesvd.Compute(rows, cols, a, s.data, u.data, v.data); v.Transpose(); #endif w = new DoubleMatrix(matrix.RowLength, matrix.ColumnLength); for (int ii = 0; ii < matrix.RowLength; ii++) { for (int jj = 0; jj < matrix.ColumnLength; jj++) { if (ii == jj) { w[ii, ii] = s[ii]; } } } double eps = System.Math.Pow(2.0, -52.0); double tol = System.Math.Max(matrix.RowLength, matrix.ColumnLength) * s[0] * eps; rank = 0; for (int h = 0; h < mm; h++) { if (s[h] > tol) { rank++; } } if (!computeVectors) { u = null; v = null; } matrix = null; }
private static Complex csign(Complex z1, Complex z2) { Complex ret = ComplexMath.Absolute(z1) * (z2 / ComplexMath.Absolute(z2)); return(ret); }