def testConcatenation(self): self.assertEqual( parse_circuit_strings('a(1) + b(2)'), Concatenation(CircuitSymbol('a', 1), CircuitSymbol('b', 2))) self.assertEqual( parse_circuit_strings('a(1) + b(2) + c(3)'), Concatenation(CircuitSymbol('a', 1), CircuitSymbol('b', 2), CircuitSymbol('c', 3)))
def testSeries(self): self.assertEqual( parse_circuit_strings('a(2) << b(2)'), SeriesProduct(CircuitSymbol('a', 2), CircuitSymbol('b', 2))) self.assertEqual( parse_circuit_strings('a(5) << b(5) << c(5)'), SeriesProduct(CircuitSymbol('a', 5), CircuitSymbol('b', 5), CircuitSymbol('c', 5)))
def setup_qnet_sys(n_cavity, stark_shift=False, zero_phi=True, keep_delta=False, slh=True): """Return the effective SLH model (if `slh` is True) or a the symbolic circuit (if `slh` is False) for a two-node network, together with the symbols and operators in each node""" Sym1, Op1 = qnet_node_system('1', n_cavity, zero_phi=zero_phi, keep_delta=keep_delta) Sym2, Op2 = qnet_node_system('2', n_cavity, zero_phi=zero_phi, keep_delta=keep_delta) if slh: H1 = node_hamiltonian(Sym1, Op1, stark_shift=stark_shift, zero_phi=zero_phi, keep_delta=keep_delta) H2 = node_hamiltonian(Sym2, Op2, stark_shift=stark_shift, zero_phi=zero_phi, keep_delta=keep_delta) S = identity_matrix(1) κ = Sym1['kappa'] L1 = sympy.sqrt(2 * κ) * Op1['a'] κ = Sym2['kappa'] L2 = sympy.sqrt(2 * κ) * Op2['a'] SLH1 = SLH(S, [ L1, ], H1) SLH2 = SLH(S, [ L2, ], H2) Node1 = CircuitSymbol("Node1", cdim=1) Node2 = CircuitSymbol("Node2", cdim=1) components = [Node1, Node2] connections = [ ((Node1, 0), (Node2, 0)), ] circuit = connect(components, connections) if slh: network = circuit.substitute({Node1: SLH1, Node2: SLH2}) else: network = circuit return network, Sym1, Op1, Sym2, Op2
def testDrawNested(self): self.assertCanBeDrawn( SeriesProduct( CircuitSymbol('a', 2), Concatenation(CircuitSymbol('b', 1), CircuitSymbol('c', 1)))) self.assertCanBeDrawn( Concatenation( CircuitSymbol('a', 2), SeriesProduct(CircuitSymbol('b', 1), CircuitSymbol('c', 1)))) self.assertCanBeDrawn( Feedback( Concatenation( CircuitSymbol('a', 2), SeriesProduct(CircuitSymbol('b', 1), CircuitSymbol('c', 1))), 2, 0))
def testNested(self): self.assertEqual( parse_circuit_strings('a(2) << (b(1) + c(1))'), SeriesProduct( CircuitSymbol('a', 2), Concatenation(CircuitSymbol('b', 1), CircuitSymbol('c', 1)))) self.assertEqual( parse_circuit_strings('a(2) + (b(1) << c(1))'), Concatenation( CircuitSymbol('a', 2), SeriesProduct(CircuitSymbol('b', 1), CircuitSymbol('c', 1)))) self.assertEqual( parse_circuit_strings('[a(2) + (b(1) << c(1))]_(2->0)'), Feedback( Concatenation( CircuitSymbol('a', 2), SeriesProduct(CircuitSymbol('b', 1), CircuitSymbol('c', 1))), 2, 0))
def setup_qnet_2chan_chain(n_cavity, n_nodes, slh=True, topology=None): """Set up a chain of JC system with two channels Args: n_cavity (int): Number of levels in the cavity (numerical truncation) n_nodes (int): Number of nodes in the chain slh (bool): If True, return effective SLH object. If False, return circuit of linked nodes topology (str or None): How the nodes should be linked up, see below Notes: The `topology` can take the following values: * None (default): chain is open-endeded. The total system will have two I/O channels * "FB": The rightmost output is fed back into the rightmost input:: >-------+ | <-------+ """ # Set up the circuit components = [] connections = [] prev_node = None for i in range(n_nodes): ind = i + 1 cur_node = CircuitSymbol("Node%d" % ind, cdim=2) components.append(cur_node) if prev_node is not None: if topology in [None, 'FB']: connections.append(((prev_node, 1), (cur_node, 0))) connections.append(((cur_node, 0), (prev_node, 1))) else: raise ValueError("Unknown topology: %s" % topology) prev_node = cur_node if topology == 'FB': connections.append(((cur_node, 1), (cur_node, 1))) circuit = connect(components, connections) if slh: slh_map = slh_map_2chan_chain(components, n_cavity) return circuit.substitute(slh_map).toSLH() else: return circuit
def testFeedback(self): self.assertEqual(parse_circuit_strings('[M(5)]_(3->4)'), Feedback(CircuitSymbol('M', 5), 3, 4))
def testSymbol(self): self.assertEqual(parse_circuit_strings('a(2)'), CircuitSymbol('a', 2)) self.assertEqual(parse_circuit_strings('a(5)'), CircuitSymbol('a', 5)) self.assertEqual(parse_circuit_strings('a_longer_string(5)'), CircuitSymbol('a_longer_string', 5))
def testDrawFeedback(self): self.assertCanBeDrawn(Feedback(CircuitSymbol('M', 5), 3, 4))
def testDrawConcatenation(self): self.assertCanBeDrawn( Concatenation(CircuitSymbol('a', 5), CircuitSymbol('b', 5)))
def testDrawSeries(self): self.assertCanBeDrawn( SeriesProduct(CircuitSymbol('a', 5), CircuitSymbol('b', 5)))
def testDrawSymbol(self): self.assertCanBeDrawn(CircuitSymbol('b', 1)) self.assertCanBeDrawn(CircuitSymbol('b', 2))
def get_symbol(cdim): global symbol_counter sym = CircuitSymbol('test_%d' % symbol_counter, cdim) symbol_counter += 1 return sym
def testFactorizePermutation(self): self.assertEqual(full_block_perm((0, 1, 2), (1, 1, 1)), (0, 1, 2)) self.assertEqual(full_block_perm((0, 2, 1), (1, 1, 1)), (0, 2, 1)) self.assertEqual(full_block_perm((0, 2, 1), (1, 1, 2)), (0, 3, 1, 2)) self.assertEqual(full_block_perm((0, 2, 1), (1, 2, 3)), (0, 4, 5, 1, 2, 3)) self.assertEqual(full_block_perm((1, 2, 0), (1, 2, 3)), (3, 4, 5, 0, 1, 2)) self.assertEqual(full_block_perm((3, 1, 2, 0), (1, 2, 3, 4)), (9, 4, 5, 6, 7, 8, 0, 1, 2, 3)) self.assertEqual(block_perm_and_perms_within_blocks((9, 4, 5, 6, 7, 8, 0, 1, 2, 3 ), (1,2,3,4)), \ ((3,1,2,0), [(0,),(0,1),(0,1,2),(0,1,2,3)])) A1, A2, A3, A4 = get_symbols(1, 2, 3, 4) new_lhs, permuted_rhs, new_rhs = P_sigma( 9, 4, 5, 6, 7, 8, 0, 1, 2, 3)._factorize_for_rhs(A1 + A2 + A3 + A4) self.assertEqual(new_lhs, cid(10)) self.assertEqual(permuted_rhs, (A4 + A2 + A3 + A1)) self.assertEqual(new_rhs, P_sigma(9, 4, 5, 6, 7, 8, 0, 1, 2, 3)) p = P_sigma(0, 1, 4, 2, 3, 5) expr = A2 + A3 + A1 new_lhs, permuted_rhs, new_rhs = p._factorize_for_rhs(expr) self.assertEqual(new_lhs, cid(6)) self.assertEqual(permuted_rhs, A2 + (P_sigma(2, 0, 1) << A3) + A1) self.assertEqual(new_rhs, cid(6)) p = P_sigma(0, 3, 1, 2) p_r = P_sigma(2, 0, 1) assert p == cid(1) + p_r A = get_symbol(2) new_lhs, permuted_rhs, new_rhs = p._factorize_for_rhs( cid(1) + A + cid(1)) self.assertEqual(new_lhs, P_sigma(0, 1, 3, 2)) self.assertEqual(permuted_rhs, (cid(1) + (P_sigma(1, 0) << A) + cid(1))) self.assertEqual(new_rhs, cid(4)) new_lhs, permuted_rhs, new_rhs = p._factorize_for_rhs(cid(2) + A) self.assertEqual(new_lhs, cid(4)) self.assertEqual(permuted_rhs, (cid(1) + A + cid(1))) self.assertEqual(new_rhs, p) self.assertEqual( p.series_inverse() << (cid(2) + A), cid(1) + SeriesProduct( P_sigma(0, 2, 1), Concatenation(SeriesProduct(P_sigma(1, 0), A), cid(1)), P_sigma(2, 0, 1))) self.assertEqual( p.series_inverse() << (cid(2) + A) << p, cid(1) + (p_r.series_inverse() << (cid(1) + A) << p_r)) new_lhs, permuted_rhs, new_rhs = P_sigma(4, 2, 1, 3, 0)._factorize_for_rhs( (A4 + cid(1))) self.assertEqual(new_lhs, cid(5)) self.assertEqual(permuted_rhs, (cid(1) + (P_sigma(3, 1, 0, 2) << A4))) self.assertEqual(new_rhs, map_signals_circuit({4: 0}, 5)) ## special test case that helped find the major permutation block structure factorization bug p = P_sigma(3, 4, 5, 0, 1, 6, 2) q = cid(3) + CircuitSymbol('NAND1', 4) new_lhs, permuted_rhs, new_rhs = p._factorize_for_rhs(q) self.assertEqual(new_lhs, P_sigma(0, 1, 2, 6, 3, 4, 5)) self.assertEqual(permuted_rhs, (P_sigma(0, 1, 3, 2) << CircuitSymbol('NAND1', 4)) + cid(3)) self.assertEqual(new_rhs, P_sigma(4, 5, 6, 0, 1, 2, 3))