@@ -973,6 +973,108 @@ def new_wamf1_control(
973973 )
974974
975975
976+ def new_gaussian_control (
977+ rabi_rotation : float ,
978+ segment_count : int ,
979+ duration : float ,
980+ width : float ,
981+ name : Optional [str ] = None ,
982+ ) -> DrivenControl :
983+ r"""
984+ Generates a Gaussian driven control sequence.
985+
986+ Gaussian driven controls mitigate leakage out of the qubit subspace.
987+
988+ Parameters
989+ ----------
990+ rabi_rotation : float
991+ Total Rabi rotation :math:`\theta` to be performed by the driven control.
992+ segment_count : int
993+ Number of segments in the control sequence.
994+ duration : float
995+ Total duration :math:`t_g` of the control sequence.
996+ width : float
997+ Width (standard deviation) :math:`\sigma` of the ideal Gaussian pulse.
998+ name : str, optional
999+ An optional string to name the control. Defaults to ``None``.
1000+
1001+ Returns
1002+ -------
1003+ DrivenControl
1004+ A control sequence as an instance of DrivenControl.
1005+
1006+ See Also
1007+ --------
1008+ new_modulated_gaussian_control
1009+
1010+ Notes
1011+ -----
1012+ A Gaussian driven control [#]_ consists of a piecewise constant approximation
1013+ to an ideal Gaussian pulse:
1014+
1015+ .. math::
1016+ \mathcal{E}_G (t) = A \exp \left[- \frac{(t - t_g/2)^2}{2\sigma^2}\right] - B
1017+
1018+ where the two additional parameters :math:`A, B` chosen such that
1019+ :math:`\int_{0}^{t_g} \mathcal{E}_G \,dt = \theta` and :math:`\mathcal{E}_G(0) = 0`.
1020+
1021+ Relative values of segments are determined by sampling the ideal Gaussian at the midpoints
1022+ of the segments.
1023+
1024+ References
1025+ ----------
1026+ .. [#] `Motzoi, F. et al. Physical Review Letters 103, 110501 (2009)
1027+ <https://doi.org/10.1103/PhysRevLett.103.110501>`_
1028+ """
1029+
1030+ check_arguments (
1031+ duration > 0.0 ,
1032+ "Pulse duration must be greater than zero." ,
1033+ {"duration" : duration },
1034+ )
1035+
1036+ check_arguments (
1037+ segment_count > 0 ,
1038+ "Segment count must be greater than zero." ,
1039+ {"segment_count" : segment_count },
1040+ )
1041+
1042+ check_arguments (
1043+ width > 0.0 ,
1044+ "Width of ideal Gaussian pulse must be greater than zero." ,
1045+ {"width" : width },
1046+ )
1047+
1048+ # work out exact segment duration
1049+ segment_duration = duration / segment_count
1050+ segment_start_times = np .arange (segment_count ) * segment_duration
1051+ segment_midpoints = segment_start_times + segment_duration / 2
1052+
1053+ # prepare a base (un-normalized) gaussian shaped pulse
1054+ gaussian_mean = duration / 2
1055+ base_gaussian_segments = np .exp (
1056+ - 0.5 * ((segment_midpoints - gaussian_mean ) / width ) ** 2
1057+ )
1058+
1059+ # translate pulse by B/A (from Motzoi paper) to ensure output is 0 at t=0
1060+ y_translation = - np .exp (- 0.5 * ((0 - gaussian_mean ) / width ) ** 2 )
1061+ base_gaussian_segments += y_translation
1062+
1063+ # scale segments such that their net effect matches the desired rotation
1064+ base_gaussian_total_rotation = np .sum (base_gaussian_segments ) * segment_duration
1065+ gaussian_segments = (
1066+ base_gaussian_segments / base_gaussian_total_rotation
1067+ ) * rabi_rotation
1068+
1069+ return DrivenControl (
1070+ rabi_rates = gaussian_segments ,
1071+ azimuthal_angles = np .zeros (segment_count ),
1072+ detunings = np .zeros (segment_count ),
1073+ durations = np .array ([segment_duration ] * segment_count ),
1074+ name = name ,
1075+ )
1076+
1077+
9761078def new_modulated_gaussian_control (
9771079 maximum_rabi_rate : float ,
9781080 minimum_segment_duration : float ,
@@ -1003,6 +1105,10 @@ def new_modulated_gaussian_control(
10031105 -------
10041106 DrivenControl
10051107 A control sequence as an instance of DrivenControl.
1108+
1109+ See Also
1110+ --------
1111+ new_gaussian_control
10061112 """
10071113
10081114 check_arguments (
0 commit comments