def test_copy(self): mp = create_freezable_circuit(3) mp.perturb(amount=5, mode=Mode.SET) mp.perturb(amount=2, axis=Axis.LAYERS, mode=Mode.SET, mask=FreezeMask) mp_copy = mp.copy() assert pnp.array_equal(mp.full_mask(FreezeMask), mp_copy.full_mask(FreezeMask)) mp.perturb(amount=5, mode=Mode.RESET) mp.perturb(amount=2, axis=Axis.LAYERS, mode=Mode.RESET, mask=FreezeMask) assert pnp.sum(mp.full_mask(FreezeMask)) == 0 assert not pnp.array_equal(mp.full_mask(FreezeMask), mp_copy.full_mask(FreezeMask))
def test_plain(self): optimizer = L_BFGS_B() mp = create_circuit(3, layer_size=2) mp_step = mp.copy() circuit = qml.QNode( plain_variational_circuit, device(mp.mask(Axis.WIRES).size), ) def cost_fn(params): return plain_cost( params, circuit, ) base_cost = cost_fn(mp.parameters) _params, final_cost, _gradient = optimizer.optimize( cost_fn, mp.parameters) params, step_cost, _gradient = optimizer.step_cost_and_grad( cost_fn, mp_step.parameters) assert final_cost < base_cost assert step_cost < base_cost assert final_cost < step_cost new_params = optimizer.step(cost_fn, mp_step.parameters) assert pnp.array_equal(params, new_params) new_params, new_cost = optimizer.step_and_cost(cost_fn, new_params) assert new_cost < step_cost
def test_freeze(self): size = 3 mp = create_freezable_circuit(size) assert (mp.differentiable_parameters.size == mp.mask( Axis.PARAMETERS, mask_type=FreezeMask).size) # Test 0 amount # FIXME: does not test the same thing, befor it tested the whole mask mask = mp.full_mask(FreezeMask) mp.perturb(axis=Axis.LAYERS, amount=0, mode=Mode.SET, mask=FreezeMask) assert pnp.array_equal(mp.full_mask(FreezeMask), mask) # Test freezing of layers mp.perturb(axis=Axis.LAYERS, amount=1, mode=Mode.SET, mask=FreezeMask) assert mp.differentiable_parameters.size == mp.mask( Axis.PARAMETERS).size - size assert pnp.sum(mp.mask(axis=Axis.LAYERS, mask_type=FreezeMask)) == 1 assert pnp.sum( mp._accumulated_mask()) == size # dropout and freeze mask # Test freezing of wires mp.perturb(axis=Axis.WIRES, amount=1, mode=Mode.SET, mask=FreezeMask) assert pnp.sum(mp.mask(axis=Axis.WIRES, mask_type=FreezeMask)) == 1 assert (pnp.sum(mp._accumulated_mask()) == 2 * size - 1 ) # dropout and freeze mask # Test freezing of parameters mp.perturb(axis=Axis.PARAMETERS, amount=1, mode=Mode.SET, mask=FreezeMask) assert pnp.sum(mp.mask(axis=Axis.PARAMETERS, mask_type=FreezeMask)) == 1 assert (pnp.sum(mp._accumulated_mask()) == 2 * size - 1 or pnp.sum( mp._accumulated_mask()) == 2 * size # dropout and freeze mask ) # Test wrong axis with pytest.raises(ValueError): mp.perturb(axis=10, amount=1, mode=Mode.SET, mask=FreezeMask)
def test_sample_shape_and_dtype(self, gaussian_device_2_wires, observable, n_sample): """Test that the sample function outputs samples of the right size""" sample = gaussian_device_2_wires.sample(observable, [0], [], n_sample) assert np.array_equal(sample.shape, (n_sample, )) assert sample.dtype == np.dtype("float")
def test_init(self): size = 3 with pytest.raises(AssertionError): DropoutMask((size, ), mask=pnp.array([True, True, False, False])) with pytest.raises(AssertionError): DropoutMask((size, ), mask=pnp.array([0, 1, 3])) preset = [False, True, False] mp = DropoutMask((size, ), mask=pnp.array(preset)) assert pnp.array_equal(mp.mask, preset)
def test_sample_dimensions(self, tensornet_device_2_wires): """Tests if the samples returned by the sample function have the correct dimensions """ # Explicitly resetting is necessary as the internal # state is set to None in __init__ and only properly # initialized during reset tensornet_device_2_wires.reset() tensornet_device_2_wires.apply('RX', wires=[0], par=[1.5708]) tensornet_device_2_wires.apply('RX', wires=[1], par=[1.5708]) tensornet_device_2_wires.shots = 10 s1 = tensornet_device_2_wires.sample('PauliZ', [0], []) assert np.array_equal(s1.shape, (10,)) tensornet_device_2_wires.shots = 12 s2 = tensornet_device_2_wires.sample('PauliZ', [1], []) assert np.array_equal(s2.shape, (12,)) tensornet_device_2_wires.shots = 17 s3 = tensornet_device_2_wires.sample('CZ', [0, 1], []) assert np.array_equal(s3.shape, (17,))
def test_operation_transformed_into_qubit_unitary(self, recorder): """Tests loading a circuit with operations that can be converted, but not natively supported by PennyLane.""" qc = QuantumCircuit(3, 1) qc.ch([0], [1]) quantum_circuit = load(qc) with recorder: quantum_circuit() assert recorder.queue[0].name == "QubitUnitary" assert len(recorder.queue[0].parameters) == 1 assert np.array_equal(recorder.queue[0].parameters[0], ex.CHGate().to_matrix()) assert recorder.queue[0].wires == Wires([0, 1])
def test_reduced_row_echelon(binary_matrix, result): r"""Test that _reduced_row_echelon returns the correct result.""" # build row echelon form of the matrix shape = binary_matrix.shape for irow in range(shape[0]): pivot_index = 0 if np.count_nonzero(binary_matrix[irow, :]): pivot_index = np.nonzero(binary_matrix[irow, :])[0][0] for jrow in range(shape[0]): if jrow != irow and binary_matrix[jrow, pivot_index]: binary_matrix[jrow, :] = (binary_matrix[jrow, :] + binary_matrix[irow, :]) % 2 indices = [ irow for irow in range(shape[0] - 1) if np.array_equal(binary_matrix[irow, :], np.zeros(shape[1])) ] temp_row_echelon_matrix = binary_matrix.copy() for row in indices[::-1]: temp_row_echelon_matrix = np.delete(temp_row_echelon_matrix, row, axis=0) row_echelon_matrix = np.zeros(shape, dtype=int) row_echelon_matrix[:shape[0] - len(indices), :] = temp_row_echelon_matrix # build reduced row echelon form of the matrix from row echelon form for idx in range(len(row_echelon_matrix))[:0:-1]: nonzeros = np.nonzero(row_echelon_matrix[idx])[0] if len(nonzeros) > 0: redrow = (row_echelon_matrix[idx, :] % 2).reshape(1, -1) coeffs = ((-row_echelon_matrix[:idx, nonzeros[0]] / row_echelon_matrix[idx, nonzeros[0]]) % 2).reshape( 1, -1) row_echelon_matrix[:idx, :] = (row_echelon_matrix[:idx, :] + (coeffs.T * redrow) % 2) % 2 # get reduced row echelon form from the _reduced_row_echelon function rref_bin_mat = _reduced_row_echelon(binary_matrix) assert (rref_bin_mat == row_echelon_matrix).all() assert (rref_bin_mat == result).all()
def test_two_qubit_operations_supported_by_pennylane(self, recorder): """Tests loading a circuit with the two-qubit operations supported by PennyLane.""" two_wires = [0, 1] qc = QuantumCircuit(2, 1) unitary_op = [[1, 0, 0, 0], [0, 0, 1j, 0], [0, 1j, 0, 0], [0, 0, 0, 1]] iswap_op = Operator(unitary_op) qc.cx(*two_wires) qc.cz(*two_wires) qc.swap(*two_wires) qc.unitary(iswap_op, [0, 1], label='iswap') quantum_circuit = load(qc) with recorder: quantum_circuit() assert len(recorder.queue) == 4 assert recorder.queue[0].name == 'CNOT' assert recorder.queue[0].params == [] assert recorder.queue[0].wires == two_wires assert recorder.queue[1].name == 'CZ' assert recorder.queue[1].params == [] assert recorder.queue[1].wires == two_wires assert recorder.queue[2].name == 'SWAP' assert recorder.queue[2].params == [] assert recorder.queue[2].wires == two_wires assert recorder.queue[3].name == 'QubitUnitary' assert len(recorder.queue[3].params) == 1 assert np.array_equal(recorder.queue[3].params[0], np.array(unitary_op)) assert recorder.queue[3].wires == two_wires
def generate_paulis(generators, num_qubits): r"""Generate the single qubit Pauli-X operators :math:`\sigma^{x}_{i}` for each symmetry :math:`\tau_j`, such that it anti-commutes with :math:`\tau_j` and commutes with all others symmetries :math:`\tau_{k\neq j}`. These are required to obtain the Clifford operators :math:`U` for the Hamiltonian :math:`H`. Args: generators (list[Hamiltonian]): list of generators of symmetries, taus, for the Hamiltonian num_qubits (int): number of wires required to define the Hamiltonian Return: list[Observable]: list of single-qubit Pauli-X operators which will be used to build the Clifford operators :math:`U`. **Example** >>> generators = [qml.Hamiltonian([1.0], [qml.PauliZ(0) @ qml.PauliZ(1)]), ... qml.Hamiltonian([1.0], [qml.PauliZ(0) @ qml.PauliZ(2)]), ... qml.Hamiltonian([1.0], [qml.PauliZ(0) @ qml.PauliZ(3)])] >>> generate_paulis(generators, 4) [PauliX(wires=[1]), PauliX(wires=[2]), PauliX(wires=[3])] """ ops_generator = [ g.ops[0] if isinstance(g.ops, list) else g.ops for g in generators ] bmat = _binary_matrix(ops_generator, num_qubits) paulix_ops = [] for row in range(bmat.shape[0]): bmatrow = bmat[row] bmatrest = np.delete(bmat, row, axis=0) for col in range(bmat.shape[1] // 2): # Anti-commutes with the (row) and commutes with all other symmetries. if bmatrow[col] and np.array_equal( bmatrest[:, col], np.zeros(bmat.shape[0] - 1, dtype=int)): paulix_ops.append(qml.PauliX(col)) break return paulix_ops
def test_init(self): mp = self._create_circuit(3) assert mp assert len(mp.mask(Axis.WIRES)) == 3 assert len(mp.mask(Axis.LAYERS)) == 3 assert mp.mask(Axis.PARAMETERS).shape == (3, 3) size = 3 with pytest.raises(AssertionError): MaskedCircuit( parameters=pnp.random.uniform(low=0, high=1, size=(size, size)), layers=size - 1, wires=size, ) with pytest.raises(AssertionError): MaskedCircuit( parameters=pnp.random.uniform(low=0, high=1, size=(size, size)), layers=size + 1, wires=size, ) with pytest.raises(AssertionError): MaskedCircuit( parameters=pnp.random.uniform(low=0, high=1, size=(size, size)), layers=size, wires=size - 1, ) with pytest.raises(AssertionError): MaskedCircuit( parameters=pnp.random.uniform(low=0, high=1, size=(size, size)), layers=size, wires=size + 1, ) with pytest.raises(AssertionError): MaskedCircuit.full_circuit( parameters=pnp.random.uniform(low=0, high=1, size=(size, size)), layers=size, wires=size, entangling_mask=DropoutMask(shape=(size + 1, size)), ) with pytest.raises(NotImplementedError): MaskedCircuit( parameters=pnp.random.uniform(low=0, high=1, size=(size, size)), layers=size, wires=size, masks=[(Axis.ENTANGLING, DropoutMask)], ) mc = MaskedCircuit.full_circuit( parameters=pnp.random.uniform(low=0, high=1, size=(size, size)), layers=size, wires=size, wire_mask=DropoutMask(shape=(size, ), mask=pnp.ones((size, ), dtype=bool)), ) assert pnp.array_equal(mc.mask(Axis.WIRES), pnp.ones((size, ), dtype=bool))