Example #1
0
def _test_Lambdify_Piecewise(Lambdify):
    x = se.symbols('x')
    p = se.Piecewise((-x, x < 0), (x * x * x, True))
    f = Lambdify([x], [p])
    arr = np.linspace(3, 7)
    assert np.allclose(f(-arr).flat, arr, atol=1e-14, rtol=1e-15)
    assert np.allclose(f(arr).flat, arr**3, atol=1e-14, rtol=1e-15)
Example #2
0
def piecewise_matrix(*piecewise_vector):
    # TODO testme
    # FIXME support non 2d matrices?
    dimensions = piecewise_vector[0][0].shape
    for m, condition in piecewise_vector:
        assert m.shape == dimensions
    matrix = se.zeros(*dimensions)
    for x in range(dimensions[0]):
        for y in range(dimensions[1]):
            piecewise_entry = []
            for m, condition in piecewise_vector:
                piecewise_entry.append([m[x, y], condition])
            matrix[x, y] = se.Piecewise(*piecewise_entry)
    return matrix
    def __init__(
        self,
        duration: Union[int, ParameterExpression],
        amp: Union[complex, ParameterExpression],
        name: Optional[str] = None,
        limit_amplitude: Optional[bool] = None,
    ):
        """Create new pulse instance.

        Args:
            duration: Pulse length in terms of the sampling period `dt`.
            amp: The amplitude of the constant square pulse.
            name: Display name for this pulse envelope.
            limit_amplitude: If ``True``, then limit the amplitude of the
                waveform to 1. The default is ``True`` and the amplitude is constrained to 1.
        """
        parameters = {"amp": amp}

        # Prepare symbolic expressions
        _t, _amp, _duration = sym.symbols("t, amp, duration")

        # Note this is implemented using Piecewise instead of just returning amp
        # directly because otherwise the expression has no t dependence and sympy's
        # lambdify will produce a function f that for an array t returns amp
        # instead of amp * np.ones(t.shape). This does not work well with
        # ParametricPulse.get_waveform().
        #
        # See: https://github.com/sympy/sympy/issues/5642
        envelope_expr = _amp * sym.Piecewise((1, sym.And(_t >= 0, _t <= _duration)), (0, True))
        valid_amp_conditions_expr = sym.Abs(_amp) <= 1.0

        super().__init__(
            pulse_type=self.__class__.__name__,
            duration=duration,
            parameters=parameters,
            name=name,
            limit_amplitude=limit_amplitude,
            envelope=envelope_expr,
            valid_amp_conditions=valid_amp_conditions_expr,
        )
        self.validate_parameters()
Example #4
0
    def test_custom_pulse(self):
        """Test defining a custom pulse which is not in the form of amp * F(t)."""
        t, t1, t2, amp1, amp2 = sym.symbols("t, t1, t2, amp1, amp2")
        envelope = sym.Piecewise((amp1, sym.And(t > t1, t < t2)),
                                 (amp2, sym.true))

        custom_pulse = SymbolicPulse(
            pulse_type="Custom",
            duration=100,
            parameters={
                "t1": 30,
                "t2": 80,
                "amp1": 0.1j,
                "amp2": -0.1
            },
            envelope=envelope,
        )
        waveform = custom_pulse.get_waveform()
        reference = np.concatenate(
            [-0.1 * np.ones(30), 0.1j * np.ones(50), -0.1 * np.ones(20)])
        np.testing.assert_array_almost_equal(waveform.samples, reference)
Example #5
0
def fmod(a, b):
    s = sign(a)
    a = Abs(a)
    b = Abs(b)
    f1 = a - (b * floor(a / b))
    return s * se.Piecewise([0, Abs(a - b) < SMALL_NUMBER], [f1, True])
    def __init__(
        self,
        duration: Union[int, ParameterExpression],
        amp: Union[complex, ParameterExpression],
        sigma: Union[float, ParameterExpression],
        width: Optional[Union[float, ParameterExpression]] = None,
        risefall_sigma_ratio: Optional[Union[float, ParameterExpression]] = None,
        name: Optional[str] = None,
        limit_amplitude: Optional[bool] = None,
    ):
        """Create new pulse instance.

        Args:
            duration: Pulse length in terms of the sampling period `dt`.
            amp: The amplitude of the Gaussian and of the square pulse.
            sigma: A measure of how wide or narrow the Gaussian risefall is; see the class
                   docstring for more details.
            width: The duration of the embedded square pulse.
            risefall_sigma_ratio: The ratio of each risefall duration to sigma.
            name: Display name for this pulse envelope.
            limit_amplitude: If ``True``, then limit the amplitude of the
                waveform to 1. The default is ``True`` and the amplitude is constrained to 1.

        Raises:
            PulseError: When width and risefall_sigma_ratio are both empty or both non-empty.
        """
        # Convert risefall_sigma_ratio into width which is defined in OpenPulse spec
        if width is None and risefall_sigma_ratio is None:
            raise PulseError(
                "Either the pulse width or the risefall_sigma_ratio parameter must be specified."
            )
        if width is not None and risefall_sigma_ratio is not None:
            raise PulseError(
                "Either the pulse width or the risefall_sigma_ratio parameter can be specified"
                " but not both."
            )
        if width is None and risefall_sigma_ratio is not None:
            width = duration - 2.0 * risefall_sigma_ratio * sigma

        parameters = {"amp": amp, "sigma": sigma, "width": width}

        # Prepare symbolic expressions
        _t, _duration, _amp, _sigma, _width = sym.symbols("t, duration, amp, sigma, width")
        _center = _duration / 2

        _sq_t0 = _center - _width / 2
        _sq_t1 = _center + _width / 2

        _gaussian_ledge = _lifted_gaussian(_t, _sq_t0, -1, _sigma)
        _gaussian_redge = _lifted_gaussian(_t, _sq_t1, _duration + 1, _sigma)

        envelope_expr = _amp * sym.Piecewise(
            (_gaussian_ledge, _t <= _sq_t0), (_gaussian_redge, _t >= _sq_t1), (1, True)
        )
        consts_expr = sym.And(_sigma > 0, _width >= 0, _duration >= _width)
        valid_amp_conditions_expr = sym.Abs(_amp) <= 1.0

        super().__init__(
            pulse_type=self.__class__.__name__,
            duration=duration,
            parameters=parameters,
            name=name,
            limit_amplitude=limit_amplitude,
            envelope=envelope_expr,
            constraints=consts_expr,
            valid_amp_conditions=valid_amp_conditions_expr,
        )
        self.validate_parameters()