def test_pretty_string_format(): """Tests __str__ of the dynamic decoupling sequence """ _duration = 1. _offsets = np.array([0., 0.5, 1.]) _rabi_rotations = np.array([0., np.pi, 0.]) _azimuthal_angles = 0.5 * np.array([0., np.pi/2, np.pi]) _detuning_rotations = np.array([np.pi/4, 0., 0.]) _name = 'test_sequence' dd_sequence = DynamicDecouplingSequence( offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name) _pretty_string = ['test_sequence:'] _pretty_string.append('Duration = {}'.format(_duration)) _pretty_string.append('Offsets = [{},{},{}] x {}'.format(_offsets[0], _offsets[1], _offsets[2], _duration)) _pretty_string.append('Rabi Rotations = [{},{},{}] x pi'.format( _rabi_rotations[0]/np.pi, _rabi_rotations[1]/np.pi, _rabi_rotations[2]/np.pi)) _pretty_string.append('Azimuthal Angles = [{},{},{}] x pi'.format( _azimuthal_angles[0]/np.pi, _azimuthal_angles[1]/np.pi, _azimuthal_angles[2]/np.pi)) _pretty_string.append('Detuning Rotations = [{},{},{}] x pi'.format( _detuning_rotations[0] / np.pi, _detuning_rotations[1] / np.pi, _detuning_rotations[2] / np.pi)) _pretty_string = '\n'.join(_pretty_string) assert _pretty_string == str(dd_sequence) dd_sequence = DynamicDecouplingSequence( offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations) _pretty_string = list() _pretty_string.append('Duration = {}'.format(_duration)) _pretty_string.append('Offsets = [{},{},{}] x {}'.format( _offsets[0], _offsets[1], _offsets[2], _duration)) _pretty_string.append('Rabi Rotations = [{},{},{}] x pi'.format( _rabi_rotations[0] / np.pi, _rabi_rotations[1] / np.pi, _rabi_rotations[2] / np.pi)) _pretty_string.append('Azimuthal Angles = [{},{},{}] x pi'.format( _azimuthal_angles[0] / np.pi, _azimuthal_angles[1] / np.pi, _azimuthal_angles[2] / np.pi)) _pretty_string.append('Detuning Rotations = [{},{},{}] x pi'.format( _detuning_rotations[0] / np.pi, _detuning_rotations[1] / np.pi, _detuning_rotations[2] / np.pi)) _pretty_string = '\n'.join(_pretty_string) assert _pretty_string == str(dd_sequence)
def test_conversion_of_tightly_packed_sequence(): """ Tests if the method to convert a DDS to driven controls handles properly a sequence tightly packed with pulses, where there is no time for a gap between the pi/2-pulses and the adjacent pi-pulses. """ # create a sequence containing 2 pi-pulses and 2 pi/2-pulses at the extremities dynamic_decoupling_sequence = DynamicDecouplingSequence( duration=0.2, offsets=np.array([0.0, 0.05, 0.15, 0.2]), rabi_rotations=np.array( [1.57079633, 3.14159265, 3.14159265, 1.57079633]), azimuthal_angles=np.array([0.0, 0.0, 0.0, 0.0]), detuning_rotations=np.array([0.0, 0.0, 0.0, 0.0]), name=None, ) driven_control = convert_dds_to_driven_control( dynamic_decoupling_sequence, maximum_rabi_rate=20.0 * np.pi, maximum_detuning_rate=2 * np.pi, name=None, ) # There is no space for a gap between the pi/2-pulses and the adjacent pi-pulses, # so the resulting sequence should have 4 pulses + 1 gaps = 5 segments with non-zero duration assert sum(np.greater(driven_control.durations, 0.0)) == 5 # ... of which 4 are X pulses (i.e. rabi_rotation > 0) assert sum(np.greater(driven_control.rabi_rates, 0.0)) == 4
def test_pyquil_program(): """Tests if the Dynamic Decoupling Sequence gives rise to Identity operation in PyQuil """ _duration = 5e-6 _offsets = [0, 1e-6, 2.5e-6, 4e-6, 5e-6] _rabi_rotations = [np.pi / 2, np.pi / 2, np.pi, 0, np.pi / 2] _azimuthal_angles = [0, 0, np.pi / 2, 0, 0] _detuning_rotations = [0, 0, 0, np.pi, 0] sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations) program = convert_dds_to_pyquil_program(sequence, [0], gate_time=1e-6) assert len(program) == 13 assert program[0] == Pragma("PRESERVE_BLOCK") assert program[-1] == Pragma("END_PRESERVE_BLOCK") assert program[1] == RX(np.pi / 2, 0) assert program[2] == I(0) assert program[3] == RX(np.pi / 2, 0) assert program[4] == I(0) assert program[5] == RY(np.pi, 0) assert program[6] == I(0) assert program[7] == RZ(np.pi, 0) assert program[8] == I(0) assert program[9] == RX(np.pi / 2, 0)
def test_free_evolution_conversion(): """Tests the conversion of free evolution """ _duration = 10. _offsets = np.array([0., _duration]) _rabi_rotations = np.array([0., 0.]) _azimuthal_angles = np.array([0., 0.]) _detuning_rotations = np.array([0., 0.]) _name = 'test_sequence' dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name) _maximum_rabi_rate = 20 * np.pi _maximum_detuning_rate = 20 * np.pi driven_control = convert_dds_to_driven_controls( dd_sequence, maximum_rabi_rate=_maximum_rabi_rate, maximum_detuning_rate=_maximum_detuning_rate, name=_name) _segments = np.reshape(np.array([0., 0., 0., _duration]), (1, 4)) assert np.allclose(driven_control.segments, _segments)
def test_conversion_of_pulses_with_arbitrary_azimuthal_angles(): """ Tests if the method to convert a DDS to driven controls handles properly pi-pulses with azimuthal angles that assume arbitrary values between 0 and pi/2. """ _duration = 3.0 _offsets = [0.5, 1.5, 2.5] _rabi_rotations = [np.pi, np.pi, np.pi] _azimuthal_angles = [0.5, 1.0, 1.5] _detuning_rotations = [0.0, 0.0, 0.0] _name = "arbitrary_azimuthal_angle_sequence" dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name, ) _maximum_rabi_rate = 20 * np.pi _maximum_detuning_rate = 10 * np.pi minimum_segment_duration = 0.1 driven_control = convert_dds_to_driven_control( dd_sequence, maximum_rabi_rate=_maximum_rabi_rate, maximum_detuning_rate=_maximum_detuning_rate, minimum_segment_duration=minimum_segment_duration, name=_name, ) expected_rabi_rates = [ 0.0, 10.0 * np.pi, 0.0, 10.0 * np.pi, 0.0, 10.0 * np.pi, 0.0 ] expected_azimuthal_angles = [0.0, 0.5, 0.0, 1.0, 0.0, 1.5, 0.0] expected_detuning_rates = [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0] expected_durations = [ 0.5 - 0.1 / 2, 0.1, 1.0 - 0.1 / 2 - 0.1 / 2, 0.1, 1.0 - 0.1 / 2 - 0.1 / 2, 0.1, 0.5 - 0.1 / 2, ] assert np.allclose(driven_control.rabi_rates, expected_rabi_rates) assert np.allclose(driven_control.azimuthal_angles, expected_azimuthal_angles) assert np.allclose(driven_control.detunings, expected_detuning_rates) assert np.allclose(driven_control.durations, expected_durations) # check explicitly that minimum segment duration is respected assert _all_greater_or_close(driven_control.duration, minimum_segment_duration)
def test_export_to_file(): """Tests exporting to file """ _duration = 2. _offsets = 2 * np.array([0., 0.25, 0.5, 0.75, 1.]) _rabi_rotations = np.array([0., np.pi, 0., np.pi, 0.]) _azimuthal_angles = np.array([0., np.pi / 2, 0., 0., 0.]) _detuning_rotations = np.array([0., 0., np.pi, 0., 0.]) _name = 'test_sequence' dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name) _maximum_rabi_rate = 20 * np.pi _maximum_detuning_rate = 20 * np.pi driven_control = convert_dds_to_driven_control( dd_sequence, maximum_rabi_rate=_maximum_rabi_rate, maximum_detuning_rate=_maximum_detuning_rate, name=_name) _filename = 'dds_qctrl_cylindrical.csv' driven_control.export_to_file(filename=_filename, file_format='Q-CTRL expanded', file_type='CSV', coordinates='cylindrical') _filename = 'dds_qctrl_cartesian.csv' driven_control.export_to_file(filename=_filename, file_format='Q-CTRL expanded', file_type='CSV', coordinates='cartesian') _filename = 'dds_qctrl_cylindrical.json' driven_control.export_to_file(filename=_filename, file_format='Q-CTRL expanded', file_type='JSON', coordinates='cylindrical') _filename = 'dds_qctrl_cartesian.json' driven_control.export_to_file(filename=_filename, file_format='Q-CTRL expanded', file_type='JSON', coordinates='cartesian') _remove_file('dds_qctrl_cylindrical.csv') _remove_file('dds_qctrl_cartesian.csv') _remove_file('dds_qctrl_cylindrical.json') _remove_file('dds_qctrl_cartesian.json')
def test_conversion_to_driven_controls(): """ Tests the method to convert a DDS to Driven Control. """ _duration = 2.0 _offsets = 2 * np.array([0.25, 0.5, 0.75]) _rabi_rotations = np.array([np.pi, 0.0, np.pi]) _azimuthal_angles = np.array([np.pi / 2, 0.0, 0.0]) _detuning_rotations = np.array([0.0, np.pi, 0.0]) _name = "test_sequence" dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name, ) _maximum_rabi_rate = 20 * np.pi _maximum_detuning_rate = 20 * np.pi driven_control = convert_dds_to_driven_control( dd_sequence, maximum_rabi_rate=_maximum_rabi_rate, maximum_detuning_rate=_maximum_detuning_rate, name=_name, ) assert np.allclose( driven_control.rabi_rates, np.array( [0.0, _maximum_rabi_rate, 0.0, 0.0, 0.0, _maximum_rabi_rate, 0.0]), ) assert np.allclose( driven_control.azimuthal_angles, np.array([ 0.0, _azimuthal_angles[0], 0.0, 0.0, 0.0, _azimuthal_angles[2], 0.0 ]), ) assert np.allclose( driven_control.detunings, np.array([0.0, 0.0, 0.0, _maximum_detuning_rate, 0.0, 0.0, 0]), ) assert np.allclose( driven_control.durations, np.array([4.75e-1, 5e-2, 4.5e-1, 5e-2, 4.5e-1, 5e-2, 4.75e-1]), )
def test_conversion_to_driven_controls(): """Tests the method to convert a DDS to Driven Control """ _duration = 2. _offsets = 2*np.array([0., 0.25, 0.5, 0.75, 1.]) _rabi_rotations = np.array([0., np.pi, 0., np.pi, 0.]) _azimuthal_angles = np.array([0., np.pi / 2, 0., 0., 0.]) _detuning_rotations = np.array([0., 0., np.pi, 0., 0.]) _name = 'test_sequence' dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name) _maximum_rabi_rate = 20*np.pi _maximum_detuning_rate = 20*np.pi driven_control = convert_dds_to_driven_controls(dd_sequence, maximum_rabi_rate=_maximum_rabi_rate, maximum_detuning_rate=_maximum_detuning_rate, name=_name) assert np.sum(driven_control.segments[:, 3]) == _duration assert np.allclose(driven_control.segments[:, 0], np.array( [0., _maximum_rabi_rate*np.cos(_azimuthal_angles[1]), 0., 0., 0., _maximum_rabi_rate*np.cos(_azimuthal_angles[3]), 0.])) assert np.allclose(driven_control.segments[:, 1], np.array( [0., _maximum_rabi_rate*np.sin(_azimuthal_angles[1]), 0., 0., 0., 0., 0])) assert np.allclose(driven_control.segments[:, 2], np.array( [0., 0., 0., np.pi, 0., 0., 0])) assert np.allclose(driven_control.segments[:, 3], np.array( [4.75e-1, 5e-2, 4.5e-1, 5e-2, 4.5e-1, 5e-2, 4.75e-1])) _duration = 2. _offsets = 2 * np.array([0., 0.25, 0.5, 0.75, 1.]) _rabi_rotations = np.array([0., np.pi, 0., np.pi, 0.]) _azimuthal_angles = np.array([0., np.pi / 2, 0., 0., 0.]) _detuning_rotations = np.array([0., 0., np.pi, 0., 0.]) _name = 'test_sequence'
def test_conversion_of_y_pi_2_pulses_at_extremities(): """ Tests if the method to convert a DDS to driven controls handles properly Y pi/2-pulses in inverse directions, in the beginning and end of the sequence. """ _duration = 1.0 _offsets = np.array([0.0, _duration]) _rabi_rotations = np.array([np.pi / 2, np.pi / 2]) _azimuthal_angles = np.array([-np.pi / 2, np.pi / 2]) _detuning_rotations = np.array([0.0, 0]) _name = "y_pi2_pulse_sequence" dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name, ) _maximum_rabi_rate = 20 * np.pi _maximum_detuning_rate = 20 * np.pi driven_control = convert_dds_to_driven_control( dd_sequence, maximum_rabi_rate=_maximum_rabi_rate, maximum_detuning_rate=_maximum_detuning_rate, name=_name, ) assert np.allclose( driven_control.rabi_rates, np.array([_maximum_rabi_rate, 0.0, _maximum_rabi_rate]), ) assert np.allclose( driven_control.azimuthal_angles, np.array([_azimuthal_angles[0], 0.0, _azimuthal_angles[1]]), ) assert np.allclose(driven_control.detunings, np.array([0.0, 0.0, 0.0])) assert np.allclose(driven_control.durations, np.array([2.5e-2, _duration - 2 * 2.5e-2, 2.5e-2]))
def test_dynamical_decoupling_sequence(): """Tests for the Dynamic Decoupling Sequence class """ _duration = 2. _offsets = np.array([0.25, 0.5, 0.75, 1.00, 1.25, 1.50, 1.75]) _rabi_rotations = np.array( [np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi]) _azimthal_angles = 0.5 * np.array( [np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi]) _detuning_rotations = np.array([0., 0., 0., 0., 0., 0., 0.]) _name = 'test_sequence' sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimthal_angles, detuning_rotations=_detuning_rotations, name=_name) assert sequence.duration == _duration assert np.allclose(sequence.offsets, _offsets) assert np.allclose(sequence.rabi_rotations, _rabi_rotations) assert np.allclose(sequence.azimuthal_angles, _azimthal_angles) assert np.allclose(sequence.detuning_rotations, _detuning_rotations) assert sequence.name == _name _repr_string = '{0.__class__.__name__!s}('.format(sequence) attributes = { 'duration': sequence.duration, 'offsets': sequence.offsets, 'rabi_rotations': sequence.rabi_rotations, 'azimuthal_angles': sequence.azimuthal_angles, 'detuning_rotations': sequence.detuning_rotations, 'name': sequence.name } attributes_string = ','.join( '{0}={1}'.format(attribute, repr(getattr(sequence, attribute))) for attribute in attributes) _repr_string += attributes_string _repr_string += ')' assert repr(sequence) == _repr_string _duration = 2. _offsets = np.array([0., 0.25, 0.5, 0.75, 1.00, 1.25, 1.50, 1.75, 2.00]) _rabi_rotations = np.array([ np.pi / 2, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi / 2 ]) _azimthal_angles = 0.5 * np.array( [0., np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, 0.]) _detuning_rotations = np.array([0., 0., 0., 0., 0., 0., 0., 0., 0.]) _name = 'test_sequence' sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimthal_angles, detuning_rotations=_detuning_rotations, name=_name) assert sequence.duration == _duration assert np.allclose(sequence.offsets, _offsets) assert np.allclose(sequence.rabi_rotations, _rabi_rotations) assert np.allclose(sequence.azimuthal_angles, _azimthal_angles) assert np.allclose(sequence.detuning_rotations, _detuning_rotations) assert sequence.name == _name with pytest.raises(ArgumentsValueError): # not more than 10000 offsets _ = DynamicDecouplingSequence(duration=2., offsets=2. / 2000 * np.ones((20000, 1)), rabi_rotations=np.pi * np.ones( (20000, 1))) # duration cannot be negative _ = DynamicDecouplingSequence(duration=-2.)
def test_free_evolution_conversion(): """Tests the conversion of free evolution """ _duration = 10. _name = 'test_sequence' _offsets = [] _rabi_rotations = [] _azimuthal_angles = [] _detuning_rotations = [] dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name) _maximum_rabi_rate = 20 * np.pi _maximum_detuning_rate = 20 * np.pi driven_control = convert_dds_to_driven_control( dd_sequence, maximum_rabi_rate=_maximum_rabi_rate, maximum_detuning_rate=_maximum_detuning_rate, name=_name) _rabi_rates = np.array([0.]) _azimuthal_angles = np.array([0.]) _detunings = np.array([0.]) _durations = np.array([_duration]) assert np.allclose(driven_control.rabi_rates, _rabi_rates) assert np.allclose(driven_control.azimuthal_angles, _azimuthal_angles) assert np.allclose(driven_control.detunings, _detunings) assert np.allclose(driven_control.durations, _durations) _duration = 10. _name = 'test_sequence' _offsets = [0, _duration] _rabi_rotations = [np.pi / 2, np.pi / 2] _azimuthal_angles = [0, 0] _detuning_rotations = [0, 0] dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name) _maximum_rabi_rate = 20 * np.pi _maximum_detuning_rate = 20 * np.pi driven_control = convert_dds_to_driven_control( dd_sequence, maximum_rabi_rate=_maximum_rabi_rate, maximum_detuning_rate=_maximum_detuning_rate, name=_name) _rabi_rates = np.array([_maximum_rabi_rate, 0., _maximum_rabi_rate]) _azimuthal_angles = np.array([0, 0, 0]) _detunings = np.array([0, 0, 0]) _durations = np.array([0.025, 9.95, 0.025]) assert np.allclose(driven_control.rabi_rates, _rabi_rates) assert np.allclose(driven_control.azimuthal_angles, _azimuthal_angles) assert np.allclose(driven_control.detunings, _detunings) assert np.allclose(driven_control.durations, _durations)
def test_pretty_string_format(): """ Tests `__str__` of the dynamic decoupling sequence. """ _duration = 1.0 _offsets = np.array([0.0, 0.5, 1.0]) _rabi_rotations = np.array([0.0, np.pi, 0.0]) _azimuthal_angles = 0.5 * np.array([0.0, np.pi / 2, np.pi]) _detuning_rotations = np.array([np.pi / 4, 0.0, 0.0]) _name = "test_sequence" dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name, ) _pretty_string = ["test_sequence:"] _pretty_string.append("Duration = {}".format(_duration)) _pretty_string.append("Offsets = [{}, {}, {}] x {}".format( _offsets[0], _offsets[1], _offsets[2], _duration)) _pretty_string.append("Rabi Rotations = [{}, {}, {}] x pi".format( _rabi_rotations[0] / np.pi, _rabi_rotations[1] / np.pi, _rabi_rotations[2] / np.pi, )) _pretty_string.append("Azimuthal Angles = [{}, {}, {}] x pi".format( _azimuthal_angles[0] / np.pi, _azimuthal_angles[1] / np.pi, _azimuthal_angles[2] / np.pi, )) _pretty_string.append("Detuning Rotations = [{}, {}, {}] x pi".format( _detuning_rotations[0] / np.pi, _detuning_rotations[1] / np.pi, _detuning_rotations[2] / np.pi, )) expected_string = "\n".join(_pretty_string) assert expected_string == str(dd_sequence) dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, ) _pretty_string = list() _pretty_string.append("Duration = {}".format(_duration)) _pretty_string.append("Offsets = [{}, {}, {}] x {}".format( _offsets[0], _offsets[1], _offsets[2], _duration)) _pretty_string.append("Rabi Rotations = [{}, {}, {}] x pi".format( _rabi_rotations[0] / np.pi, _rabi_rotations[1] / np.pi, _rabi_rotations[2] / np.pi, )) _pretty_string.append("Azimuthal Angles = [{}, {}, {}] x pi".format( _azimuthal_angles[0] / np.pi, _azimuthal_angles[1] / np.pi, _azimuthal_angles[2] / np.pi, )) _pretty_string.append("Detuning Rotations = [{}, {}, {}] x pi".format( _detuning_rotations[0] / np.pi, _detuning_rotations[1] / np.pi, _detuning_rotations[2] / np.pi, )) expected_string = "\n".join(_pretty_string) assert expected_string == str(dd_sequence)
def test_sequence_plot(): """ Tests the plot data of sequences """ # An arbitrary sequence - may not conform to any of the predefined ones _offsets = np.array([0, 0.25, 0.5, 0.75, 1.00]) _rabi_rotations = np.array([0, np.pi, 0, np.pi, 0]) _azimuthal_angle = np.array([0, 0, 0, 0, 0]) _detuning_rotations = np.array([0, 0, 0, 0, 0]) seq = DynamicDecouplingSequence(duration=1.0, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angle, detuning_rotations=_detuning_rotations) plot_data = seq.export() _plot_rabi_offsets = [pulse['offset'] for pulse in plot_data['Rabi']] _plot_detuning_offsets = [ pulse['offset'] for pulse in plot_data['Detuning'] ] _plot_rabi_rotations = [pulse['rotation'] for pulse in plot_data['Rabi']] _plot_detuning_rotations = [ pulse['rotation'] for pulse in plot_data['Detuning'] ] assert np.allclose(_plot_rabi_offsets, _offsets) assert np.allclose(_plot_detuning_offsets, _offsets) assert np.allclose(np.abs(_plot_rabi_rotations), _rabi_rotations) assert np.allclose(np.angle(_plot_rabi_rotations), _azimuthal_angle) assert np.allclose(_plot_detuning_rotations, _detuning_rotations) # with both X and Y pi _offsets = np.array([0, 0.25, 0.5, 0.75, 1.00]) _rabi_rotations = np.array([0, np.pi, 0, np.pi, 0]) _azimuthal_angle = np.array([0, np.pi / 2, 0, np.pi / 2, 0]) _detuning_rotations = np.array([0, 0, 0, 0, 0]) seq = DynamicDecouplingSequence(duration=1.0, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angle, detuning_rotations=_detuning_rotations) plot_data = seq.export() _plot_rabi_offsets = [pulse['offset'] for pulse in plot_data['Rabi']] _plot_detuning_offsets = [ pulse['offset'] for pulse in plot_data['Detuning'] ] _plot_rabi_rotations = [pulse['rotation'] for pulse in plot_data['Rabi']] _plot_detuning_rotations = [ pulse['rotation'] for pulse in plot_data['Detuning'] ] assert np.allclose(_plot_rabi_offsets, _offsets) assert np.allclose(_plot_detuning_offsets, _offsets) assert np.allclose(np.abs(_plot_rabi_rotations), _rabi_rotations) assert np.allclose(np.angle(_plot_rabi_rotations), _azimuthal_angle) assert np.allclose(_plot_detuning_rotations, _detuning_rotations)
def test_sequence_plot(): """ Tests the plot data of sequences """ # An arbitrary sequence - may not conform to any of the predefined ones _offsets = np.array([0, 0.25, 0.5, 0.75, 1.00]) _rabi_rotations = np.array([0, np.pi, 0, np.pi, 0]) _azimuthal_angle = np.array([0, 0, 0, 0, 0]) _detuning_rotations = np.array([0, 0, 0, 0, 0]) _plot_times = np.array([ 0, 0, 0, 0.25, 0.25, 0.25, 0.5, 0.5, 0.5, 0.75, 0.75, 0.75, 1., 1., 1. ]) _plot_rabi_rotations = np.array( [0, 0, 0, 0, np.pi, 0, 0, 0, 0, 0, np.pi, 0, 0, 0, 0]) _plot_azimuthal_angles = np.array( [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) _plot_detuning_rotations = np.array( [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) seq = DynamicDecouplingSequence(duration=1.0, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angle, detuning_rotations=_detuning_rotations) plot_data = seq.get_plot_formatted_arrays() plot_rabi, plot_azimuthal, plot_detuning, plot_times = ( plot_data['rabi_rotations'], plot_data['azimuthal_angles'], plot_data['detuning_rotations'], plot_data['times']) assert np.allclose(_plot_rabi_rotations, plot_rabi) assert np.allclose(_plot_azimuthal_angles, plot_azimuthal) assert np.allclose(_plot_detuning_rotations, plot_detuning) assert np.allclose(_plot_times, plot_times) # with both X and Y pi _offsets = np.array([0, 0.25, 0.5, 0.75, 1.00]) _rabi_rotations = np.array([0, np.pi, 0, np.pi, 0]) _azimuthal_angle = np.array([0, np.pi / 2, 0, np.pi / 2, 0]) _detuning_rotations = np.array([0, 0, 0, 0, 0]) _plot_rabi_rotations = np.array( [0, 0, 0, 0, np.pi, 0, 0, 0, 0, 0, np.pi, 0, 0, 0, 0]) _plot_azimuthal_angles = np.array( [0, 0, 0, 0, np.pi / 2, 0, 0, 0, 0, 0, np.pi / 2, 0, 0, 0, 0]) _plot_detuning_rotations = np.array( [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]) _plot_times = np.array([ 0, 0, 0, 0.25, 0.25, 0.25, 0.5, 0.5, 0.5, 0.75, 0.75, 0.75, 1., 1., 1. ]) seq = DynamicDecouplingSequence(duration=1.0, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angle, detuning_rotations=_detuning_rotations) plot_data = seq.get_plot_formatted_arrays() plot_rabi, plot_azimuthal, plot_detuning, plot_times = ( plot_data['rabi_rotations'], plot_data['azimuthal_angles'], plot_data['detuning_rotations'], plot_data['times']) assert np.allclose(_plot_rabi_rotations, plot_rabi) assert np.allclose(_plot_azimuthal_angles, plot_azimuthal) assert np.allclose(_plot_detuning_rotations, plot_detuning) assert np.allclose(_plot_times, plot_times)
def test_export_to_file(): """ Tests exporting to file. """ _duration = 2.0 _offsets = 2 * np.array([0.0, 0.25, 0.5, 0.75, 1.0]) _rabi_rotations = np.array([0.0, np.pi, 0.0, np.pi, 0.0]) _azimuthal_angles = np.array([0.0, np.pi / 2, 0.0, 0.0, 0.0]) _detuning_rotations = np.array([0.0, 0.0, np.pi, 0.0, 0.0]) _name = "test_sequence" dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name, ) _maximum_rabi_rate = 20 * np.pi _maximum_detuning_rate = 20 * np.pi driven_control = convert_dds_to_driven_control( dd_sequence, maximum_rabi_rate=_maximum_rabi_rate, maximum_detuning_rate=_maximum_detuning_rate, name=_name, ) _filename = "dds_qctrl_cylindrical.csv" driven_control.export_to_file( filename=_filename, file_format="Q-CTRL expanded", file_type="CSV", coordinates="cylindrical", ) _filename = "dds_qctrl_cartesian.csv" driven_control.export_to_file( filename=_filename, file_format="Q-CTRL expanded", file_type="CSV", coordinates="cartesian", ) _filename = "dds_qctrl_cylindrical.json" driven_control.export_to_file( filename=_filename, file_format="Q-CTRL expanded", file_type="JSON", coordinates="cylindrical", ) _filename = "dds_qctrl_cartesian.json" driven_control.export_to_file( filename=_filename, file_format="Q-CTRL expanded", file_type="JSON", coordinates="cartesian", ) _remove_file("dds_qctrl_cylindrical.csv") _remove_file("dds_qctrl_cartesian.csv") _remove_file("dds_qctrl_cylindrical.json") _remove_file("dds_qctrl_cartesian.json")
def test_conversion_of_pi_2_pulses_to_driven_controls(): """ Tests if the method to convert a DDS to driven controls handles properly pi/2-pulses in the x, y, and z directions. """ _duration = 6.0 _offsets = np.array([0.5, 1.5, 2.5, 3.5, 4.5, 5.5]) _rabi_rotations = np.array( [np.pi / 2, 0.0, np.pi / 2, np.pi / 2, 0.0, np.pi / 2]) _azimuthal_angles = np.array([np.pi / 2, 0.0, 0.0, -np.pi / 2, 0, np.pi]) _detuning_rotations = np.array([0.0, np.pi / 2, 0.0, 0.0, -np.pi / 2, 0]) _name = "pi2_pulse_sequence" dd_sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimuthal_angles, detuning_rotations=_detuning_rotations, name=_name, ) _maximum_rabi_rate = 20 * np.pi _maximum_detuning_rate = 20 * np.pi driven_control = convert_dds_to_driven_control( dd_sequence, maximum_rabi_rate=_maximum_rabi_rate, maximum_detuning_rate=_maximum_detuning_rate, name=_name, ) assert np.allclose( driven_control.rabi_rates, np.array([ 0.0, _maximum_rabi_rate, 0.0, 0.0, 0.0, _maximum_rabi_rate, 0.0, _maximum_rabi_rate, 0.0, 0.0, 0.0, _maximum_rabi_rate, 0.0, ]), ) assert np.allclose( driven_control.azimuthal_angles, np.array([ 0.0, _azimuthal_angles[0], 0.0, 0.0, 0.0, _azimuthal_angles[2], 0.0, _azimuthal_angles[3], 0.0, 0.0, 0.0, _azimuthal_angles[5], 0.0, ]), ) assert np.allclose( driven_control.detunings, np.array([ 0.0, 0.0, 0.0, _maximum_detuning_rate, 0.0, 0.0, 0.0, 0.0, 0.0, -_maximum_detuning_rate, 0.0, 0.0, 0.0, ]), ) assert np.allclose( driven_control.durations, np.array([ 4.875e-1, 2.5e-2, 9.75e-1, 2.5e-2, 9.75e-1, 2.5e-2, 9.75e-1, 2.5e-2, 9.75e-1, 2.5e-2, 9.75e-1, 2.5e-2, 4.875e-1, ]), )
def test_dynamical_decoupling_sequence(): """ Tests the Dynamic Decoupling Sequence class. """ _duration = 2.0 _offsets = np.array([0.25, 0.5, 0.75, 1.00, 1.25, 1.50, 1.75]) _rabi_rotations = np.array( [np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi]) _azimthal_angles = 0.5 * np.array( [np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi]) _detuning_rotations = np.array([0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) _name = "test_sequence" sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimthal_angles, detuning_rotations=_detuning_rotations, name=_name, ) assert sequence.duration == _duration assert np.allclose(sequence.offsets, _offsets) assert np.allclose(sequence.rabi_rotations, _rabi_rotations) assert np.allclose(sequence.azimuthal_angles, _azimthal_angles) assert np.allclose(sequence.detuning_rotations, _detuning_rotations) assert sequence.name == _name _repr_string = "{0.__class__.__name__!s}(".format(sequence) attributes = { "duration": sequence.duration, "offsets": sequence.offsets, "rabi_rotations": sequence.rabi_rotations, "azimuthal_angles": sequence.azimuthal_angles, "detuning_rotations": sequence.detuning_rotations, "name": sequence.name, } attributes_string = ",".join( "{0}={1}".format(attribute, repr(getattr(sequence, attribute))) for attribute in attributes) _repr_string += attributes_string _repr_string += ")" assert repr(sequence) == _repr_string _duration = 2.0 _offsets = np.array([0.0, 0.25, 0.5, 0.75, 1.00, 1.25, 1.50, 1.75, 2.00]) _rabi_rotations = np.array([ np.pi / 2, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi / 2 ]) _azimthal_angles = 0.5 * np.array( [0.0, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, np.pi, 0.0]) _detuning_rotations = np.array( [0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0]) _name = "test_sequence" sequence = DynamicDecouplingSequence( duration=_duration, offsets=_offsets, rabi_rotations=_rabi_rotations, azimuthal_angles=_azimthal_angles, detuning_rotations=_detuning_rotations, name=_name, ) assert sequence.duration == _duration assert np.allclose(sequence.offsets, _offsets) assert np.allclose(sequence.rabi_rotations, _rabi_rotations) assert np.allclose(sequence.azimuthal_angles, _azimthal_angles) assert np.allclose(sequence.detuning_rotations, _detuning_rotations) assert sequence.name == _name with pytest.raises(ArgumentsValueError): # duration cannot be negative _ = DynamicDecouplingSequence( duration=-2.0, offsets=2.0 / 2000 * np.ones((2000, 1)), rabi_rotations=np.pi * np.ones((2000, 1)), azimuthal_angles=np.ones((2000, 1)), detuning_rotations=np.zeros((2000, 1)), ) with pytest.raises(ArgumentsValueError): # rabi rotations cannot be negative _ = DynamicDecouplingSequence( duration=2.0, offsets=np.ones((2, 1)), rabi_rotations=np.asarray([1, -1]), azimuthal_angles=np.ones((2, 1)), detuning_rotations=np.zeros((2, 1)), )