Exemple #1
0
def _solve_(node, errList1, errList2, herr):

    errList2.append(herr * pow(2, -53))
    expr1 = sum([seng.Abs(erri) for erri in errList1])
    expr2 = sum([seng.Abs(erri) for erri in errList2])

    if (seng.count_ops(expr1) >= opMax):
        #	print("Solving Ferror @depth: ", node.depth)
        print("\nSolving f@depth :", node.depth)
        errList1 = [solve_remaining_error(expr1)]

    expr2_ops = seng.count_ops(expr2)
    #print("Solving h@depth :", node.depth)
    #errList2 = [solve_remaining_error(expr2)]

    if expr2_ops >= SopMax:
        print("\nSolving", expr2_ops, " h@depth :", node.depth)
        #errList2 = [solve_remaining_error(errList2)]
        errList2 = [_partial_solve_(errList2)]
    else:
        print("bwahahaha!", expr2_ops, expr2, SopMax)

    #errList2 = [solve_remaining_error(errList2+[herr*pow(2,-53)])]
    #if(seng.count_ops(expr2) > opMax):
    #	print("Solving Herror @depth: ", node.depth, expr2_ops)
    #	errList2 = [_partial_solve_(errList2+[herr*pow(2,-53)])]
    #else:
    #	print("Else:", seng.count_ops(expr2_ops))
    #	errList2.append(herr*pow(2,-53))

    return [errList1, errList2]
Exemple #2
0
    def rec_eval(obj):
        ch_lexpr = [child.rec_eval(child) for child in obj.children]
        lexpr = ops._FOPS[obj.token.type](ch_lexpr)
        if (seng.Abs(ch_lexpr[0])==1.0 or \
        seng.Abs(ch_lexpr[1])==1.0):
            obj.rnd = 0.0
        else:
            obj.rnd = max([max([child.rnd for child in obj.children]), 1.0])

        return obj.simplify(lexpr)
Exemple #3
0
def _HSIN_(node, S1, S2):
    f = node.children[0].f_expression

    errList1 = [node.f_expression] + \
         [seng.Abs(Si*seng.cos(f)) for Si in S1]

    errList2 = [seng.Abs(Si.seng.cos(f)) for Si in S2]

    herr = seng.Abs(
        seng.sin(f + sum([seng.Abs(Si * pow(2, -53)) for Si in S1 + S2])) *
        sum([seng.Abs(Si * Sj) for Si in S1 + S2 for Sj in S1 + S2]))

    return _solve_(node, errList1, errList2, herr)
Exemple #4
0
def _HEXP_(node, S1, S2):
    f = node.children[0].f_expression

    errList1 = [node.f_expression] + \
         [seng.expand(Si*node.f_expression) for Si in S1]
    errList2 = [seng.expand(Si * node.f_expression) for Si in S2]

    ferr = sum([seng.Abs(Si * pow(2, -53))
                for Si in S1 + S2]) + node.f_expression
    herr = sum([
        seng.Abs(Si * Sj * seng.exp(ferr)) for Si in S1 + S2 for Sj in S1 + S2
    ])

    return _solve_(node, errList1, errList2, herr)
Exemple #5
0
def _HLOG_(node, S1, S2):
    f = node.children[0].f_expression

    errList1 = [node.f_expression] + \
         [Si/f for Si in S1]

    errList2 = [Si / f for Si in S2]

    hdenorm = (node.f_expression +
               0.5 * sum([seng.Abs(Si * pow(2, -53)) for Si in S1 + S2]))**2

    herr = sum([seng.Abs(Si * Sj) for Si in S for Sj in S]) / hdenorm

    return _solve_(node, errList1, errList2, herr)
Exemple #6
0
def _solve1_(node, errList1, errList2, herr):

    expr1 = sum([seng.Abs(erri) for erri in errList1])
    expr2 = sum([seng.Abs(erri) for erri in errList2]) + herr * pow(2, -53)

    #if(seng.count_ops(expr1) > opMax):
    #	print("Solving Ferror @depth: ", node.depth)
    print("\nSolving f@depth :", node.depth)
    errList1 = [solve_remaining_error(expr1)]

    expr2_ops = seng.count_ops(expr2)
    print("Solving h@depth :", expr2, node.depth)
    errList2 = [solve_remaining_error(expr2)]

    return [errList1, errList2]
