def test_gkp_wigner_compare_backends(self, fock_eps): """Test correct Wigner function are generated by comparing fock and bosonic outputs. Since the fock backend cannot simulate very small epsilon, we restrict to fock_eps>0.1.""" theta = np.pi / 8 phi = np.pi / 6 ket = [theta, phi] xvec = np.linspace(-1, 1, 200) prog_fock = sf.Program(1) with prog_fock.context as q: sf.ops.GKP(epsilon=fock_eps, state=ket) | q cutoff = 100 hbar = 2 eng_fock = sf.Engine("fock", backend_options={ "cutoff_dim": cutoff, "hbar": hbar }) gkp_fock = eng_fock.run(prog_fock).state W_fock = gkp_fock.wigner(0, xvec, xvec) prog_bosonic = sf.Program(1) with prog_bosonic.context as q: sf.ops.GKP(epsilon=fock_eps, state=ket) | q hbar = 2 eng_bosonic = sf.Engine("bosonic", backend_options={"hbar": hbar}) gkp_bosonic = eng_bosonic.run(prog_bosonic).state W_bosonic = gkp_bosonic.wigner(0, xvec, xvec) assert np.allclose(W_fock, W_bosonic)
def circuit(X): # Create a parameter with an initial value of 2. params = [make_param(name='phi', constant=2.)] eng, q = sf.Engine(2) with eng: # Note that we are feeding 1-d tensors into gates, not scalars! Dgate(X[:, 0], 0.) | q[0] Dgate(X[:, 1], 0.) | q[1] BSgate(phi=params[0]) | (q[0], q[1]) BSgate() | (q[0], q[1]) # We have to tell the engine how big the batches (first dim of X) are # which we feed into gates num_inputs = X.get_shape().as_list()[0] state = eng.run('tf', cutoff_dim=10, eval=False, batch_size=num_inputs) # Define the output as the probability of measuring |0,2> as opposed to |2,0> p0 = state.fock_prob([0, 2]) p1 = state.fock_prob([2, 0]) normalization = p0 + p1 + 1e-10 circuit_output = p1 / normalization return circuit_output
def setUp(self): """parameters""" self.hbar = 2. self.eng, _ = sf.Engine(3, hbar=self.hbar) self.r = 0.2 self.th = 0.42 self.phi = 0.123
def test_multimode_args_apply_operation(self): """Test applying an operation to multiple modes""" rval = 4.32 thetaval = -0.654 phival = 0.543 @utils.operation(2) def dummy_func(r, theta, phi, q): Sgate(r) | q[0] BSgate(theta, phi) | (q[0], q[1]) eng, q = sf.Engine(2) with eng: with pytest.raises(ValueError, match="Wrong number of subsystems"): dummy_func(rval, thetaval, phival) | q[0] with eng: dummy_func(rval, thetaval, phival) | q # check eng queue matches the operation assert len(eng.cmd_queue) == 2 # check first queue op is Sgate(rval) assert isinstance(eng.cmd_queue[0].op, Sgate) assert eng.cmd_queue[0].reg == [q[0]] assert eng.cmd_queue[0].op.p[0].x == rval # check second queue op is BSgate(thetaval, phival) assert isinstance(eng.cmd_queue[1].op, BSgate) assert eng.cmd_queue[1].reg == list(q) assert eng.cmd_queue[1].op.p[0].x == thetaval assert eng.cmd_queue[1].op.p[1].x == phival
def test_call_function(self): """Test _call_function method for operation class""" rval = 4.32 thetaval = -0.654 phival = 0.543 def dummy_func(r, theta, phi, q): Sgate(r) | q[0] BSgate(theta, phi) | (q[0], q[1]) op = utils.operation(ns=1) op(dummy_func)(rval, thetaval, phival) eng, q = sf.Engine(2) with eng: res = op._call_function(q) # check register is returned assert res == q # check eng queue matches the operation assert len(eng.cmd_queue) == 2 # check first queue op is Sgate(rval) assert isinstance(eng.cmd_queue[0].op, Sgate) assert eng.cmd_queue[0].reg == [q[0]] assert eng.cmd_queue[0].op.p[0].x == rval # check second queue op is BSgate(thetaval, phival) assert isinstance(eng.cmd_queue[1].op, BSgate) assert eng.cmd_queue[1].reg == list(q) assert eng.cmd_queue[1].op.p[0].x == thetaval assert eng.cmd_queue[1].op.p[1].x == phival
def run(self, fresh_inputs, desired_outputs=[]): print("Started a Run") # initialize engine and program objects eng = sf.Engine(backend="tf", backend_options={"cutoff_dim": self.cutoff_dim}) qnn = sf.Program(self.modes) # defining desired state target_state = np.zeros(self.cutoff_dim) target_state[-1] = 1 self.target_state = tf.constant(target_state, dtype=tf.complex64) # Desired output # self.target_state = desired_outputs self.modified_inputs = tf.placeholder(tf.float32, shape=[self.cutoff_dim]) with qnn.context as q: print("Started and Working") for i in range(self.layers): self.layer(q) # self.record(i) # starting the engine results = eng.run(qnn, run_options={"eval": False}) ket = results.state.ket() # defining cost function difference = tf.reduce_sum(tf.abs(ket - self.target_state)) fidelity = tf.abs(tf.reduce_sum(tf.conj(ket) * self.target_state))**2 cost = difference # setting up optimizer optimiser = tf.train.AdamOptimizer() minimize_cost = optimiser.minimize(cost) print("Beginning optimization") sess = tf.Session() sess.run(tf.global_variables_initializer()) feed_dict = {self.modified_inputs: fresh_inputs} fidelity_before = sess.run(fidelity, feed_dict=feed_dict) for i in range(10): sess.run(minimize_cost, feed_dict=feed_dict) self.read_all() print(str(i) + " / 10") fidelity_after = sess.run(fidelity, feed_dict=feed_dict) print("Fidelity before optimization: " + str(fidelity_before)) print("Fidelity after optimization: " + str(fidelity_after)) print("\nTarget state: " + str(sess.run(self.target_state, feed_dict=feed_dict))) print("Output state: " + str(np.round(sess.run(ket, feed_dict=feed_dict), decimals=3))) qnn.draw_circuit()
def test_generate_code_with_engine(self, engine_kwargs): """Test generating code for a regular program with an engine""" prog = sf.Program(3) eng = sf.Engine(**engine_kwargs) with prog.context as q: ops.Sgate(0.54, 0) | q[0] ops.BSgate(0.45, np.pi / 2) | (q[0], q[2]) ops.Sgate(3 * np.pi / 2, 0) | q[1] ops.BSgate(2 * np.pi, 0.62) | (q[0], q[1]) ops.MeasureFock() | q[0] results = eng.run(prog) code = io.generate_code(prog, eng) code_list = code.split("\n") formatting_str = f"\"{engine_kwargs['backend']}\"" if "backend_options" in engine_kwargs: formatting_str += ( ", backend_options=" f'{{"cutoff_dim": {engine_kwargs["backend_options"]["cutoff_dim"]}}}' ) expected = prog_txt.format(engine_args=formatting_str).split("\n") for i, row in enumerate(code_list): assert row == expected[i]
def pre_measure(self): self.eng = sf.Engine("fock", backend_options={"cutoff_dim": self.cutoff}) results = self.eng.run(self.prog) self.state = results.state self.samples = results.samples
def test_all_samples_batched(self): """Test the case of storing all samples for batches""" batch_size = 2 eng = sf.Engine("tf", backend_options={ "batch_size": batch_size, "cutoff_dim": 6 }) prog = sf.Program(5) with prog.context as q: ops.MeasureFock() | q[2] ops.MeasureFock() | (q[1], q[3]) ops.MeasureFock() | q[2] result = eng.run(prog) assert len(result.all_samples[1]) == 1 assert len(result.all_samples[3]) == 1 assert len(result.all_samples[2]) == 2 assert np.array_equal(result.all_samples[1][0].numpy(), np.array([[0], [0]])) assert np.array_equal(result.all_samples[3][0].numpy(), np.array([[0], [0]])) assert np.array_equal(result.all_samples[2][0].numpy(), np.array([[0], [0]])) assert np.array_equal(result.all_samples[2][1].numpy(), np.array([[0], [0]]))
def test_1x2_tf(self, hbar, tol): """Test a 1x2 lattice Bose-Hubbard model using TF""" try: import tensorflow as tf except (ImportError, ModuleNotFoundError): pytest.skip("TensorFlow not installed.") if tf.__version__[:3] != "1.3": pytest.skip("Incorrect TensorFlow version") sf.hbar = hbar prog = sf.Program(2) H = bose_hubbard(1, 2, self.J, self.U) with prog.context as q: Fock(2) | q[0] BoseHubbardPropagation(H, self.t, self.k) | q eng = sf.Engine("tf", backend_options={"cutoff_dim": 7}) state = eng.run(prog).state Hm = -self.J*np.sqrt(2)*np.array([[0, 1, 0], [1, 0, 1], [0, 1, 0]]) \ + self.U*np.diag([1, 0, 1]) init_state = np.array([1, 0, 0]) exp = np.abs(np.dot(expm(-1j * self.t * Hm), init_state))**2 assert np.allclose(state.fock_prob([2, 0]), exp[0], rtol=tol) assert np.allclose(state.fock_prob([1, 1]), exp[1], rtol=tol) assert np.allclose(state.fock_prob([0, 2]), exp[2], rtol=tol)
def test_truncations(states, truncations=[10, 15, 20]): batch_size = states.shape[0] x = tf.placeholder(tf.complex64, shape=[batch_size, 3]) eng, q = sf.Engine(1) with eng: Sgate(x[:, 0]) | q[0] Dgate(x[:, 1]) | q[0] Vgate(x[:, 2]) | q[0] sess = tf.Session() sess.run(tf.global_variables_initializer()) traces = np.zeros([batch_size, len(truncations)]) for n in range(len(truncations)): state = eng.run('tf', eval=False, batch_size=batch_size, cutoff_dim=truncations[n]) trace = tf.real(state.trace()) traces[:, n] = sess.run(trace, feed_dict={x: states}) print("Evaluated T={}".format(truncations[n])) import matplotlib.pyplot as plt for n in range(len(truncations)): plt.subplot(len(truncations), 1, n + 1) plt.hist(traces[:, n], bins=25) plt.xlabel("Trace") plt.ylabel("Frequency") plt.ylim([0, batch_size]) plt.show()
def test_rotation(self, hbar): """Test rotation gives correct means and cov""" prog = sf.Program(1) eng = sf.Engine("gaussian") x = 0.2 p = 0.3 phi = 0.123 H, t = rotation(phi, hbar=hbar) with prog.context as q: Xgate(x) | q[0] Zgate(p) | q[0] Sgate(2) | q[0] GaussianPropagation(H, t) | q[0] state = eng.run(prog).state # test the covariance matrix res = state.cov() V = np.diag([np.exp(-4), np.exp(4)]) * hbar / 2 expected = rot(phi) @ V @ rot(phi).T assert np.allclose(res, expected) # test the vector of means res = state.means() exp = rot(phi) @ np.diag(np.exp([-2, 2])) @ np.array([x, p]) assert np.allclose(res, exp)
def test_squeezing(self, hbar): """Test squeezing gives correct means and cov""" prog = sf.Program(1) eng = sf.Engine("gaussian") x = 0.2 p = 0.3 r = 0.42 phi = 0.123 H, t = squeezing(r, phi, hbar=hbar) with prog.context as q: Xgate(x) | q[0] Zgate(p) | q[0] GaussianPropagation(H, t) | q[0] state = eng.run(prog).state # test the covariance matrix res = state.cov() S = rot(phi / 2) @ np.diag(np.exp([-r, r])) @ rot(phi / 2).T V = S @ S.T * hbar / 2 assert np.allclose(res, V) # test the vector of means res = state.means() exp = S @ np.array([x, p]) assert np.allclose(res, exp)
def test_displaced_oscillator(self): """Test that a forced quantum oscillator produces the correct self.logTestName() trajectory in the phase space""" H = QuadOperator('q0 q0', 0.5) H += QuadOperator('p0 p0', 0.5) H -= QuadOperator('q0', self.F) res = [] tlist = np.arange(0, self.t, self.dt) eng = sf.Engine("gaussian") for idx, t in enumerate(tlist): #pylint: disable=unused-variable prog = sf.Program(1) with prog.context as q: Xgate(self.x0) | q[0] Zgate(self.p0) | q[0] GaussianPropagation(H, self.t) | q state = eng.run(prog).state eng.reset() res.append(state.means().tolist()) res = np.array(res)[-1] expected = self.displaced_oscillator_soln(self.t) assert np.allclose(res, expected)
def test_quadratic_phase(self, hbar): """Test quadratic phase gives correct means and cov""" prog = sf.Program(1) eng = sf.Engine("gaussian") x = 0.2 p = 0.3 s = 0.432 H, t = quadratic_phase(s) with prog.context as q: Xgate(x) | q[0] Zgate(p) | q[0] GaussianPropagation(H, t) | q[0] state = eng.run(prog).state # test the covariance matrix res = state.cov() expected = np.array([[1, s], [s, 1 + s**2]]) * hbar / 2 assert np.allclose(res, expected) # test the vector of means res = state.means() expected = np.array([x, p + s * x]) assert np.allclose(res, expected)
def __init__(self): self.X = tf.placeholder(tf.float32, [1]) self.Y = tf.placeholder(tf.float32, [1]) self.alpha0 = tf.Variable(0.1) self.alpha1 = tf.Variable(0.1) self.alpha2 = tf.Variable(0.1) self.alpha3 = tf.Variable(0.1) self.alpha4 = tf.Variable(0.1) self.alpha5 = tf.Variable(0.1) self.alpha6 = tf.Variable(0.1) self.alpha7 = tf.Variable(0.1) self.alpha8 = tf.Variable(0.1) self.eng, self.q = sf.Engine(1) with self.eng: Dgate(self.X[0], 0.) | self.q[0] Dgate(self.alpha1) | self.q[0] Sgate(self.alpha2) | self.q[0] Vgate(self.alpha0) | self.q[0] Dgate(self.alpha4) | self.q[0] Sgate(self.alpha5) | self.q[0] Vgate(self.alpha3) | self.q[0] Dgate(self.alpha7) | self.q[0] Sgate(self.alpha8) | self.q[0] Vgate(self.alpha6) | self.q[0] self.state = self.eng.run('tf', cutoff_dim=10, eval=False) self.p0 = self.state.fock_prob([2]) self.circuit_output = [self.p0 * 10] self.costf = tf.reduce_sum(tf.square(self.circuit_output[0] - self.Y)) self.optimize = tf.train.GradientDescentOptimizer(0.1) self.trainop = self.optimize.minimize(self.costf) self.sess = tf.Session() self.sess.run(tf.global_variables_initializer())
def circuit(X, params): eng, q = sf.Engine(2) # Since X is a batch of data, define a circuit for a single input # If you use the tf backend, you can pass batches into gates # like in the supervised tf learner example. def single_input_circuit(x): eng.reset() with eng: Dgate(x[0], 0.) | q[0] Dgate(x[1], 0.) | q[1] BSgate(phi=params[0]) | (q[0], q[1]) BSgate() | (q[0], q[1]) state = eng.run('fock', cutoff_dim=10, eval=True) # Define the output as the probability of measuring |0,2> as opposed to |2,0> p0 = state.fock_prob([0, 2]) p1 = state.fock_prob([2, 0]) normalization = p0 + p1 + 1e-10 output = p1 / normalization return output # Apply the single circuit to every input in the batch circuit_output = [single_input_circuit(x) for x in X] return circuit_output
def circuit(): phi = make_param(name='phi', stdev=0.2, regularize=False) theta = make_param(name='theta', stdev=0.2, regularize=False) a = make_param(name='a', stdev=0.2, regularize=True, monitor=True) rtheta = make_param(name='rtheta', stdev=0.2, regularize=False, monitor=True) r = make_param(name='r', stdev=0.2, regularize=True, monitor=True) kappa = make_param(name='kappa', stdev=0.2, regularize=True, monitor=True) eng, q = sf.Engine(2) with eng: BSgate(phi, theta) | (q[0], q[1]) Dgate(a) | q[0] Rgate(rtheta) | q[0] Sgate(r) | q[0] Kgate(kappa) | q[0] state = eng.run('tf', cutoff_dim=7, eval=False) circuit_output = state.all_fock_probs() return circuit_output
def test_cov_is_pure(): """Tests space unrolling when going into the Gaussian backend""" delays = [1, 6, 36] modes = 216 angles = np.concatenate([ generate_valid_bs_sequence(delays, modes), generate_valid_r_sequence(delays, modes) ]) net = modes + sum(delays) d = len(delays) n, N = get_mode_indices(delays) prog = sf.TDMProgram([N]) vac_modes = sum(delays) with prog.context(*angles) as (p, q): Sgate(0.8) | q[n[0]] for i in range(d): Rgate(p[i + d]) | q[n[i]] BSgate(p[i], np.pi / 2) | (q[n[i + 1]], q[n[i]]) prog.space_unroll() eng = sf.Engine(backend="gaussian") results = eng.run(prog) cov = results.state.cov() mu = np.zeros(len(cov)) mu_vac, cov_vac = reduced_state(mu, cov, list(range(vac_modes))) mu_comp, cov_comp = reduced_state(mu, cov, list(range(vac_modes, net))) assert np.allclose(cov_vac, 0.5 * (sf.hbar) * np.identity(2 * vac_modes)) assert is_pure_cov(cov_comp, hbar=sf.hbar)
def setup_two_mode_circuit(self, setup_eng, cutoff): """Create the circuit for following tests""" eng_ref, q = setup_eng(2) S = ops.Sgate(2) B = ops.BSgate(2.234, -1.165) initial_state = np.complex64( np.random.rand(*[cutoff] * 4) + 1j * np.random.rand(*[cutoff] * 4)) with eng_ref: ops.DensityMatrix(initial_state) | q S | q[0] B | q S | q[1] B | q eng, q = sf.Engine(2) with eng: S | q[0] B | q S | q[1] B | q rho = eng_ref.run().dm() return eng, rho, initial_state
def test_cat_state_wigners(self, alpha, phi, representation): r"""Checks that the real and complex cat state representations have the same Wigner functions as the cat state from the Fock backend.""" x = np.linspace(-2 * alpha, 2 * alpha, 100) p = np.linspace(-2 * alpha, 2 * alpha, 100) prog_complex_cat = sf.Program(1) with prog_complex_cat.context as qb: sf.ops.Catstate(alpha, phi, representation=representation) | qb[0] backend_bosonic = bosonic.BosonicBackend() backend_bosonic.run_prog(prog_complex_cat) wigner_bosonic = backend_bosonic.state().wigner(0, x, p) prog_cat_fock = sf.Program(1) with prog_cat_fock.context as qf: if alpha != 0: sf.ops.Catstate(alpha, phi) | qf[0] else: sf.ops.Vacuum() | qf[0] eng = sf.Engine("fock", backend_options={"cutoff_dim": 20}) results = eng.run(prog_cat_fock) wigner_fock = results.state.wigner(0, x, p) assert np.allclose(wigner_bosonic, wigner_fock, rtol=1e-3, atol=1e-6)
def give_outcome_sf(self, beta, layer): """ Returns outcome according to current layer (needed to compute the "current" intensity). To accomplish this, it is used the Strawberryfields simulator, as a proof of principle that this can be easily done with this photonic platform. Notice that - if desired - the full experiment could be implemented with strawberryfields, considering a number of self.layers modes, and applying the displacements with the corresponding feed-forward. For the moment, as only the outcomes at each photodetector are needed to learn the correct displacements, we obtained them separately. """ #Actually, if all intensities are equal, you don't need to keep track of the layer here... effective_attenuation = np.prod(np.sin(self.at[:layer])) * np.cos( self.at[layer]) #Warning one! eng = sf.Engine("fock", backend_options={"cutoff_dim": 4}) prog = sf.Program(1) with prog.context as q: Coherent(a=(effective_attenuation * self.phase * self.amplitude) - beta) | q[0] MeasureFock() | q[0] results = eng.run(prog) outcome = np.array(outcome_from_fock(results).samples)[0] if outcome == 0: return 0 else: return 1
def circuit(params, a, m, cutoff): """Runs the constrained variational circuit with specified parameters, returning the output fidelity to the requested ON state, as well as the post-selection probability. Args: params (list): list of gate parameters for the constrained variational quantum circuit. This should contain the following values in the following order: * ``'sq0' = (r, phi)``: the squeezing magnitude and phase on mode 0 * ``'disp0' = (r, phi)``: the displacement magnitude and phase on mode 0 * ``'sq1' = (r, phi)``: the squeezing magnitude and phase on mode 1 * ``'disp1' = (r, phi)``: the displacement magnitude and phase on mode 1 * ``'BS' = (theta, phi)``: the beamsplitter angles a (float): the ON state parameter m (int): the Fock state measurement to be post-selected cutoff (int): the Fock basis truncation Returns: tuple: a tuple containing the output fidelity to the target ON state, the probability of post-selection, the state norm before entering the beamsplitter, the state norm after exiting the beamsplitter, and the density matrix of the output state. """ # define target state ONdm = on_state(a, cutoff) # unpack circuit parameters sq0_r, sq0_phi, disp0_r, disp0_phi, sq1_r, sq1_phi, disp1_r, disp1_phi, theta, phi = params # quantum circuit prior to entering the beamsplitter prog1 = sf.Program(2) with prog1.context as q1: Sgate(sq0_r, sq0_phi) | q1[0] Dgate(disp0_r, disp0_phi) | q1[0] Sgate(sq1_r, sq1_phi) | q1[1] Dgate(disp1_r, disp1_phi) | q1[1] eng = sf.Engine("fock", backend_options={"cutoff_dim": cutoff}) stateIn = eng.run(prog1).state normIn = np.abs(stateIn.trace()) # norm of output state and probability prog_BS = sf.Program(2) with prog_BS.context as q1: BSgate(theta, phi) | (q1[0], q1[1]) stateOut = eng.run(prog_BS).state normOut = np.abs(stateOut.trace()) rho = stateOut.dm() # probability of meausring m1 and m2 prob = np.abs(np.trace(rho[m, m])) # output state rhoB = rho[m, m] / prob fidelity = np.abs(np.trace(np.einsum('ij,jk->ik', rhoB, ONdm))) return (fidelity, prob, normIn, normOut, rhoB)
def ClosestClassicalState(r, K, eta, U, t): M = len(U) ap = eta * np.exp(2 * r) + 1 - eta an = eta * np.exp(-2 * r) + 1 - eta ss = 0.25 * np.log(ap / an) ns = 0.5 * (np.sqrt(ap * an) - 1) sc = 0.5 * np.log(2 * ns + 1) nt = 0.5 - 0.5 * np.sqrt(1 + 2 * t * np.sinh(2 * sc) * np.exp(2 * ss)) s0 = 0.5 * np.log((2 * nt + 1) / t) if ss < s0: st = ss nt = ns else: s0 = 0.5 * np.log((2 * nt + 1) / t) st = s0 # build the state prog = sf.Program(M) with prog.context as q: for i in range(K): Thermal(nt) | q[i] Sgate(st) | q[i] Interferometer(U) | q eng = sf.Engine('gaussian') result = eng.run(prog) cov = result.state.cov() return cov
def test_Ggate_optimization(self, setup_backend, pure): if not pure: pytest.skip("Test only runs on pure states") num_mode = 2 eng = sf.Engine("tf", backend_options={"cutoff_dim": 5}) prog = sf.Program(num_mode) optimizer = tf.keras.optimizers.SGD(learning_rate=0.001) S = tf.Variable(random_symplectic(num_mode), dtype=tf.complex128) d = tf.Variable(np.random.random(2 * num_mode), dtype=tf.complex128) prog = sf.Program(num_mode) with prog.context as q: ops.Ggate(S, d) | q loss_vals = [] for _ in range(11): with tf.GradientTape() as tape: state_out = eng.run(prog).state.ket() loss_val = tf.abs(state_out[1, 1] - 0.25)**2 eng.reset() grad_S, gradients_d = tape.gradient(loss_val, [S, d]) optimizer.apply_gradients([(gradients_d, d)]) sf.backends.tfbackend.ops.update_symplectic(S, grad_S, lr=0.05) loss_vals.append(loss_val) print(loss_val) assert all([bool(l1 > l2) for l1, l2 in zip(loss_vals, loss_vals[1:])])
def build_circuit(self): params_counter = 0 sgates = [] dgates = [] kgates = [] vgates = [] for gate_structure in self.gates_structure: if gate_structure[0] is Sgate: sgates.append( ParametrizedGate(gate_structure[0], gate_structure[1], [ make_param(**gate_structure[2]), make_param(**gate_structure[3]) ])) if gate_structure[0] is Dgate: dgates.append( ParametrizedGate(gate_structure[0], gate_structure[1], [ make_param(**gate_structure[2]), make_param(**gate_structure[3]) ])) if gate_structure[0] is Kgate: kgates.append( ParametrizedGate(gate_structure[0], gate_structure[1], [make_param(**gate_structure[2])])) if gate_structure[0] is Vgate: vgates.append( ParametrizedGate(gate_structure[0], gate_structure[1], [make_param(**gate_structure[2])])) eng, q = sf.Engine(self.n_qumodes) rl, U = takagi(self.adj_matrix) initial_squeezings = np.arctanh(rl) with eng: Interferometer(U) | q for i, squeeze_value in enumerate(initial_squeezings): Sgate(squeeze_value) | i if len(sgates) != 0: Interferometer(self.interferometer_matrix) | q for gate in sgates: gate.gate(gate.params[0], gate.params[1]) | gate.qumodes if len(dgates) != 0: Interferometer(self.interferometer_matrix) | q for gate in dgates: gate.gate(gate.params[0], gate.params[1]) | gate.qumodes for gate in kgates: gate.gate(gate.params[0]) | gate.qumodes for gate in vgates: gate.gate(gate.params[0]) | gate.qumodes circuit = {} circuit['eng'] = eng circuit['q'] = q return circuit
def test_not_drawable(self, tmpdir): eng, q = sf.Engine(3) with eng: ops.BSgate(0, 2) | (q[0], q[2]) with pytest.raises(NotDrawableException): eng.draw_circuit(print_queued_ops=True, tex_dir=tmpdir)
def test_apply_gate(self): """Test successful gate application""" eng, _ = sf.Engine(2) with eng: ops.Dgate(0.5) | 0 assert len(eng.cmd_queue) == 1
def test_invalid(self): """cannot referring to a register with a non-integral or RegRef object""" eng, _ = sf.Engine(2) with eng: with pytest.raises(engine.RegRefError, match="using integers and RegRefs"): ops.Dgate(0) | 1.2
def test_wrong_engine(self): """Test that acting on a mode not belonging to the engine raises error""" eng, _ = sf.Engine(2) q_new = engine.RegRef(3) with eng: with pytest.raises(engine.RegRefError, match="Unknown RegRef."): ops.Dgate(0.5) | q_new