From 276a1ef441157d4b8e59947a0ed3bbda269fdf2a Mon Sep 17 00:00:00 2001
From: Li Li
Date: Mon, 27 Jul 2020 18:27:17 +1000
Subject: [PATCH 1/5] Add type hint
---
.../driven_controls/predefined.py | 144 +++++++++++-------
1 file changed, 93 insertions(+), 51 deletions(-)
diff --git a/qctrlopencontrols/driven_controls/predefined.py b/qctrlopencontrols/driven_controls/predefined.py
index a36dff0c..18b60b25 100644
--- a/qctrlopencontrols/driven_controls/predefined.py
+++ b/qctrlopencontrols/driven_controls/predefined.py
@@ -19,6 +19,12 @@
can be found at https://docs.q-ctrl.com/wiki/control-library
"""
+from typing import (
+ List,
+ Optional,
+ Tuple,
+)
+
import numpy as np
from ..driven_controls import (
@@ -36,7 +42,7 @@
from .driven_control import DrivenControl
-def new_predefined_driven_control(scheme=PRIMITIVE, **kwargs):
+def new_predefined_driven_control(scheme: str = PRIMITIVE, **kwargs):
"""
Create a new driven control
@@ -104,20 +110,24 @@ def new_predefined_driven_control(scheme=PRIMITIVE, **kwargs):
return driven_control
-def _predefined_common_attributes(maximum_rabi_rate, rabi_rotation, azimuthal_angle):
+def _predefined_common_attributes(
+ maximum_rabi_rate: float,
+ azimuthal_angle: float,
+ rabi_rotation: Optional[float] = None,
+) -> Tuple[float, float, Optional[float]]:
"""
Adds some checks etc for all the predefined pulses
Parameters
----------
- rabi_rotation : float
- The total polar angle to be performed by the pulse.
- Defined in polar coordinates.
maximum_rabi_rate : float
Defaults to 2.*np.pi
The maximum rabi frequency for the pulse.
azimuthal_angle : float
The azimuthal position of the pulse.
+ rabi_rotation : float, optional
+ The total polar angle to be performed by the pulse.
+ Defined in polar coordinates. Defaults to None.
Returns
-------
@@ -138,18 +148,19 @@ def _predefined_common_attributes(maximum_rabi_rate, rabi_rotation, azimuthal_an
{"maximum_rabi_rate": maximum_rabi_rate},
)
- rabi_rotation = float(rabi_rotation)
- if rabi_rotation == 0:
- raise ArgumentsValueError(
- "The rabi rotation must be non zero.", {"rabi_rotation": rabi_rotation}
- )
+ if rabi_rotation is not None:
+ rabi_rotation = float(rabi_rotation)
+ if rabi_rotation == 0:
+ raise ArgumentsValueError(
+ "The rabi rotation must be non zero.", {"rabi_rotation": rabi_rotation}
+ )
azimuthal_angle = float(azimuthal_angle)
- return (maximum_rabi_rate, rabi_rotation, azimuthal_angle)
+ return (maximum_rabi_rate, azimuthal_angle, rabi_rotation)
-def _get_transformed_rabi_rotation_wimperis(rabi_rotation):
+def _get_transformed_rabi_rotation_wimperis(rabi_rotation: float) -> float:
"""
Calculates the Rabi rotation angle as required by Wimperis 1 (BB1)
and Solovay-Kitaev driven controls.
@@ -178,7 +189,9 @@ def _get_transformed_rabi_rotation_wimperis(rabi_rotation):
return np.arccos(-rabi_rotation / (4 * np.pi))
-def _derive_segments(angles, amplitude=2.0 * np.pi):
+def _derive_segments(
+ angles: np.ndarray, amplitude: float = 2.0 * np.pi
+) -> List[List[float]]:
"""
Derive the driven control segments from a set of rabi_rotations defined in terms of the
spherical polar angles
@@ -208,8 +221,11 @@ def _derive_segments(angles, amplitude=2.0 * np.pi):
def _new_primitive_control(
- rabi_rotation=None, azimuthal_angle=0.0, maximum_rabi_rate=2.0 * np.pi, **kwargs
-):
+ rabi_rotation: Optional[float] = None,
+ azimuthal_angle: float = 0.0,
+ maximum_rabi_rate: float = 2.0 * np.pi,
+ **kwargs
+) -> DrivenControl:
"""
Primitive driven control.
@@ -230,8 +246,8 @@ def _new_primitive_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (maximum_rabi_rate, rabi_rotation, azimuthal_angle) = _predefined_common_attributes(
- maximum_rabi_rate, rabi_rotation, azimuthal_angle
+ (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
+ maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
return DrivenControl(
@@ -244,8 +260,11 @@ def _new_primitive_control(
def _new_wimperis_1_control(
- rabi_rotation=None, azimuthal_angle=0.0, maximum_rabi_rate=2.0 * np.pi, **kwargs
-):
+ rabi_rotation: Optional[float] = None,
+ azimuthal_angle: float = 0.0,
+ maximum_rabi_rate: float = 2.0 * np.pi,
+ **kwargs
+) -> DrivenControl:
"""
Wimperis or BB1 control.
@@ -266,8 +285,8 @@ def _new_wimperis_1_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (maximum_rabi_rate, rabi_rotation, azimuthal_angle) = _predefined_common_attributes(
- maximum_rabi_rate, rabi_rotation, azimuthal_angle
+ (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
+ maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
@@ -296,8 +315,11 @@ def _new_wimperis_1_control(
def _new_solovay_kitaev_1_control(
- rabi_rotation=None, azimuthal_angle=0.0, maximum_rabi_rate=2.0 * np.pi, **kwargs
-):
+ rabi_rotation: Optional[float] = None,
+ azimuthal_angle: float = 0.0,
+ maximum_rabi_rate: float = 2.0 * np.pi,
+ **kwargs
+) -> DrivenControl:
"""
First-order Solovay-Kitaev control, also known as SK1
@@ -318,8 +340,8 @@ def _new_solovay_kitaev_1_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (maximum_rabi_rate, rabi_rotation, azimuthal_angle) = _predefined_common_attributes(
- maximum_rabi_rate, rabi_rotation, azimuthal_angle
+ (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
+ maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
@@ -347,10 +369,13 @@ def _new_solovay_kitaev_1_control(
def _short_composite_rotation_for_undoing_length_over_under_shoot_control(
- rabi_rotation=None, azimuthal_angle=0.0, maximum_rabi_rate=2.0 * np.pi, **kwargs
-):
+ rabi_rotation: Optional[float] = None,
+ azimuthal_angle: float = 0.0,
+ maximum_rabi_rate: float = 2.0 * np.pi,
+ **kwargs
+) -> DrivenControl:
"""
- SCROFULOUS control to compensate for pulse length errors
+ SCROFULOUS control to compensate for pulse length errors.
Parameters
----------
@@ -374,8 +399,8 @@ def _short_composite_rotation_for_undoing_length_over_under_shoot_control(
ArgumentsValueError
Raised when an argument is invalid.
"""
- (maximum_rabi_rate, rabi_rotation, azimuthal_angle) = _predefined_common_attributes(
- maximum_rabi_rate, rabi_rotation, azimuthal_angle
+ (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
+ maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
# Create a lookup table for rabi rotation and phase angles, taken from the official paper.
@@ -434,8 +459,11 @@ def degrees_to_radians(angle_in_degrees):
def _new_compensating_for_off_resonance_with_a_pulse_sequence_control(
- rabi_rotation=None, azimuthal_angle=0.0, maximum_rabi_rate=2.0 * np.pi, **kwargs
-):
+ rabi_rotation: Optional[float] = None,
+ azimuthal_angle: float = 0.0,
+ maximum_rabi_rate: float = 2.0 * np.pi,
+ **kwargs
+) -> DrivenControl:
"""
Compensating for off resonance with a pulse sequence, often abbreviated as CORPSE.
@@ -456,9 +484,11 @@ def _new_compensating_for_off_resonance_with_a_pulse_sequence_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (maximum_rabi_rate, rabi_rotation, azimuthal_angle) = _predefined_common_attributes(
- maximum_rabi_rate, rabi_rotation, azimuthal_angle
- )
+ (
+ maximum_rabi_rate,
+ azimuthal_angle,
+ rabi_rotation,
+ ) = _predefined_common_attributes(maximum_rabi_rate, azimuthal_angle, rabi_rotation)
k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
@@ -485,8 +515,11 @@ def _new_compensating_for_off_resonance_with_a_pulse_sequence_control(
def _new_compensating_for_off_resonance_with_a_sequence_with_wimperis_control(
- rabi_rotation=None, azimuthal_angle=0.0, maximum_rabi_rate=2.0 * np.pi, **kwargs
-):
+ rabi_rotation: Optional[float] = None,
+ azimuthal_angle: float = 0.0,
+ maximum_rabi_rate: float = 2.0 * np.pi,
+ **kwargs
+) -> DrivenControl:
"""
Compensating for off resonance with a pulse sequence with an embedded
Wimperis (or BB1) control, also known as CinBB.
@@ -508,8 +541,8 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_wimperis_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (maximum_rabi_rate, rabi_rotation, azimuthal_angle) = _predefined_common_attributes(
- maximum_rabi_rate, rabi_rotation, azimuthal_angle
+ (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
+ maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
@@ -548,8 +581,11 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_wimperis_control(
def _new_compensating_for_off_resonance_with_a_sequence_with_sk_control(
- rabi_rotation=None, azimuthal_angle=0.0, maximum_rabi_rate=2.0 * np.pi, **kwargs
-):
+ rabi_rotation: Optional[float] = None,
+ azimuthal_angle: float = 0.0,
+ maximum_rabi_rate: float = 2.0 * np.pi,
+ **kwargs
+) -> DrivenControl:
"""
Compensating for off resonance with a pulse sequence with an
embedded Solovay Kitaev (or SK1) control, also knowns as CinSK.
@@ -571,8 +607,8 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_sk_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (maximum_rabi_rate, rabi_rotation, azimuthal_angle) = _predefined_common_attributes(
- maximum_rabi_rate, rabi_rotation, azimuthal_angle
+ (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
+ maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
@@ -609,8 +645,11 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_sk_control(
def _new_corpse_in_scrofulous_control(
- rabi_rotation=None, azimuthal_angle=0.0, maximum_rabi_rate=2.0 * np.pi, **kwargs
-):
+ rabi_rotation: Optional[float] = None,
+ azimuthal_angle: float = 0.0,
+ maximum_rabi_rate: float = 2.0 * np.pi,
+ **kwargs
+) -> DrivenControl:
"""
CORPSE (Compensating for Off Resonance with a Pulse SEquence) embedded within a
SCROFULOUS (Short Composite ROtation For Undoing Length Over and Under Shoot) control,
@@ -638,8 +677,8 @@ def _new_corpse_in_scrofulous_control(
ArgumentsValueError
Raised when an argument is invalid.
"""
- (maximum_rabi_rate, rabi_rotation, azimuthal_angle) = _predefined_common_attributes(
- maximum_rabi_rate, rabi_rotation, azimuthal_angle
+ (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
+ maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
# Create a lookup table for rabi rotation and phase angles, taken from
@@ -708,8 +747,11 @@ def degrees_to_radians(angle_in_degrees):
def _new_walsh_amplitude_modulated_filter_1_control(
- rabi_rotation=None, azimuthal_angle=0.0, maximum_rabi_rate=2.0 * np.pi, **kwargs
-):
+ rabi_rotation: Optional[float] = None,
+ azimuthal_angle: float = 0.0,
+ maximum_rabi_rate: float = 2.0 * np.pi,
+ **kwargs
+) -> DrivenControl:
"""
First order Walsh control with amplitude modulation.
@@ -735,8 +777,8 @@ def _new_walsh_amplitude_modulated_filter_1_control(
ArgumentsValueError
Raised when an argument is invalid.
"""
- (maximum_rabi_rate, rabi_rotation, azimuthal_angle) = _predefined_common_attributes(
- maximum_rabi_rate, rabi_rotation, azimuthal_angle
+ (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
+ maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
if np.isclose(rabi_rotation, np.pi):
From 7ac763e4e78843a61d9877c895893ba8e1caa0f3 Mon Sep 17 00:00:00 2001
From: Li Li
Date: Mon, 27 Jul 2020 18:57:27 +1000
Subject: [PATCH 2/5] Refactor due to type issue
---
.../driven_controls/predefined.py | 199 +++++++++---------
1 file changed, 101 insertions(+), 98 deletions(-)
diff --git a/qctrlopencontrols/driven_controls/predefined.py b/qctrlopencontrols/driven_controls/predefined.py
index 18b60b25..18119476 100644
--- a/qctrlopencontrols/driven_controls/predefined.py
+++ b/qctrlopencontrols/driven_controls/predefined.py
@@ -2,9 +2,7 @@
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at
-#
-# http://www.apache.org/licenses/LICENSE-2.0
+# You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -249,13 +247,17 @@ def _new_primitive_control(
(maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
+ if rabi_rotation is None:
+ durations = None
+ else:
+ durations = ([rabi_rotation / maximum_rabi_rate],)
return DrivenControl(
rabi_rates=[maximum_rabi_rate],
azimuthal_angles=[azimuthal_angle],
detunings=[0],
- durations=[rabi_rotation / maximum_rabi_rate],
- **kwargs
+ durations=durations,
+ **kwargs,
)
@@ -288,10 +290,9 @@ def _new_wimperis_1_control(
(maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
-
- phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
-
- rabi_rotations = [rabi_rotation, np.pi, 2 * np.pi, np.pi]
+ if rabi_rotation is not None:
+ phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
+ rabi_rotations = [rabi_rotation, np.pi, 2 * np.pi, np.pi]
rabi_rates = [maximum_rabi_rate] * 4
azimuthal_angles = [
@@ -310,7 +311,7 @@ def _new_wimperis_1_control(
azimuthal_angles=azimuthal_angles,
detunings=detunings,
durations=durations,
- **kwargs
+ **kwargs,
)
@@ -344,9 +345,9 @@ def _new_solovay_kitaev_1_control(
maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
- phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
-
- rabi_rotations = [rabi_rotation, 2 * np.pi, 2 * np.pi]
+ if rabi_rotation is not None:
+ phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
+ rabi_rotations = [rabi_rotation, 2 * np.pi, 2 * np.pi]
rabi_rates = [maximum_rabi_rate] * 3
azimuthal_angles = [
@@ -364,7 +365,7 @@ def _new_solovay_kitaev_1_control(
azimuthal_angles=azimuthal_angles,
detunings=detunings,
durations=durations,
- **kwargs
+ **kwargs,
)
@@ -408,29 +409,30 @@ def _short_composite_rotation_for_undoing_length_over_under_shoot_control(
def degrees_to_radians(angle_in_degrees):
return angle_in_degrees / 180 * np.pi
- if np.isclose(rabi_rotation, np.pi):
- theta_1 = degrees_to_radians(180.0)
- phi_1 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- elif np.isclose(rabi_rotation, 0.5 * np.pi):
- theta_1 = degrees_to_radians(115.2)
- phi_1 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- elif np.isclose(rabi_rotation, 0.25 * np.pi):
- theta_1 = degrees_to_radians(96.7)
- phi_1 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- else:
- raise ArgumentsValueError(
- "rabi_rotation angle must be either pi, pi/2 or pi/4",
- {"rabi_rotation": rabi_rotation},
- )
+ if rabi_rotation is not None:
+ if np.isclose(rabi_rotation, np.pi):
+ theta_1 = degrees_to_radians(180.0)
+ phi_1 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ elif np.isclose(rabi_rotation, 0.5 * np.pi):
+ theta_1 = degrees_to_radians(115.2)
+ phi_1 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ elif np.isclose(rabi_rotation, 0.25 * np.pi):
+ theta_1 = degrees_to_radians(96.7)
+ phi_1 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ else:
+ raise ArgumentsValueError(
+ "rabi_rotation angle must be either pi, pi/2 or pi/4",
+ {"rabi_rotation": rabi_rotation},
+ )
theta_3 = theta_1
phi_3 = phi_1
@@ -454,7 +456,7 @@ def degrees_to_radians(angle_in_degrees):
azimuthal_angles=azimuthal_angles,
detunings=detunings,
durations=durations,
- **kwargs
+ **kwargs,
)
@@ -490,13 +492,13 @@ def _new_compensating_for_off_resonance_with_a_pulse_sequence_control(
rabi_rotation,
) = _predefined_common_attributes(maximum_rabi_rate, azimuthal_angle, rabi_rotation)
- k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
-
- rabi_rotations = [
- rabi_rotation / 2.0 + 2 * np.pi - k,
- 2 * np.pi - 2 * k,
- rabi_rotation / 2.0 - k,
- ]
+ if rabi_rotation is not None:
+ k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
+ rabi_rotations = [
+ rabi_rotation / 2.0 + 2 * np.pi - k,
+ 2 * np.pi - 2 * k,
+ rabi_rotation / 2.0 - k,
+ ]
rabi_rates = [maximum_rabi_rate] * 3
azimuthal_angles = [azimuthal_angle, azimuthal_angle + np.pi, azimuthal_angle]
@@ -510,7 +512,7 @@ def _new_compensating_for_off_resonance_with_a_pulse_sequence_control(
azimuthal_angles=azimuthal_angles,
detunings=detunings,
durations=durations,
- **kwargs
+ **kwargs,
)
@@ -545,17 +547,18 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_wimperis_control(
maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
- phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
- k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
-
- rabi_rotations = [
- 2 * np.pi + rabi_rotation / 2.0 - k,
- 2 * np.pi - 2 * k,
- rabi_rotation / 2.0 - k,
- np.pi,
- 2 * np.pi,
- np.pi,
- ]
+ if rabi_rotation is not None:
+ phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
+ k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
+
+ rabi_rotations = [
+ 2 * np.pi + rabi_rotation / 2.0 - k,
+ 2 * np.pi - 2 * k,
+ rabi_rotation / 2.0 - k,
+ np.pi,
+ 2 * np.pi,
+ np.pi,
+ ]
rabi_rates = [maximum_rabi_rate] * 6
azimuthal_angles = [
@@ -576,7 +579,7 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_wimperis_control(
azimuthal_angles=azimuthal_angles,
detunings=detunings,
durations=durations,
- **kwargs
+ **kwargs,
)
@@ -610,17 +613,17 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_sk_control(
(maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
maximum_rabi_rate, azimuthal_angle, rabi_rotation
)
+ if rabi_rotation is not None:
+ phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
+ k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
- phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
- k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
-
- rabi_rotations = [
- 2 * np.pi + rabi_rotation / 2.0 - k,
- 2 * np.pi - 2 * k,
- rabi_rotation / 2.0 - k,
- 2 * np.pi,
- 2 * np.pi,
- ]
+ rabi_rotations = [
+ 2 * np.pi + rabi_rotation / 2.0 - k,
+ 2 * np.pi - 2 * k,
+ rabi_rotation / 2.0 - k,
+ 2 * np.pi,
+ 2 * np.pi,
+ ]
rabi_rates = [maximum_rabi_rate] * 5
azimuthal_angles = [
@@ -640,7 +643,7 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_sk_control(
azimuthal_angles=azimuthal_angles,
detunings=detunings,
durations=durations,
- **kwargs
+ **kwargs,
)
@@ -686,33 +689,34 @@ def _new_corpse_in_scrofulous_control(
def degrees_to_radians(angle_in_degrees):
return angle_in_degrees / 180 * np.pi
- if np.isclose(rabi_rotation, np.pi):
- theta_1 = theta_3 = degrees_to_radians(180.0)
- phi_1 = phi_3 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- elif np.isclose(rabi_rotation, 0.5 * np.pi):
- theta_1 = theta_3 = degrees_to_radians(115.2)
- phi_1 = phi_3 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- elif np.isclose(rabi_rotation, 0.25 * np.pi):
- theta_1 = theta_3 = degrees_to_radians(96.7)
- phi_1 = phi_3 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- else:
- raise ArgumentsValueError(
- "rabi_rotation angle must be either pi, pi/2 or pi/4",
- {"rabi_rotation": rabi_rotation},
- )
+ if rabi_rotation is not None:
+ if np.isclose(rabi_rotation, np.pi):
+ theta_1 = theta_3 = degrees_to_radians(180.0)
+ phi_1 = phi_3 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ elif np.isclose(rabi_rotation, 0.5 * np.pi):
+ theta_1 = theta_3 = degrees_to_radians(115.2)
+ phi_1 = phi_3 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ elif np.isclose(rabi_rotation, 0.25 * np.pi):
+ theta_1 = theta_3 = degrees_to_radians(96.7)
+ phi_1 = phi_3 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ else:
+ raise ArgumentsValueError(
+ "rabi_rotation angle must be either pi, pi/2 or pi/4",
+ {"rabi_rotation": rabi_rotation},
+ )
theta_2 = np.pi
- total_angles = []
+ _total_angles = []
# Loop over all SCROFULOUS Rabi rotations (theta) and azimuthal angles (phi)
# And make CORPSEs with those.
for theta, phi in zip([theta_1, theta_2, theta_3], [phi_1, phi_2, phi_3]):
@@ -724,10 +728,9 @@ def degrees_to_radians(angle_in_degrees):
[theta / 2.0 - k, phi + azimuthal_angle],
]
)
- total_angles.append(angles)
-
- total_angles = np.vstack(total_angles)
+ _total_angles.append(angles)
+ total_angles = np.vstack(_total_angles)
rabi_rotations = total_angles[:, 0]
rabi_rates = [maximum_rabi_rate] * 9
@@ -742,7 +745,7 @@ def degrees_to_radians(angle_in_degrees):
azimuthal_angles=azimuthal_angles,
detunings=detunings,
durations=durations,
- **kwargs
+ **kwargs,
)
@@ -811,5 +814,5 @@ def _new_walsh_amplitude_modulated_filter_1_control(
azimuthal_angles=azimuthal_angles,
detunings=detunings,
durations=durations,
- **kwargs
+ **kwargs,
)
From 8ef2868189c4280a22c6d0b2a4a4478fed1cc432 Mon Sep 17 00:00:00 2001
From: Li Li
Date: Mon, 27 Jul 2020 19:12:04 +1000
Subject: [PATCH 3/5] Fix docstring
---
qctrlopencontrols/driven_controls/predefined.py | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/qctrlopencontrols/driven_controls/predefined.py b/qctrlopencontrols/driven_controls/predefined.py
index 18119476..0357af01 100644
--- a/qctrlopencontrols/driven_controls/predefined.py
+++ b/qctrlopencontrols/driven_controls/predefined.py
@@ -2,7 +2,9 @@
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
-# You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0
+# You may obtain a copy of the License at
+#
+# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
@@ -192,7 +194,7 @@ def _derive_segments(
) -> List[List[float]]:
"""
Derive the driven control segments from a set of rabi_rotations defined in terms of the
- spherical polar angles
+ spherical polar angles.
Parameters
----------
@@ -322,7 +324,7 @@ def _new_solovay_kitaev_1_control(
**kwargs
) -> DrivenControl:
"""
- First-order Solovay-Kitaev control, also known as SK1
+ First-order Solovay-Kitaev control, also known as SK1.
Parameters
----------
From c07621d8dd8a56bc76fe62bac7e23bb0e85c7a1e Mon Sep 17 00:00:00 2001
From: Li Li
Date: Tue, 28 Jul 2020 10:01:15 +1000
Subject: [PATCH 4/5] Make `rabi_rotation` required
---
.../driven_controls/predefined.py | 286 +++++++++---------
1 file changed, 140 insertions(+), 146 deletions(-)
diff --git a/qctrlopencontrols/driven_controls/predefined.py b/qctrlopencontrols/driven_controls/predefined.py
index 0357af01..3ac40bda 100644
--- a/qctrlopencontrols/driven_controls/predefined.py
+++ b/qctrlopencontrols/driven_controls/predefined.py
@@ -21,7 +21,6 @@
from typing import (
List,
- Optional,
Tuple,
)
@@ -111,29 +110,27 @@ def new_predefined_driven_control(scheme: str = PRIMITIVE, **kwargs):
def _predefined_common_attributes(
- maximum_rabi_rate: float,
- azimuthal_angle: float,
- rabi_rotation: Optional[float] = None,
-) -> Tuple[float, float, Optional[float]]:
+ azimuthal_angle: float, rabi_rotation: float, maximum_rabi_rate: float = 2 * np.pi,
+) -> Tuple[float, float, float]:
"""
Adds some checks etc for all the predefined pulses
Parameters
----------
- maximum_rabi_rate : float
- Defaults to 2.*np.pi
- The maximum rabi frequency for the pulse.
azimuthal_angle : float
The azimuthal position of the pulse.
- rabi_rotation : float, optional
+ rabi_rotation : float
The total polar angle to be performed by the pulse.
Defined in polar coordinates. Defaults to None.
+ maximum_rabi_rate : float, optional
+ Defaults to 2.*np.pi
+ The maximum rabi frequency for the pulse.
Returns
-------
tuple
Tuple of floats made of:
- (rabi_rate, rabi_rotation, azimuthal)
+ (azimuthal, rabi_rotation, maximum_rabi_rate)
Raises
------
@@ -148,16 +145,15 @@ def _predefined_common_attributes(
{"maximum_rabi_rate": maximum_rabi_rate},
)
- if rabi_rotation is not None:
- rabi_rotation = float(rabi_rotation)
- if rabi_rotation == 0:
- raise ArgumentsValueError(
- "The rabi rotation must be non zero.", {"rabi_rotation": rabi_rotation}
- )
+ rabi_rotation = float(rabi_rotation)
+ if rabi_rotation == 0:
+ raise ArgumentsValueError(
+ "The rabi rotation must be non zero.", {"rabi_rotation": rabi_rotation}
+ )
azimuthal_angle = float(azimuthal_angle)
- return (maximum_rabi_rate, azimuthal_angle, rabi_rotation)
+ return (azimuthal_angle, rabi_rotation, maximum_rabi_rate)
def _get_transformed_rabi_rotation_wimperis(rabi_rotation: float) -> float:
@@ -168,12 +164,12 @@ def _get_transformed_rabi_rotation_wimperis(rabi_rotation: float) -> float:
Parameters
----------
rabi_rotation : float
- Rotation angle of the operation
+ Rotation angle of the operation.
Returns
-------
float
- The transformed angle as per definition for the Wimperis 1 (BB1) control
+ The transformed angle as per definition for the Wimperis 1 (BB1) control.
Raises
------
@@ -221,7 +217,7 @@ def _derive_segments(
def _new_primitive_control(
- rabi_rotation: Optional[float] = None,
+ rabi_rotation: float,
azimuthal_angle: float = 0.0,
maximum_rabi_rate: float = 2.0 * np.pi,
**kwargs
@@ -231,13 +227,13 @@ def _new_primitive_control(
Parameters
----------
- rabi_rotation : float, optional
+ rabi_rotation : float
The total rabi rotation to be performed by the driven control.
maximum_rabi_rate : float, optional
Defaults to 2.*np.pi
The maximum rabi frequency for the driven control.
azimuthal_angle : float, optional
- The azimuthal position of the driven control.
+ The azimuthal position of the driven control. Defaults to 0.
kwargs : dict
Other keywords required to make a qctrlopencontrols.DrivenControls.
@@ -246,25 +242,22 @@ def _new_primitive_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
- maximum_rabi_rate, azimuthal_angle, rabi_rotation
+
+ (azimuthal_angle, rabi_rotation, maximum_rabi_rate) = _predefined_common_attributes(
+ azimuthal_angle, rabi_rotation, maximum_rabi_rate
)
- if rabi_rotation is None:
- durations = None
- else:
- durations = ([rabi_rotation / maximum_rabi_rate],)
return DrivenControl(
rabi_rates=[maximum_rabi_rate],
azimuthal_angles=[azimuthal_angle],
detunings=[0],
- durations=durations,
+ durations=[rabi_rotation / maximum_rabi_rate],
**kwargs,
)
def _new_wimperis_1_control(
- rabi_rotation: Optional[float] = None,
+ rabi_rotation: float,
azimuthal_angle: float = 0.0,
maximum_rabi_rate: float = 2.0 * np.pi,
**kwargs
@@ -280,6 +273,7 @@ def _new_wimperis_1_control(
Defaults to 2.*np.pi
The maximum rabi frequency for the control.
azimuthal_angle : float, optional
+ Defaults to 0.
The azimuthal position of the control.
kwargs : dict
Other keywords required to make a qctrlopencontrols.DrivenControls.
@@ -289,12 +283,12 @@ def _new_wimperis_1_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
- maximum_rabi_rate, azimuthal_angle, rabi_rotation
+ (azimuthal_angle, rabi_rotation, maximum_rabi_rate) = _predefined_common_attributes(
+ azimuthal_angle, rabi_rotation, maximum_rabi_rate
)
- if rabi_rotation is not None:
- phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
- rabi_rotations = [rabi_rotation, np.pi, 2 * np.pi, np.pi]
+
+ phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
+ rabi_rotations = [rabi_rotation, np.pi, 2 * np.pi, np.pi]
rabi_rates = [maximum_rabi_rate] * 4
azimuthal_angles = [
@@ -318,7 +312,7 @@ def _new_wimperis_1_control(
def _new_solovay_kitaev_1_control(
- rabi_rotation: Optional[float] = None,
+ rabi_rotation: float,
azimuthal_angle: float = 0.0,
maximum_rabi_rate: float = 2.0 * np.pi,
**kwargs
@@ -334,6 +328,7 @@ def _new_solovay_kitaev_1_control(
Defaults to 2.*np.pi
The maximum rabi frequency for the control.
azimuthal_angle : float, optional
+ Defaults to 0.
The azimuthal position of the control.
kwargs : dict
Other keywords required to make a qctrlopencontrols.DrivenControls.
@@ -343,13 +338,12 @@ def _new_solovay_kitaev_1_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
- maximum_rabi_rate, azimuthal_angle, rabi_rotation
+ (azimuthal_angle, rabi_rotation, maximum_rabi_rate) = _predefined_common_attributes(
+ azimuthal_angle, rabi_rotation, maximum_rabi_rate
)
- if rabi_rotation is not None:
- phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
- rabi_rotations = [rabi_rotation, 2 * np.pi, 2 * np.pi]
+ phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
+ rabi_rotations = [rabi_rotation, 2 * np.pi, 2 * np.pi]
rabi_rates = [maximum_rabi_rate] * 3
azimuthal_angles = [
@@ -372,7 +366,7 @@ def _new_solovay_kitaev_1_control(
def _short_composite_rotation_for_undoing_length_over_under_shoot_control(
- rabi_rotation: Optional[float] = None,
+ rabi_rotation: float,
azimuthal_angle: float = 0.0,
maximum_rabi_rate: float = 2.0 * np.pi,
**kwargs
@@ -382,12 +376,13 @@ def _short_composite_rotation_for_undoing_length_over_under_shoot_control(
Parameters
----------
- rabi_rotation : float, optional
+ rabi_rotation : float
The total rabi rotation to be performed by the control.
maximum_rabi_rate : float, optional
Defaults to 2.*np.pi
The maximum rabi frequency for the control.
azimuthal_angle : float, optional
+ Defaults to 0.
The azimuthal position of the control.
kwargs : dict
Other keywords required to make a qctrlopencontrols.DrivenControls.
@@ -402,8 +397,8 @@ def _short_composite_rotation_for_undoing_length_over_under_shoot_control(
ArgumentsValueError
Raised when an argument is invalid.
"""
- (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
- maximum_rabi_rate, azimuthal_angle, rabi_rotation
+ (azimuthal_angle, rabi_rotation, maximum_rabi_rate) = _predefined_common_attributes(
+ azimuthal_angle, rabi_rotation, maximum_rabi_rate
)
# Create a lookup table for rabi rotation and phase angles, taken from the official paper.
@@ -411,30 +406,29 @@ def _short_composite_rotation_for_undoing_length_over_under_shoot_control(
def degrees_to_radians(angle_in_degrees):
return angle_in_degrees / 180 * np.pi
- if rabi_rotation is not None:
- if np.isclose(rabi_rotation, np.pi):
- theta_1 = degrees_to_radians(180.0)
- phi_1 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- elif np.isclose(rabi_rotation, 0.5 * np.pi):
- theta_1 = degrees_to_radians(115.2)
- phi_1 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- elif np.isclose(rabi_rotation, 0.25 * np.pi):
- theta_1 = degrees_to_radians(96.7)
- phi_1 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- else:
- raise ArgumentsValueError(
- "rabi_rotation angle must be either pi, pi/2 or pi/4",
- {"rabi_rotation": rabi_rotation},
- )
+ if np.isclose(rabi_rotation, np.pi):
+ theta_1 = degrees_to_radians(180.0)
+ phi_1 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ elif np.isclose(rabi_rotation, 0.5 * np.pi):
+ theta_1 = degrees_to_radians(115.2)
+ phi_1 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ elif np.isclose(rabi_rotation, 0.25 * np.pi):
+ theta_1 = degrees_to_radians(96.7)
+ phi_1 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ else:
+ raise ArgumentsValueError(
+ "rabi_rotation angle must be either pi, pi/2 or pi/4",
+ {"rabi_rotation": rabi_rotation},
+ )
theta_3 = theta_1
phi_3 = phi_1
@@ -463,7 +457,7 @@ def degrees_to_radians(angle_in_degrees):
def _new_compensating_for_off_resonance_with_a_pulse_sequence_control(
- rabi_rotation: Optional[float] = None,
+ rabi_rotation: float,
azimuthal_angle: float = 0.0,
maximum_rabi_rate: float = 2.0 * np.pi,
**kwargs
@@ -473,12 +467,13 @@ def _new_compensating_for_off_resonance_with_a_pulse_sequence_control(
Parameters
----------
- rabi_rotation : float, optional
+ rabi_rotation : float
The total rabi rotation to be performed by the control.
maximum_rabi_rate : float, optional
- Defaults to 2.*np.pi
+ Defaults to 2*np.pi.
The maximum rabi frequency for the control.
azimuthal_angle : float, optional
+ Defaults to 0.
The azimuthal position of the control.
kwargs : dict
Other keywords required to make a qctrlopencontrols.DrivenControls.
@@ -488,19 +483,16 @@ def _new_compensating_for_off_resonance_with_a_pulse_sequence_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (
- maximum_rabi_rate,
- azimuthal_angle,
- rabi_rotation,
- ) = _predefined_common_attributes(maximum_rabi_rate, azimuthal_angle, rabi_rotation)
+ (azimuthal_angle, rabi_rotation, maximum_rabi_rate) = _predefined_common_attributes(
+ azimuthal_angle, rabi_rotation, maximum_rabi_rate
+ )
- if rabi_rotation is not None:
- k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
- rabi_rotations = [
- rabi_rotation / 2.0 + 2 * np.pi - k,
- 2 * np.pi - 2 * k,
- rabi_rotation / 2.0 - k,
- ]
+ k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
+ rabi_rotations = [
+ rabi_rotation / 2.0 + 2 * np.pi - k,
+ 2 * np.pi - 2 * k,
+ rabi_rotation / 2.0 - k,
+ ]
rabi_rates = [maximum_rabi_rate] * 3
azimuthal_angles = [azimuthal_angle, azimuthal_angle + np.pi, azimuthal_angle]
@@ -519,7 +511,7 @@ def _new_compensating_for_off_resonance_with_a_pulse_sequence_control(
def _new_compensating_for_off_resonance_with_a_sequence_with_wimperis_control(
- rabi_rotation: Optional[float] = None,
+ rabi_rotation: float,
azimuthal_angle: float = 0.0,
maximum_rabi_rate: float = 2.0 * np.pi,
**kwargs
@@ -530,12 +522,13 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_wimperis_control(
Parameters
----------
- rabi_rotation : float, optional
+ rabi_rotation : float
The total rabi rotation to be performed by the control.
maximum_rabi_rate : float, optional
Defaults to 2.*np.pi
The maximum rabi frequency for the control.
azimuthal_angle : float, optional
+ Defaults to 0.
The azimuthal position of the control.
kwargs : dict
Other keywords required to make a qctrlopencontrols.DrivenControls.
@@ -545,22 +538,22 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_wimperis_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
- maximum_rabi_rate, azimuthal_angle, rabi_rotation
+
+ (azimuthal_angle, rabi_rotation, maximum_rabi_rate) = _predefined_common_attributes(
+ azimuthal_angle, rabi_rotation, maximum_rabi_rate
)
- if rabi_rotation is not None:
- phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
- k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
+ phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
+ k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
- rabi_rotations = [
- 2 * np.pi + rabi_rotation / 2.0 - k,
- 2 * np.pi - 2 * k,
- rabi_rotation / 2.0 - k,
- np.pi,
- 2 * np.pi,
- np.pi,
- ]
+ rabi_rotations = [
+ 2 * np.pi + rabi_rotation / 2.0 - k,
+ 2 * np.pi - 2 * k,
+ rabi_rotation / 2.0 - k,
+ np.pi,
+ 2 * np.pi,
+ np.pi,
+ ]
rabi_rates = [maximum_rabi_rate] * 6
azimuthal_angles = [
@@ -586,7 +579,7 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_wimperis_control(
def _new_compensating_for_off_resonance_with_a_sequence_with_sk_control(
- rabi_rotation: Optional[float] = None,
+ rabi_rotation: float,
azimuthal_angle: float = 0.0,
maximum_rabi_rate: float = 2.0 * np.pi,
**kwargs
@@ -597,12 +590,13 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_sk_control(
Parameters
----------
- rabi_rotation : float, optional
+ rabi_rotation : float
The total rabi rotation to be performed by the control.
maximum_rabi_rate : float, optional
Defaults to 2.*np.pi
The maximum rabi frequency for the control.
azimuthal_angle : float, optional
+ Defaults to 0.
The azimuthal position of the control.
kwargs : dict
Other keywords required to make a qctrlopencontrols.DrivenControls.
@@ -612,20 +606,19 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_sk_control(
qctrlopencontrols.DrivenControl
The driven control.
"""
- (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
- maximum_rabi_rate, azimuthal_angle, rabi_rotation
+ (azimuthal_angle, rabi_rotation, maximum_rabi_rate) = _predefined_common_attributes(
+ azimuthal_angle, rabi_rotation, maximum_rabi_rate
)
- if rabi_rotation is not None:
- phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
- k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
-
- rabi_rotations = [
- 2 * np.pi + rabi_rotation / 2.0 - k,
- 2 * np.pi - 2 * k,
- rabi_rotation / 2.0 - k,
- 2 * np.pi,
- 2 * np.pi,
- ]
+ phi_p = _get_transformed_rabi_rotation_wimperis(rabi_rotation)
+ k = np.arcsin(np.sin(rabi_rotation / 2.0) / 2.0)
+
+ rabi_rotations = [
+ 2 * np.pi + rabi_rotation / 2.0 - k,
+ 2 * np.pi - 2 * k,
+ rabi_rotation / 2.0 - k,
+ 2 * np.pi,
+ 2 * np.pi,
+ ]
rabi_rates = [maximum_rabi_rate] * 5
azimuthal_angles = [
@@ -650,7 +643,7 @@ def _new_compensating_for_off_resonance_with_a_sequence_with_sk_control(
def _new_corpse_in_scrofulous_control(
- rabi_rotation: Optional[float] = None,
+ rabi_rotation: float,
azimuthal_angle: float = 0.0,
maximum_rabi_rate: float = 2.0 * np.pi,
**kwargs
@@ -662,12 +655,13 @@ def _new_corpse_in_scrofulous_control(
Parameters
----------
- rabi_rotation : float, optional
+ rabi_rotation : float
The total rabi rotation to be performed by the control.
maximum_rabi_rate : float, optional
Defaults to 2.*np.pi
The maximum rabi frequency for the control.
azimuthal_angle : float, optional
+ Defaults to 0.
The azimuthal position of the control.
kwargs : dict
Other keywords required to make a qctrlopencontrols.DrivenControls.
@@ -682,8 +676,8 @@ def _new_corpse_in_scrofulous_control(
ArgumentsValueError
Raised when an argument is invalid.
"""
- (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
- maximum_rabi_rate, azimuthal_angle, rabi_rotation
+ (azimuthal_angle, rabi_rotation, maximum_rabi_rate) = _predefined_common_attributes(
+ azimuthal_angle, rabi_rotation, maximum_rabi_rate
)
# Create a lookup table for rabi rotation and phase angles, taken from
@@ -691,30 +685,29 @@ def _new_corpse_in_scrofulous_control(
def degrees_to_radians(angle_in_degrees):
return angle_in_degrees / 180 * np.pi
- if rabi_rotation is not None:
- if np.isclose(rabi_rotation, np.pi):
- theta_1 = theta_3 = degrees_to_radians(180.0)
- phi_1 = phi_3 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- elif np.isclose(rabi_rotation, 0.5 * np.pi):
- theta_1 = theta_3 = degrees_to_radians(115.2)
- phi_1 = phi_3 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- elif np.isclose(rabi_rotation, 0.25 * np.pi):
- theta_1 = theta_3 = degrees_to_radians(96.7)
- phi_1 = phi_3 = np.arccos(
- -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
- )
- phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
- else:
- raise ArgumentsValueError(
- "rabi_rotation angle must be either pi, pi/2 or pi/4",
- {"rabi_rotation": rabi_rotation},
- )
+ if np.isclose(rabi_rotation, np.pi):
+ theta_1 = theta_3 = degrees_to_radians(180.0)
+ phi_1 = phi_3 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ elif np.isclose(rabi_rotation, 0.5 * np.pi):
+ theta_1 = theta_3 = degrees_to_radians(115.2)
+ phi_1 = phi_3 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ elif np.isclose(rabi_rotation, 0.25 * np.pi):
+ theta_1 = theta_3 = degrees_to_radians(96.7)
+ phi_1 = phi_3 = np.arccos(
+ -np.pi * np.cos(theta_1) / 2 / theta_1 / np.sin(rabi_rotation / 2)
+ )
+ phi_2 = phi_1 - np.arccos(-np.pi / 2 / theta_1)
+ else:
+ raise ArgumentsValueError(
+ "rabi_rotation angle must be either pi, pi/2 or pi/4",
+ {"rabi_rotation": rabi_rotation},
+ )
theta_2 = np.pi
@@ -752,7 +745,7 @@ def degrees_to_radians(angle_in_degrees):
def _new_walsh_amplitude_modulated_filter_1_control(
- rabi_rotation: Optional[float] = None,
+ rabi_rotation: float,
azimuthal_angle: float = 0.0,
maximum_rabi_rate: float = 2.0 * np.pi,
**kwargs
@@ -762,12 +755,13 @@ def _new_walsh_amplitude_modulated_filter_1_control(
Parameters
----------
- rabi_rotation : float, optional
+ rabi_rotation : float
The total rabi rotation to be performed by the control.
maximum_rabi_rate : float, optional
Defaults to 2.*np.pi
The maximum rabi frequency for the control.
azimuthal_angle : float, optional
+ Defaults to 0.
The azimuthal position of the control.
kwargs : dict
Other keywords required to make a qctrlopencontrols.DrivenControls.
@@ -782,8 +776,8 @@ def _new_walsh_amplitude_modulated_filter_1_control(
ArgumentsValueError
Raised when an argument is invalid.
"""
- (maximum_rabi_rate, azimuthal_angle, rabi_rotation) = _predefined_common_attributes(
- maximum_rabi_rate, azimuthal_angle, rabi_rotation
+ (azimuthal_angle, rabi_rotation, maximum_rabi_rate) = _predefined_common_attributes(
+ azimuthal_angle, rabi_rotation, maximum_rabi_rate
)
if np.isclose(rabi_rotation, np.pi):
From b9338c30f0590ef4464662f37f0388bbbdd92942 Mon Sep 17 00:00:00 2001
From: Li Li
Date: Tue, 28 Jul 2020 10:13:23 +1000
Subject: [PATCH 5/5] Fix docstring
---
qctrlopencontrols/driven_controls/predefined.py | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/qctrlopencontrols/driven_controls/predefined.py b/qctrlopencontrols/driven_controls/predefined.py
index 3ac40bda..cf3f1373 100644
--- a/qctrlopencontrols/driven_controls/predefined.py
+++ b/qctrlopencontrols/driven_controls/predefined.py
@@ -121,7 +121,7 @@ def _predefined_common_attributes(
The azimuthal position of the pulse.
rabi_rotation : float
The total polar angle to be performed by the pulse.
- Defined in polar coordinates. Defaults to None.
+ Defined in polar coordinates.
maximum_rabi_rate : float, optional
Defaults to 2.*np.pi
The maximum rabi frequency for the pulse.