Exemple #7
0
    def eval(obj):
        lexpr = ops._FOPS[obj.token.type](
            [child.f_expression for child in obj.children])
        obj.rnd = max([min([child.rnd for child in obj.children]), obj.rnd])
        if ((seng.Abs(obj.children[0].f_expression)==1.0 or \
        seng.Abs(obj.children[1].f_expression)==1.0) and obj.token.type==MUL):
            obj.rnd = 0.0
        else:
            #print("Before overwrite:", obj.rnd)
            obj.rnd = max(
                [max([child.rnd for child in obj.children]), obj.rnd, 1.0])
            #print("After overwrite:", obj.rnd)

        lexpr = obj.simplify(lexpr)
        #print(seng.count_ops(lexpr), obj.depth)
        return lexpr
Exemple #8
0
def _HINV_(node, S1, S2):
    f = node.f_expression
    inv_expr = 1.0 / f

    S1 = [solve_remaining_error(S1)]
    S2 = [solve_remaining_error(S2)]

    errList1 = [inv_expr] + [-Si / (f * f) for Si in S1]
    errList2 = [-Si / (f * f) for Si in S2]

    herr_denorm = (f + sum([seng.Abs(Si * pow(2, -53)) for Si in S1 + S2]))**3

    herr = sum(
        [seng.Abs(Si * Sj) / herr_denorm for Si in S1 + S2 for Sj in S1 + S2])

    return _solve_(node, errList1, errList2, herr)
