RNC
RNC

Reputation: 51

numpy: complex row by column img part is zero

I have a row and a column (1, 3) and (3,1) with these values

a = np.array([[-0.000147028898936696350574+0.003143749432638287544250j,
               -0.000184992561116814613342+0.001760595943778753280640j,
               -0.000147028898936696350574+0.003143749432638287544250j]], dtype=np.complex64)
b = np.array([[-147.028900146484375000000000-3143.749511718750000000000000j],
              [-184.992553710937500000000000-1760.595947265625000000000000j],
              [-147.028900146484375000000000-3143.749511718750000000000000j]], dtype=np.complex64)

I want to multiply the two

c = np.matmul(a, b, dtype=np.complex64)
print (c)

setting print options like this

np.seterr(all='raise')
np.set_printoptions(precision=24)
np.set_printoptions(floatmode="fixed")
np.set_printoptions(threshold=sys.maxsize)

I get

>>> print (c)
[[22.943477630615234375000000+0.000000000000000000000000j]]

If I do the multiplication manually like

d = a[0][0]*b[0][0] + a[0][1]*b[1][0] + a[0][2]*b[2][0]

I get

print (d)
(22.943478+5.9604645e-08j

that is consistent with a matching C example

#include <complex.h>
#include <stdio.h>

int main()
{
  complex float a[] = { -0.000147028898936696350574+0.003143749432638287544250*I, 
    -0.000184992561116814613342+0.001760595943778753280640*I,
    -0.000147028898936696350574+0.003143749432638287544250*I};

  complex float b[] = {-147.028900146484375000000000-3143.749511718750000000000000*I,
    -184.992553710937500000000000-1760.595947265625000000000000*I,
    -147.028900146484375000000000-3143.749511718750000000000000*I };

  complex float  den  = a[0] * b[0] + a[1] * b[1] +  a[2] * b[2];

  printf("%+.30e  %+.30ej\n", crealf(den), cimagf(den) );
  return 0;
}
x@y:~$ gcc main.c && ./a.out 
+2.294347763061523437500000000000e+01  +5.960464477539062500000000000000e-08j

I as shown the real part matches but the imaginary does not, why?

Upvotes: 3

Views: 68

Answers (1)

Muslimbek Abduganiev
Muslimbek Abduganiev

Reputation: 941

The problem seems to be with precisions. When computing complex64 numbers numpy somehow rounds up the result to 0. If you use dtype=complex128 or dtype=complex256, the imaginary part is different from 0. But multiplying the numbers you have provided gives me different imaginary part:

a = np.array([[-0.000147028898936696350574+0.003143749432638287544250j,
           -0.000184992561116814613342+0.001760595943778753280640j,
           -0.000147028898936696350574+0.003143749432638287544250j]], 
dtype=np.complex256)
b = np.array([[-147.028900146484375000000000-3143.749511718750000000000000j],
          [-184.992553710937500000000000-1760.595947265625000000000000j],
          [-147.028900146484375000000000-3143.749511718750000000000000j]], dtype=np.complex256)
np.matmul(a, b)
array([[22.94347681+2.93314883e-08j]], dtype=complex256)

UPDATE: The difference in your C code output and my python is due to precisions again, if you use double values in your C code, then the output will be identical to mine.

Upvotes: 3

Related Questions