I usually write a quantum computer simulator in Python. For that reason, I use complex numbers very often.
Python and numpy also support complex numbers, so it's not too much trouble, but there are some traps, so I will summarize them.
This is the one you normally find in the reference. Lightly review.
1j
and the type is complex
Mathematics often uses i for the imaginary unit, while Python uses 1j
.
(In fields such as electricity, I have seen that the imaginary unit is set to j because i is used for electric current, but I do not know anything else in other fields.)
You can also write something like 2j
or 1.23j
. (Normally means twice as much as 1j
, 1.23 times)
Whereas 1
and 1.
have different types, 1j
and 1.j
are both the same.
ʻA + b * 1. jcan also be written as
complex (a, b)`, where a and b are floats.
.real
, .imag
and take the complex conjugate with conjugate ()
(1 + 2j) .real
is 1
, (1 + 2j) .imag
is 2
. Note that we don't add ()
as it is not a method.
Complex conjugates use .conjugate ()
, such as (1 + 2j) .conjugate ()
. Since this is a method, ()
is required.
By the way, .real
, .imag
, conjugate ()
can actually be used for float and int.
Even with numpy, you can use complex numbers normally, such as np.array ([1 + 2j, 3, 4j, 5 + 6.7j])
. At this time, dtype
defaults to'complex128'.
.real
, .imag
, .conjugate ()
can also be used for numpy arrays.
Also, in numpy, you can use .conj ()
instead of .conjugate ()
.
In addition, it is necessary to use .conj (). T
to take the Hermitian conjugate of the matrix, which is a little troublesome.
With np.matrix
, it was possible with .H
. It doesn't seem to be in np.array
.
cmath
instead of math
Use ʻimport cmath instead of ʻimport math
.
Whereas the function of math
takes a domain or range as a real number, cmath
also contains a complex number in the domain or range.
See Official Documentation for details.
There are also useful functions such as phase ()
to find the argument of a complex number, polar ()
to return a tuple of radius and declination, and rect ()
to create a complex number from radius and declination. ..
I will write some traps and how to deal with them.
Python implicitly converts the type without writing the type yourself, but in numpy, the array has a type, and the type of the array does not change arbitrarily. (The same is true if the int array does not become a float)
a = np.array([1., 2.]) #dtype is float64
a *= 1j
# UFuncTypeError: Cannot cast ufunc 'multiply' output from dtype('complex128') to dtype('float64') with casting rule 'same_kind'
To prevent this from happening
Specify the type from the beginning like np.array ([1., 2.], dtype = np.complex128)
, or
It is necessary to include complex numbers from the beginning like np.array ([1 + 0j, 2.], dtype = np.complex128)
.
np.vdot
instead of np.dot
This is really a trap.
The inner product of the complex vector is the sum of the product of the complex conjugate of $ u $ and the product of each component of $ v $, such as $ u \ cdot v = \ sum_ {i = 1} ^ n u_i ^ * v_i $. Is normal, but in np.dot
, the sum of the products of each component is taken as it is without taking the complex conjugate. If you really need to use np.dot
, use the complex conjugate yourself.
On the other hand, if you use np.vdot
, you can get the inner product properly even if it is a complex vector.
Obviously for anyone working with complex numbers in other languages. Complex numbers cannot be compared.
More precisely, it is not possible to compare the magnitude of "complex type", so even if the programmer knows that the calculation result is a real number, if it is a complex number type for the computer, it cannot be compared. It must be a real number, such as .real
.
Since np.abs
internally calculates something likesqrt (real ** 2 + imag ** 2)
, it is wasteful to square it.
On the other hand, if you write a calculation like ʻarr.real ** 2 + arr.imag ** 2` on the Python side, it will not be calculated in-place, resulting in wasted memory allocation.
I've checked it before, but StackOverflow says that numba can be used -of-complex-numpy-ndarray). It seems that there is no surprising way to do it without unnecessary square root extraction in-place with only Python and numpy.
Recommended Posts