Reputation: 51
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
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