Search code examples
c++matrixg++signedhermite

Hermitian matrix and signed zero in c++


I simply want to check whether a matrix is hermitian or not. Let A[ ][ ] is a 2D-array. C[ ][ ] is the conjugate matrix of A[ ][ ]. T[ ][ ] is the transpose matrix of C[ ][ ]. Now I've to check if T[ ][ ]==A[ ][ ]. I compiled the program and after entering a valid hermitian matrix, it said that the matrix is not Hermitian. I found the reason behind it. The compiler evaluated 0==-0 to false. But in my friends pc compiler said that the matrix is Hermitian. We both ran the same code. What is the reason behind this? I am going to give you an example. I have an element A[0][0]=5. After conjugating and transposing, this element became 5-0i (complex number part is minus zero). So my computer failed to evaluate the equality of 5 and 5-0i. How to overcome this problem?

    #include<iostream>
#include<complex>
using namespace std;

int main() {
typedef complex<double> comp;
comp A[3][3]={{2,comp(2,1),4},{comp(2,-1),3,comp(0,1)},{4,comp(0,-1),1}};
comp C[3][3]; comp T[3][3];
int a=0;

for(int i=0;i<3;i++) {
for(int j=0;j<3;j++) {
C[i][j]=conj(A[i][j]); }}

for(int i=0;i<3;i++) {
for(int j=0;j<3;j++) {
T[i][j]=C[j][i]; }}

for(int i=0;i<3;i++) {
for(int j=0;j<3;j++) {

if(T[i][j]==A[i][j])
a=a+1;
else a=0; }}

if(a==9)
cout << "Hermitian" << endl;
else cout << "Not Hermitian" << endl;

return 0;
} 

Solution

  • You could just replace

    typedef complex<double> comp;
    

    with

    typedef complex<int> comp;
    

    Or if you want to keep using double(from your example I can't see any reason why) you could use this function for comparing two complex numbers:

    bool double_equals(complex<double> a, complex<double> b, double epsilon = 0.001)
    {
        bool retval = false;
        if ((std::abs(a.real() - b.real()) < epsilon) && (std::abs(a.imag() - b.imag()) < epsilon))
            retval = true;
        return retval;
    }
    

    Also see: c++ comparison of two double values not working properly