public void CanGetConjugate() { var complex = new Complex32(123.456f, -78.9f); var conjugate = complex.Conjugate(); Assert.AreEqual(complex.Real, conjugate.Real); Assert.AreEqual(-complex.Imaginary, conjugate.Imaginary); }
/// <summary> /// Reduces a complex hermitian matrix to a real symmetric tridiagonal matrix using unitary similarity transformations. /// </summary> /// <param name="matrixA">Source matrix to reduce</param> /// <param name="d">Output: Arrays for internal storage of real parts of eigenvalues</param> /// <param name="e">Output: Arrays for internal storage of imaginary parts of eigenvalues</param> /// <param name="tau">Output: Arrays that contains further information about the transformations.</param> /// <param name="order">Order of initial matrix</param> /// <remarks>This is derived from the Algol procedures HTRIDI 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> internal static void SymmetricTridiagonalize(Complex32[] matrixA, float[] d, float[] e, Complex32[] tau, int order) { float hh; tau[order - 1] = Complex32.One; for (var i = 0; i < order; i++) { d[i] = matrixA[i * order + i].Real; } // Householder reduction to tridiagonal form. for (var i = order - 1; i > 0; i--) { // Scale to avoid under/overflow. var scale = 0.0f; var h = 0.0f; for (var k = 0; k < i; k++) { scale = scale + Math.Abs(matrixA[k * order + i].Real) + Math.Abs(matrixA[k * order + i].Imaginary); } if (scale == 0.0f) { tau[i - 1] = Complex32.One; e[i] = 0.0f; } else { for (var k = 0; k < i; k++) { matrixA[k * order + i] /= scale; h += matrixA[k * order + i].MagnitudeSquared; } Complex32 g = (float)Math.Sqrt(h); e[i] = scale * g.Real; Complex32 temp; var im1Oi = (i - 1) * order + i; var f = matrixA[im1Oi]; if (f.Magnitude != 0.0f) { temp = -(matrixA[im1Oi].Conjugate() * tau[i].Conjugate()) / f.Magnitude; h += f.Magnitude * g.Real; g = 1.0f + (g / f.Magnitude); matrixA[im1Oi] *= g; } else { temp = -tau[i].Conjugate(); matrixA[im1Oi] = g; } if ((f.Magnitude == 0.0f) || (i != 1)) { f = Complex32.Zero; for (var j = 0; j < i; j++) { var tmp = Complex32.Zero; var jO = j * order; // Form element of A*U. for (var k = 0; k <= j; k++) { tmp += matrixA[k * order + j] * matrixA[k * order + i].Conjugate(); } for (var k = j + 1; k <= i - 1; k++) { tmp += matrixA[jO + k].Conjugate() * matrixA[k * order + i].Conjugate(); } // Form element of P tau[j] = tmp / h; f += (tmp / h) * matrixA[jO + i]; } hh = f.Real / (h + h); // Form the reduced A. for (var j = 0; j < i; j++) { f = matrixA[j * order + i].Conjugate(); g = tau[j] - (hh * f); tau[j] = g.Conjugate(); for (var k = 0; k <= j; k++) { matrixA[k * order + j] -= (f * tau[k]) + (g * matrixA[k * order + i]); } } } for (var k = 0; k < i; k++) { matrixA[k * order + i] *= scale; } tau[i - 1] = temp.Conjugate(); } hh = d[i]; d[i] = matrixA[i * order + i].Real; matrixA[i * order + i] = new Complex32(hh, scale * (float)Math.Sqrt(h)); } hh = d[0]; d[0] = matrixA[0].Real; matrixA[0] = hh; e[0] = 0.0f; }