def test_pwc_shape(): params = { "t_bin_start": Quantity(1e-10), "t_bin_end": Quantity(9.9e-9), "t_final": Quantity(10e-9), "inphase": Quantity([0, 0.1, 0.3, 0.5, 0.1, 1.1, 0.4, 0.1]), } np.testing.assert_allclose( actual=envelopes["pwc_shape"](t=ts, params=params), desired=test_data["pwc_shape"], atol=get_atol("pwc_shape"), ) np.testing.assert_allclose( actual=envelopes["pwc_symmetric"](t=ts, params=params), desired=test_data["pwc_symmetric"], atol=get_atol("pwc_symmetric"), ) np.testing.assert_allclose( actual=envelopes["pwc_shape_plateau"](t=ts, params=params), desired=test_data["pwc_shape_plateau1"], atol=get_atol("pwc_shape_plateau1"), ) params["width"] = Quantity(5e-9) np.testing.assert_allclose( actual=envelopes["pwc_shape_plateau"](t=ts, params=params), desired=test_data["pwc_shape_plateau2"], atol=get_atol("pwc_shape_plateau2"), )
def quick_setup(self, chan, qubit_freq, gate_time, v2hz=1, sideband=None) -> None: """ Initialize this instruction with a default envelope and carrier. """ pi_half_amp = np.pi / 2 / gate_time / v2hz * 2 * np.pi env_params = { "t_final": Quantity(value=gate_time, unit="s"), "amp": Quantity(value=pi_half_amp, min_val=0.0, max_val=3 * pi_half_amp, unit="V"), } carrier_freq = qubit_freq if sideband: env_params["freq_offset"] = Quantity(value=sideband, unit="Hz 2pi") carrier_freq -= sideband self.comps[chan]["gaussian"] = Envelope("gaussian", shape=gaussian_nonorm, params=env_params) self.comps[chan]["carrier"] = Carrier( "Carr_" + chan, params={"freq": Quantity(value=carrier_freq, unit="Hz 2pi")})
def test_gaussian(): params = { "t_final": Quantity(10e-9), "sigma": Quantity(5e-9), } np.testing.assert_allclose( actual=envelopes["gaussian_sigma"](t=ts, params=params), desired=test_data["gaussian_sigma"], atol=get_atol("gaussian_sigma"), ) np.testing.assert_allclose( actual=envelopes["gaussian"](t=ts, params=params), desired=test_data["gaussian"], atol=get_atol("gaussian"), ) np.testing.assert_allclose( actual=envelopes["gaussian_nonorm"](t=ts, params=params), desired=test_data["gaussian_nonorm"], atol=get_atol("gaussian_nonorm"), ) np.testing.assert_allclose( actual=envelopes["gaussian_der_nonorm"](t=ts, params=params), desired=test_data["gaussian_der_nonorm"], atol=get_atol("gaussian_der_nonorm"), ) np.testing.assert_allclose( actual=envelopes["gaussian_der"](t=ts, params=params), desired=test_data["gaussian_der"], atol=get_atol("gaussian_der"), ) np.testing.assert_allclose( actual=envelopes["drag_sigma"](t=ts, params=params), desired=test_data["drag_sigma"], atol=get_atol("drag_sigma"), ) np.testing.assert_allclose( actual=envelopes["drag_der"](t=ts, params=params), desired=test_data["drag_der"], atol=get_atol("drag_der"), ) np.testing.assert_allclose( actual=envelopes["drag"](t=ts, params=params), desired=test_data["drag"], atol=get_atol("drag"), )
def test_delta_pulse(): params = { "t_sig": Quantity( [ 0.5e-9, ] ), "t_final": Quantity(10e-9), } np.testing.assert_allclose( actual=envelopes["delta_pulse"](t=ts, params=params), desired=test_data["delta_pulse"], atol=get_atol("delta_pulse"), )
def test_flattop(): params = { "risefall": Quantity(2e-9), "t_final": Quantity(10e-9), } np.testing.assert_allclose( actual=envelopes["trapezoid"](t=ts, params=params), desired=test_data["trapezoid"], atol=get_atol("trapezoid"), ) np.testing.assert_allclose( actual=envelopes["flattop_risefall"](t=ts, params=params), desired=test_data["flattop_risefall"], atol=get_atol("flattop_risefall"), ) np.testing.assert_allclose( actual=envelopes["flattop_risefall_1ns"](t=ts, params=params), desired=test_data["flattop_risefall_1ns"], atol=get_atol("flattop_risefall_1ns"), ) params = { "ramp": Quantity(2e-9), "t_up": Quantity(1e-9), "t_down": Quantity(10e-9), "t_final": Quantity(10e-9), } np.testing.assert_allclose( actual=envelopes["flattop_variant"](t=ts, params=params), desired=test_data["flattop_variant"], atol=get_atol("flattop_variant"), ) params = { "risefall": Quantity(2e-9), "t_up": Quantity(1e-9), "t_down": Quantity(10e-9), "t_final": Quantity(10e-9), } np.testing.assert_allclose( actual=envelopes["flattop"](t=ts, params=params), desired=test_data["flattop"] )
def test_signal_generation() -> None: t_final = 7e-9 # Time for single qubit gates sideband = 50e6 * 2 * np.pi gauss_params_single = { 'amp': Quantity(value=0.5, min_val=0.4, max_val=0.6, unit="V"), 't_final': Quantity(value=t_final, min_val=0.5 * t_final, max_val=1.5 * t_final, unit="s"), 'sigma': Quantity(value=t_final / 4, min_val=t_final / 8, max_val=t_final / 2, unit="s"), 'xy_angle': Quantity(value=0.0, min_val=-0.5 * np.pi, max_val=2.5 * np.pi, unit='rad'), 'freq_offset': Quantity(value=-sideband - 3e6 * 2 * np.pi, min_val=-56 * 1e6 * 2 * np.pi, max_val=-52 * 1e6 * 2 * np.pi, unit='Hz 2pi'), 'delta': Quantity(value=-1, min_val=-5, max_val=3, unit="") } gauss_env_single = Envelope(name="gauss", desc="Gaussian comp for single-qubit gates", params=gauss_params_single, shape=envelopes['gaussian_nonorm']) carrier_parameters = { 'freq': Quantity(value=5e9 * 2 * np.pi, min_val=4.5e9 * 2 * np.pi, max_val=6e9 * 2 * np.pi, unit='Hz 2pi'), 'framechange': Quantity(value=0.0, min_val=-np.pi, max_val=3 * np.pi, unit='rad') } carr = Carrier(name="carrier", desc="Frequency of the local oscillator", params=carrier_parameters) X90p_q1 = Instruction(name="X90p", t_start=0.0, t_end=t_final, channels=["d1"]) X90p_q1.add_component(gauss_env_single, "d1") X90p_q1.add_component(carr, "d1") gen.generate_signals(X90p_q1)
def test_flattop_cut(): params = { "risefall": Quantity(2e-9), "t_up": Quantity(1e-9), "t_down": Quantity(10e-9), "t_final": Quantity(10e-9), } np.testing.assert_allclose( actual=envelopes["flattop_cut"](t=ts, params=params), desired=test_data["flattop_cut"], atol=get_atol("flattop_cut"), ) params = { "risefall": Quantity(2e-9), "width": Quantity(9e-9), "t_final": Quantity(10e-9), } np.testing.assert_allclose( actual=envelopes["flattop_cut_center"](t=ts, params=params), desired=test_data["flattop_cut_center"], atol=get_atol("flattop_cut_center"), )
def __init__(self, **props): super().__init__(**props) self.inputs = props.pop("inputs", 1) self.outputs = props.pop("outputs", 1) self.signal = None self.params["noise_strength"] = props.pop("noise_strength") self.params["bfl_num"] = props.pop( "bfl_num", Quantity(value=5, min_val=1, max_val=10)) self.ts = None self.signal = None
def test_signal_generation() -> None: t_final = 7e-9 # Time for single qubit gates sideband = 50e6 * 2 * np.pi gauss_params_single = { "amp": Quantity(value=0.5, min_val=0.4, max_val=0.6, unit="V"), "t_final": Quantity( value=t_final, min_val=0.5 * t_final, max_val=1.5 * t_final, unit="s" ), "sigma": Quantity( value=t_final / 4, min_val=t_final / 8, max_val=t_final / 2, unit="s" ), "xy_angle": Quantity( value=0.0, min_val=-0.5 * np.pi, max_val=2.5 * np.pi, unit="rad" ), "freq_offset": Quantity( value=-sideband - 3e6 * 2 * np.pi, min_val=-56 * 1e6 * 2 * np.pi, max_val=-52 * 1e6 * 2 * np.pi, unit="Hz 2pi", ), "delta": Quantity(value=-1, min_val=-5, max_val=3, unit=""), } gauss_env_single = Envelope( name="gauss", desc="Gaussian comp for single-qubit gates", params=gauss_params_single, shape=envelopes["gaussian_nonorm"], ) carrier_parameters = { "freq": Quantity( value=5e9 * 2 * np.pi, min_val=4.5e9 * 2 * np.pi, max_val=6e9 * 2 * np.pi, unit="Hz 2pi", ), "framechange": Quantity( value=0.0, min_val=-np.pi, max_val=3 * np.pi, unit="rad" ), } carr = Carrier( name="carrier", desc="Frequency of the local oscillator", params=carrier_parameters, ) rx90p_q1 = Instruction(name="rx90p", t_start=0.0, t_end=t_final, channels=["d1"]) rx90p_q1.add_component(gauss_env_single, "d1") rx90p_q1.add_component(carr, "d1") gen.generate_signals(rx90p_q1)
def get_and_set() -> None: np.testing.assert_allclose( Quantity(0.3, min_val=0, max_val=1).get_opt_value(), [-0.4]) for val in np.linspace(0, 2): a = Quantity(val, min_val=-1, max_val=2) opt_val = a.get_opt_value() a.set_opt_value(opt_val) np.testing.assert_allclose(a, val)
def test_cosine(): params = { "t_final": Quantity(10e-9), } np.testing.assert_allclose( actual=envelopes["cosine"](t=ts, params=params), desired=test_data["cosine"], atol=get_atol("cosine"), ) params = { "t_final": Quantity(10e-9), "t_rise": Quantity(2e-9), } np.testing.assert_allclose( actual=np.reshape( envelopes["cosine_flattop"](t=np.reshape(ts, (-1, 1)), params=params), (-1,) ), desired=test_data["cosine_flattop"], atol=get_atol("cosine_flattop"), )
def energies_from_frequencies(self): freq = self.params["freq"].get_value() anhar = self.params["anhar"].get_value() phi = self.params["phi"].get_value() EC_guess = -anhar EJ_guess = (freq + EC_guess)**2 / (8 * EC_guess) self.params["EC"] = Quantity(EC_guess, min_val=0.0 * EC_guess, max_val=2 * EC_guess) self.params["EJ"] = Quantity(EJ_guess, min_val=0.0 * EJ_guess, max_val=2 * EJ_guess) def eval_func(x): EC, EJ = x self.params["EC"].set_opt_value(EC) self.params["EJ"].set_opt_value(EJ) prefactors = self.get_prefactors(-phi) h = tf.zeros_like(self.Hs_local["quadratic"]) for k in prefactors: h += self.Hs_local[k] * tf.cast(prefactors[k], tf.complex128) es = tf.linalg.eigvalsh(h) es -= es[0] freq_diff = tf.math.abs(tf.math.real(es[1] - es[0]) - freq) anhar_diff = tf.math.abs( tf.math.real(es[2] - es[1]) - (freq + anhar)) return freq_diff + anhar_diff fmin( eval_func, x0=[ self.params["EC"].get_opt_value(), self.params["EJ"].get_opt_value() ], disp=False, xtol=1e-9, )
def get_xtalk_pmap() -> ParameterMap: xtalk = Crosstalk( name="crosstalk", channels=["TC1", "TC2"], crosstalk_matrix=Quantity( value=[[1, 0], [0, 1]], min_val=[[0, 0], [0, 0]], max_val=[[1, 1], [1, 1]], unit="", ), ) gen = Generator(devices={"crosstalk": xtalk}) pmap = ParameterMap(generator=gen) pmap.set_opt_map([[["crosstalk", "crosstalk_matrix"]]]) return pmap
def test_qty_math() -> None: a = 0.5 b = Quantity(2) assert a + b == 2.5 assert b + a == 2.5 assert a - b == -1.5 assert b - a == 1.5 assert a * b == 1.0 assert b * a == 1.0 np.testing.assert_allclose(a**b, 0.25) assert b**a == 2**0.5 np.testing.assert_allclose(a / b, 0.25) assert b / a == 4.0 assert b % a == 0 qty = Quantity(3, min_val=0, max_val=5) qty.subtract(1.3) np.testing.assert_allclose(qty, 1.7) qty = Quantity(3, min_val=0, max_val=5) qty.add(0.3) np.testing.assert_allclose(qty, 3.3)
def test_crosstalk() -> None: generator = Generator( devices={ "LO": lo, "AWG": awg, "DigitalToAnalog": dac, "Response": resp, "Mixer": mixer, "VoltsToHertz": v_to_hz, "crosstalk": xtalk, }, chains={ "d1": ["LO", "AWG", "DigitalToAnalog", "Response", "Mixer", "VoltsToHertz"], "d2": ["LO", "AWG", "DigitalToAnalog", "Response", "Mixer", "VoltsToHertz"], }, ) RX90p_q1 = Instruction( name="RX90p", t_start=0.0, t_end=t_final, channels=["d1", "d2"] ) RX90p_q1.add_component(gauss_env_single, "d1") RX90p_q1.add_component(carr, "d1") gauss_params_single_2 = { "amp": Quantity(value=0, min_val=-0.4, max_val=0.6, unit="V"), "t_final": Quantity( value=t_final, min_val=0.5 * t_final, max_val=1.5 * t_final, unit="s" ), "sigma": Quantity( value=t_final / 4, min_val=t_final / 8, max_val=t_final / 2, unit="s" ), "xy_angle": Quantity( value=0.0, min_val=-0.5 * np.pi, max_val=2.5 * np.pi, unit="rad" ), "freq_offset": Quantity( value=-sideband - 3e6, min_val=-56 * 1e6, max_val=-52 * 1e6, unit="Hz 2pi" ), "delta": Quantity(value=-1, min_val=-5, max_val=3, unit=""), } gauss_env_single_2 = Envelope( name="gauss", desc="Gaussian comp for single-qubit gates", params=gauss_params_single_2, shape=env_lib.gaussian_nonorm, ) RX90p_q1.add_component(gauss_env_single_2, "d2") RX90p_q1.add_component(carr, "d2") full_signal = generator.generate_signals(RX90p_q1) assert ( full_signal["d1"]["values"].numpy() == full_signal["d2"]["values"].numpy() ).all()
def add_component(self, comp: C3obj, chan: str, options=None, name=None) -> None: """ Add one component, e.g. an envelope, local oscillator, to a channel. Parameters ---------- comp : C3obj Component to be added. chan : str Identifier for the target channel options: dict Options for this component, available keys are delay: Quantity Delay execution of this component by a certain time trigger_comp: Tuple[str] Tuple of (chan, name) of component acting as trigger. Delay time will be counted beginning with end of trigger t_final_cut: Quantity Length of component, signal will be cut after this time. Also used for the trigger. If not given this invokation from components `t_final` will be attempted. drag: bool Use drag correction for this component. t_end: float End of this component. None will use the full instruction. If t_end is None and t_start is given a length will be inherited from the instruction. """ if chan in self.comps and comp.name in self.comps[chan]: print( f"Component of instruction {self.get_key()} has been overwritten: Channel: {chan}, Component: {comp.name}", ) if name is None: name = comp.name self.comps[chan][name] = comp if options is None: options = dict() for k, v in options.items(): if isinstance(v, dict): options[k] = Quantity(**v) self.__options[chan][name] = options
def test_qty_np_conversions() -> None: a = Quantity(value=3, unit="unit") assert repr(a) == "3.000 unit" assert np.mod(a, 2) == 1.0 assert type(a.numpy()) is np.float64 or type(a.numpy()) is np.ndarray assert a + a == 6 np.array([a]) # test conversion np.array(a) float(a) assert np.mod([a], 2) == np.array([[1.0]]) assert list(a) == [3.0] b = Quantity(np.array([0.0000001, 0.00001])) np.array([b]) c = Quantity([0, 0.1], min_val=0, max_val=1) assert len(c) == 2 assert c.shape == (2, )
) from c3.generator.generator import Generator from c3.signal.gates import Instruction from c3.signal.pulse import Envelope, Carrier from c3.c3objs import Quantity import c3.libraries.envelopes as env_lib sim_res = 100e9 # Resolution for numerical simulation awg_res = 2e9 # Realistic, limited resolution of an AWG lo = LO(name="lo", resolution=sim_res, outputs=1) awg = AWG(name="awg", resolution=awg_res, outputs=1) dac = DigitalToAnalog(name="dac", resolution=sim_res, inputs=1, outputs=1) resp = Response( name="resp", rise_time=Quantity(value=0.3e-9, min_val=0.05e-9, max_val=0.6e-9, unit="s"), resolution=sim_res, inputs=1, outputs=1, ) mixer = Mixer(name="mixer", inputs=2, outputs=1) v_to_hz = VoltsToHertz( name="v_to_hz", V_to_Hz=Quantity(value=1e9, min_val=0.9e9, max_val=1.1e9, unit="Hz/V"), inputs=1, outputs=1, ) xtalk = Crosstalk( name="crosstalk", channels=["d1", "d2"], crosstalk_matrix=Quantity(
from c3.system.model import Model import c3.libraries.hamiltonians as hamiltonians from c3.parametermap import ParameterMap qubit_lvls = 3 freq_q1 = 5e9 anhar_q1 = -210e6 t1_q1 = 27e-6 t2star_q1 = 39e-6 qubit_temp = 50e-3 q1 = Qubit( name="Q1", desc="Qubit 1", freq=Quantity(value=freq_q1, min_val=4.995e9, max_val=5.005e9, unit="Hz 2pi"), anhar=Quantity(value=anhar_q1, min_val=-380e6, max_val=-120e6, unit="Hz 2pi"), hilbert_dim=qubit_lvls, t1=Quantity(value=t1_q1, min_val=1e-6, max_val=90e-6, unit="s"), t2star=Quantity(value=t2star_q1, min_val=10e-6, max_val=90e-3, unit="s"), temp=Quantity(value=qubit_temp, min_val=0.0, max_val=0.12, unit="K"), ) freq_q2 = 5.6e9 anhar_q2 = -240e6 t1_q2 = 23e-6 t2star_q2 = 31e-6
def test_qty_read_cfg() -> None: assert Quantity(**amp_dict).asdict() == amp.asdict()
"""Unit tests for Quantity class""" import hjson import numpy as np import pytest from c3.c3objs import Quantity amp = Quantity(value=0.0, min_val=-1.0, max_val=+1.0, unit="V") amp_dict = { "value": 0.0, "min_val": -1.0, "max_val": 1.0, "unit": "V", "symbol": "\\alpha", } freq = Quantity( value=5.6e9, min_val=5.595e9, max_val=5.605e9, unit="Hz 2pi", symbol="\\omega" ) freq_dict = { "value": 5.6e9, "min_val": 5.595e9, "max_val": 5.605e9, "unit": "Hz 2pi", "symbol": "\\omega", } gate_time = Quantity( value=5.3246e-9, min_val=2e-9, max_val=10e-9, unit="s", symbol=r"t_g" )
from c3.model import Model import c3.libraries.hamiltonians as hamiltonians qubit_lvls = 3 freq_S = 5e9 anhar_S = -210e6 beta_S = 0.3e9 t1_S = 27e-6 t2star_S = 39e-6 S_temp = 50e-3 S = SNAIL( name="Test", desc="SNAIL", freq=Quantity(value=freq_S, min_val=4.995e9, max_val=5.005e9, unit="Hz 2pi"), anhar=Quantity(value=anhar_S, min_val=-380e6, max_val=-120e6, unit="Hz 2pi"), beta=Quantity(value=beta_S, min_val=250e6, max_val=350e6, unit="Hz 2pi"), hilbert_dim=qubit_lvls, t1=Quantity(value=t1_S, min_val=1e-6, max_val=90e-6, unit="s"), t2star=Quantity(value=t2star_S, min_val=10e-6, max_val=90e-3, unit="s"), temp=Quantity(value=S_temp, min_val=0.0, max_val=0.12, unit="K"), ) drive = Drive( name="d1", desc="Drive 1",
def test_fourier(): params = { "amps": Quantity([0.5, 0.2]), "freqs": Quantity([1e6, 1e10]), "phases": Quantity([0, 1]), "t_final": Quantity(10e-9), } np.testing.assert_allclose( actual=envelopes["fourier_sin"](t=ts, params=params), desired=test_data["fourier_sin"], atol=get_atol("fourier_sin"), ) np.testing.assert_allclose( actual=envelopes["fourier_cos"](t=ts, params=params), desired=test_data["fourier_cos"], atol=get_atol("fourier_cos"), ) params = { "width": Quantity(9e-9), "fourier_coeffs": Quantity([1, 0.5, 0.2]), "offset": Quantity(0.1), "amp": Quantity(0.5), "t_final": Quantity(10e-9), } np.testing.assert_allclose( actual=envelopes["slepian_fourier"](t=ts, params=params), desired=test_data["slepian_fourier"], atol=get_atol("slepian_fourier"), ) params["risefall"] = Quantity(4e-9) np.testing.assert_allclose( actual=envelopes["slepian_fourier"](t=ts, params=params), desired=test_data["slepian_fourier_risefall"], atol=get_atol("slepian_fourier_risefall"), ) params["sin_coeffs"] = Quantity([0.3]) np.testing.assert_allclose( actual=envelopes["slepian_fourier"](t=ts, params=params), desired=test_data["slepian_fourier_sin"], atol=get_atol("slepian_fourier_sin"), )
# V_to_Hz=Quantity( # value=v2hz, # min_val=0.9e9, # max_val=1.1e9, # unit='Hz 2pi/V' # ) # ) # # generator = Generator([lo, awg, mixer, v_to_hz, dig_to_an, resp]) lo = LO(name='lo', resolution=sim_res, outputs=1) awg = AWG(name='awg', resolution=awg_res, outputs=1) dac = DigitalToAnalog(name="dac", resolution=sim_res, inputs=1, outputs=1) resp = Response(name='resp', rise_time=Quantity(value=0.3e-9, min_val=0.05e-9, max_val=0.6e-9, unit='s'), resolution=sim_res, inputs=1, outputs=1) mixer = Mixer(name='mixer', inputs=2, outputs=1) v_to_hz = VoltsToHertz(name='v_to_hz', V_to_Hz=Quantity(value=1e9, min_val=0.9e9, max_val=1.1e9, unit='Hz/V'), inputs=1, outputs=1) generator = Generator(devices={ "LO": lo, "AWG": awg,
def __init__(self, **props): super().__init__(**props) self.params["bfl_num"] = props.pop( "bfl_num", Quantity(value=5, min_val=1, max_val=10))
from c3.libraries.envelopes import envelopes from c3.parametermap import ParameterMap from c3.signal import gates, pulse from c3.model import Model import numpy as np import pytest model = Model() model.read_config("test/test_model.cfg") generator = Generator() generator.read_config("test/generator2.cfg") t_final = 7e-9 # Time for single qubit gates sideband = 50e6 gauss_params_single = { "amp": Quantity(value=0.5, min_val=0.4, max_val=0.6, unit="V"), "t_final": Quantity( value=t_final, min_val=0.5 * t_final, max_val=1.5 * t_final, unit="s" ), "sigma": Quantity( value=t_final / 4, min_val=t_final / 8, max_val=t_final / 2, unit="s" ), "xy_angle": Quantity( value=0.0, min_val=-0.5 * np.pi, max_val=2.5 * np.pi, unit="rad" ), "freq_offset": Quantity( value=-sideband - 3e6, min_val=-56 * 1e6, max_val=-52 * 1e6, unit="Hz 2pi" ), "delta": Quantity(value=-1, min_val=-5, max_val=3, unit=""), }