Exemple #9
0
def solve_remaining_error2(errList):
    #expr = sum([seng.Abs(erri) for erri in errList])
    if type(errList).__name__ == 'list':
        expr = sum([seng.Abs(erri) for erri in errList])
    else:
        expr = errList

    return max(utils.generate_signature_herror(expr))
    def __init__(
        self,
        duration: Union[int, ParameterExpression],
        amp: Union[complex, ParameterExpression],
        sigma: Union[float, ParameterExpression],
        beta: Union[float, 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 Drag envelope.
            sigma: A measure of how wide or narrow the Gaussian peak is; described mathematically
                   in the class docstring.
            beta: The correction amplitude.
            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, "sigma": sigma, "beta": beta}

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

        _gauss = _lifted_gaussian(_t, _center, _duration + 1, _sigma)
        _deriv = -(_t - _center) / (_sigma**2) * _gauss

        envelope_expr = _amp * (_gauss + sym.I * _beta * _deriv)

        consts_expr = _sigma > 0
        valid_amp_conditions_expr = sym.And(sym.Abs(_amp) <= 1.0, sym.Abs(_beta) < _sigma)

        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()
def generate_schedule_blocks():
    """Standard QPY testcase for schedule blocks."""
    from qiskit.pulse import builder, channels, library
    from qiskit.utils import optionals

    # Parameterized schedule test is avoided.
    # Generated reference and loaded QPY object may induce parameter uuid mismatch.
    # As workaround, we need test with bounded parameters, however, schedule.parameters
    # are returned as Set and thus its order is random.
    # Since schedule parameters are validated, we cannot assign random numbers.
    # We need to upgrade testing framework.

    schedule_blocks = []

    # Instructions without parameters
    with builder.build() as block:
        with builder.align_sequential():
            builder.set_frequency(5e9, channels.DriveChannel(0))
            builder.shift_frequency(10e6, channels.DriveChannel(1))
            builder.set_phase(1.57, channels.DriveChannel(0))
            builder.shift_phase(0.1, channels.DriveChannel(1))
            builder.barrier(channels.DriveChannel(0), channels.DriveChannel(1))
            builder.play(library.Gaussian(160, 0.1, 40),
                         channels.DriveChannel(0))
            builder.play(library.GaussianSquare(800, 0.1, 64, 544),
                         channels.ControlChannel(0))
            builder.play(library.Drag(160, 0.1, 40, 1.5),
                         channels.DriveChannel(1))
            builder.play(library.Constant(800, 0.1),
                         channels.MeasureChannel(0))
            builder.acquire(1000, channels.AcquireChannel(0),
                            channels.MemorySlot(0))
    schedule_blocks.append(block)
    # Raw symbolic pulse
    if optionals.HAS_SYMENGINE:
        import symengine as sym
    else:
        import sympy as sym
    duration, amp, t = sym.symbols("duration amp t")  # pylint: disable=invalid-name
    expr = amp * sym.sin(2 * sym.pi * t / duration)
    my_pulse = library.SymbolicPulse(
        pulse_type="Sinusoidal",
        duration=100,
        parameters={"amp": 0.1},
        envelope=expr,
        valid_amp_conditions=sym.Abs(amp) <= 1.0,
    )
    with builder.build() as block:
        builder.play(my_pulse, channels.DriveChannel(0))
    schedule_blocks.append(block)
    # Raw waveform
    my_waveform = 0.1 * np.sin(2 * np.pi * np.linspace(0, 1, 100))
    with builder.build() as block:
        builder.play(my_waveform, channels.DriveChannel(0))
    schedule_blocks.append(block)

    return schedule_blocks
Exemple #12
0
def _HMINUS_(node, S1, S2, T1, T2):
    f = node.children[0].f_expression
    g = node.children[1].f_expression

    errList1 = [node.f_expression] + S1 + [-t for t in T1]
    errList2 = S2 + [-t for t in T2]

    herr = sum([seng.Abs(Si) for Si in S1 + S2 + T1 + T2])
    return _solve_(node, errList1, errList2, herr)
Exemple #13
0
def _HSQRT_(node, S1, S2):
    f = node.children[0].f_expression

    S1 = [solve_remaining_error(S1)]
    S2 = [solve_remaining_error2(S2)]

    errList1 = [node.f_expression] + \
         [Si/(2*node.f_expression) for Si in S1]

    errList2 = [Si / (2 * node.f_expression) for Si in S2]

    herr_denorm = (f + sum([seng.Abs(Si * pow(2, -53))
                            for Si in S1 + S2]))**(3.0 / 2)

    herr = 0.125 * sum(
        [seng.Abs(Si * Sj) / herr_denorm for Si in S1 + S2 for Sj in S1 + S2])

    return _solve_(node, errList1, errList2, herr)
Exemple #14
0
def if_eq_zero(condition, if_result, else_result):
    """
    A short expression which can be compiled quickly.
    :type condition: Union[float, Symbol]
    :type if_result: Union[float, Symbol]
    :type else_result: Union[float, Symbol]
    :return: if_result if condition == 0 else else_result
    :rtype: Union[float, Symbol]
    """
    condition = se.Abs(sign(condition))
    return (1 - condition) * if_result + condition * else_result
Exemple #15
0
def _HMUL_(node, S1, S2, T1, T2):

    f = node.children[0].f_expression
    g = node.children[1].f_expression

    errList1 = [node.f_expression] + \
         [seng.expand( g * Si) for Si in S1] + \
         [seng.expand( f * Tj) for Tj in T1]

    errList2 = [seng.expand( g * Si) for Si in S2] + \
         [seng.expand( f * Tj) for Tj in T2]

    herr = sum(
        [seng.Abs(seng.expand(Si * Tj)) for Si in S1 + S2 for Tj in T1 + T2])

    return _solve_(node, errList1, errList2, herr)
Exemple #16
0
def _HDIV_(node, S1, S2, T1, T2):

    [TerrList1, TerrList2] = _HINV_(node.children[1], T1, T2)
    f = node.children[0].f_expression
    g = (1 / node.children[1].f_expression)

    errList1 = [node.f_expression] + \
         [seng.expand(f * Ti) for Ti in TerrList1] + \
         [seng.expand(g * Si) for Si in S1]

    errList2 = [seng.expand(f * Ti) for Ti in TerrList2] + \
         [seng.expand(g * Si) for Si in S2]

    herr = sum(
        [seng.Abs(Si * Tj) for Si in S1 + S2 for Tj in TerrList1 + TerrList2])
    return _solve_(node, errList1, errList2, herr)
Exemple #17
0
def _partial_solve_(errList):

    expr = sum([seng.Abs(erri) for erri in errList])
    expr_ops = seng.count_ops(expr)
    print("New partial:", expr_ops)
    size = len(errList)
    if size == 1 or expr_ops < SopMax:
        print("Unit level calls", size)
        #print(expr)
        val = max(utils.generate_signature_herror(expr))
        print("VAL : ", val)
        return val
    else:
        print("**************", size, expr_ops)
        return _partial_solve_(errList[0:int(size / 2)]) + _partial_solve_(
            errList[int(size / 2):size])
    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()
    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()