This page was generated from docs/examples/Parameters/Complex_Parameters.ipynb. Interactive online version: .

# Complex Numbers

QCoDeS natively supports complex numbers via the complex datatypes of numpy.

:

import numpy as np


## Complex-valued parameters

QCoDeS parameters can take complex values. There are two types of complex-valued parameters: scalar-valued parameters and array-valued parameters.

### Scalar-valued parameters

Let us create a complex-valued parameter and set and get values for it. An example that one might encounter in physics is the complex impedance.

For any QCoDeS parameter, it holds that adding input validation is a good idea. Complex parameters are no exception. We therefore use the ComplexNumbers validator with our complex parameter.

:

from qcodes.parameters import Parameter
from qcodes.validators import ComplexNumbers

:

imp = Parameter(name='imp',
label='Impedance',
unit='Ohm',
initial_value=50+0j,
set_cmd=None,
get_cmd=None,
vals=ComplexNumbers())


The ComplexNumbers validator requires explicitly complex values. floats and ints will not pass.

:

for value in np.array([1, -1, 8.2, np.pi]):
try:
imp(value)
print(f'Succesfully set the parameter to {value}')
except TypeError:
print(f'Sorry, but {value} is not complex')

Sorry, but 1.0 is not complex
Sorry, but -1.0 is not complex
Sorry, but 8.2 is not complex
Sorry, but 3.141592653589793 is not complex


The easiest way to make a scalar value complex is probably by adding 0j to it.

:

for value in np.array([1, -1, 8.2, np.pi]) + 0j:
try:
imp(value)
print(f'Succesfully set the parameter to {value}')
except TypeError:
print(f'Sorry, but {value} is not complex')

Succesfully set the parameter to (1+0j)
Succesfully set the parameter to (-1+0j)
Succesfully set the parameter to (8.2+0j)
Succesfully set the parameter to (3.141592653589793+0j)


### Array-valued parameters

There is no separate complex-valued array validator, since the Arrays validator can be customized to cover any real or complex valued case.

Let’s make a little array to hold some quantum state amplitudes. Let’s pretend to be in a 5-dimensional Hilbert space. Our state parameter should thus hold 5 complex numbers (the state expansion coefficients in some implicit basis).

:

from qcodes.validators import Arrays


The proper validator should accept complex numbers and should reject anything of the wrong shape. Note that we get to decide whether we want to accept “non-strictly complex” data.

:

amps_val_strict = Arrays(shape=(5,), valid_types=(np.complexfloating,))
amps_val_lax = Arrays(shape=(5,), valid_types=(np.complexfloating, np.floating, np.integer))


The strict validator is strict:

:

try:
amps_val_strict.validate(np.array([1, 2, 3, 4, 5]))
except TypeError:
print('Sorry, but integers are not strictly complex')

try:
amps_val_strict.validate(np.array([1.0, 2.0, 3.0, 4.0, 5.0]))
except TypeError:
print('Sorry, but floats are not strictly complex')

Sorry, but integers are not strictly complex
Sorry, but floats are not strictly complex


But note, that the presence of a single imaginary part will cast the whole array as complex:

:

my_array = np.array([1.0 + 0j, 2.0, 3.0, 4.0, 5.0])
print(my_array)
print(my_array.dtype)
amps_val_strict.validate(np.array([1.0 + 0j, 2.0, 3.0, 4.0, 5.0]))
print('Yeah, those are complex numbers')

[1.+0.j 2.+0.j 3.+0.j 4.+0.j 5.+0.j]
complex128
Yeah, those are complex numbers


The lax validator let’s everything through:

:

amps_val_lax.validate(np.array([1, 2, 3, 4, 5]))
amps_val_lax.validate(np.array([1.0, 2.0, 3.0, 4.0, 5.0]))
amps_val_lax.validate(np.array([1.0 + 0j, 2, 3, 4, 5]))


We can use either validator for the parameter.

:

amplitudes = Parameter(name='amplitudes',
label='Amplitudes',
unit='',
set_cmd=None,
get_cmd=None,
vals=amps_val_strict,
initial_value=(1/np.sqrt(2)*np.array([1+1j, 0, 0, 0, 0])))

:

amplitudes()

:

array([0.70710678+0.70710678j, 0.        +0.j        ,
0.        +0.j        , 0.        +0.j        ,
0.        +0.j        ])

:

amplitudes(1/np.sqrt(2)*np.array([0, 1+1j, 0, 0, 0]))

[ ]: