Exemplo n.º 1
0
def test_get_unitary(gate: Gate) -> None:
    size = gate.get_size()
    circ = Circ(size, radixes=gate.get_radixes())
    circ.append_gate(gate, list(range(size)))
    num_params = circ.get_num_params()
    x = np.random.random((num_params, ))
    circuit = Circuit(circ)
    assert np.allclose(circ.get_unitary(x).get_numpy(), circuit.get_unitary(x))
Exemplo n.º 2
0
    def test_value(self, gate: Gate) -> None:
        circuit = Circuit(gate.get_size(), gate.get_radixes())
        assert circuit.is_differentiable()

        circuit.append_gate(gate, list(range(gate.get_size())))
        if isinstance(gate, DifferentiableUnitary):
            assert circuit.is_differentiable()
        else:
            assert not circuit.is_differentiable()
Exemplo n.º 3
0
def test_get_grad(gate: Gate) -> None:
    size = gate.get_size()
    circ = Circ(size, radixes=gate.get_radixes())
    circ.append_gate(gate, list(range(size)))
    num_params = circ.get_num_params()
    x = np.random.random((num_params, ))
    circuit = Circuit(circ)
    grad_python = circ.get_grad(x)
    grad_rust = circuit.get_grad(x)
    for py, rs in zip(grad_python, grad_rust):
        assert np.allclose(py, rs)
Exemplo n.º 4
0
 def test_radix_mismatch_2(self, qutrit_gate: Gate) -> None:
     circuit = Circuit(qutrit_gate.get_size())
     location = list(range(qutrit_gate.get_size()))
     params = [0] * qutrit_gate.get_num_params()
     op = Operation(qutrit_gate, location, params)
     try:
         circuit.check_valid_operation(op)
     except ValueError:
         return
     except BaseException:
         assert False, 'Unexpected Exception'
     assert False
Exemplo n.º 5
0
def test_get_unitary_and_grad(gate: Gate) -> None:
    size = gate.get_size()
    circ = Circ(size, radixes=gate.get_radixes())
    circ.append_gate(gate, list(range(size)))
    num_params = circ.get_num_params()
    x = np.random.random((num_params, ))
    circuit = Circuit(circ)
    utry_python, grad_python = circ.get_unitary_and_grad(x)
    utry_rust, grad_rust = circuit.get_unitary_and_grad(x)
    assert np.allclose(utry_python.get_numpy(), utry_rust)
    for i, (py, rs) in enumerate(zip(grad_python, grad_rust)):
        assert np.allclose(py, rs)
Exemplo n.º 6
0
def test_random_circuit_qubit_gates(qubit_gate: Gate) -> None:
    circ = Circ(qubit_gate.get_size())
    circ.append_gate(qubit_gate, location=list(range(qubit_gate.get_size())))
    num_params = circ.get_num_params()
    if qubit_gate.is_constant():
        assert num_params == 0
    x = np.random.random((num_params, ))
    circuit = Circuit(circ)
    py = circ.get_unitary(x).get_numpy()
    rs = circuit.get_unitary(x)
    assert py.shape == rs.shape
    assert py.dtype is rs.dtype
    np.testing.assert_allclose(py, rs, verbose=True)
Exemplo n.º 7
0
    def __init__(self, gate: Gate, frozen_params: dict[int, float]) -> None:
        """
        Create a gate which fixes some of the parameters it takes.

        Args:
            gate (Gate): The Gate to fix the parameters of.
            frozen_params (dict[int, float]): A dictionary mapping parameters
                indices to the fixed value they should be.

        Raises:
            ValueError: If any of the `frozen_params` indices are greater
                than the number of parameters `gate` takes or less than 0
                or if the total amount of `frozen_params` is larger than
                the number of parameters `gate` takes.
        """
        if not isinstance(gate, Gate):
            raise TypeError('Expected gate, got %s.' % type(gate))
        if not isinstance(frozen_params, dict):
            raise TypeError(
                'Expected dict for frozen_params, '
                'got %s.' % type(frozen_params), )
        if not len(frozen_params) <= gate.get_num_params():
            raise ValueError(
                'Too many fixed parameters specified, expected at most'
                ' %d, got %d' % (gate.get_num_params(), len(frozen_params)), )
        keys = list(frozen_params.keys())
        values = list(frozen_params.values())
        if not all(isinstance(p, int) for p in keys):
            fail_idx = [isinstance(p, int) for p in keys].index(False)
            raise TypeError(
                'Expected frozen_params keys to be int, got %s.' %
                type(keys[fail_idx]), )
        if not all(isinstance(p, (int, float)) for p in values):
            typechecks = [isinstance(p, (int, float)) for p in values]
            fail_idx = typechecks.index(False)
            raise TypeError(
                'Expected frozen_params values to be float, got %s.' %
                type(values[fail_idx]), )
        if not all(0 <= p < gate.get_num_params() for p in keys):
            fail_idx = [0 <= p < gate.get_num_params()
                        for p in keys].index(False)
            raise ValueError(
                'Expected parameter index to be non-negative integer'
                ' < %d, got %d.' % (gate.get_num_params(), keys[fail_idx]), )

        self.gate = gate
        self.num_params = gate.get_num_params() - len(frozen_params)
        self.size = gate.get_size()
        self.radixes = gate.get_radixes()
        self.frozen_params = frozen_params
        self.unfixed_param_idxs = [
            i for i in range(gate.get_num_params())
            if i not in self.frozen_params.keys()
        ]
Exemplo n.º 8
0
    def __init__(self, gate: Gate, tag: Any) -> None:
        """Associate `tag` with `gate`."""

        if not isinstance(gate, Gate):
            raise TypeError('Expected gate object, got %s' % type(gate))

        self.gate = gate
        self.tag = tag
        self.name = 'Tagged(%s:%s)' % (gate.get_name(), tag)
        self.num_params = gate.get_num_params()
        self.size = gate.get_size()
        self.radixes = gate.get_radixes()

        # If input is a constant gate, we can cache the unitary.
        if self.num_params == 0:
            self.utry = gate.get_unitary()
Exemplo n.º 9
0
    def __init__(
        self, gate: Gate,
        location: CircuitLocationLike,
        params: Sequence[float] = [],
    ) -> None:
        """
        Operation Constructor.
s
        Args:
            gate (Gate): The cell's gate.

            location (CircuitLocationLike):  The set of qudits this gate
                affects.

            params (Sequence[float]): The parameters for the gate.

        Raises:
            ValueError: If `gate`'s size doesn't match `location`'s length.

            ValueError: If `gate`'s size doesn't match `params`'s length.
        """

        if not isinstance(gate, Gate):
            raise TypeError('Expected gate, got %s.' % type(gate))

        if not CircuitLocation.is_location(location):
            raise TypeError('Invalid location.')

        location = CircuitLocation(location)

        if len(location) != gate.get_size():
            raise ValueError('Gate and location size mismatch.')

        self.num_params = gate.get_num_params()
        self.radixes = gate.get_radixes()
        self.size = gate.get_size()

        if len(params) == 0 and self.get_num_params() != 0:
            params = [0.0] * self.get_num_params()

        self.check_parameters(params)

        self._gate = gate
        self._location = location
        self._params = list(params)
Exemplo n.º 10
0
    def test_get_qasm_gate_def(self, gate: Gate) -> None:
        try:
            qasm_gate_def = gate.get_qasm_gate_def()
        except AttributeError:
            return
        except BaseException:
            assert False, 'Unexpected error on gate.get_qasm_gate_def() call.'

        assert isinstance(qasm_gate_def, str)
Exemplo n.º 11
0
    def __init__(
        self,
        gate: Gate,
        num_controls: int = 1,
        radixes: Sequence[int] = [],
    ) -> None:
        """Construct a ControlledGate."""

        if not isinstance(gate, Gate):
            raise TypeError('Expected gate object, got %s.' % type(gate))

        if not is_integer(num_controls):
            raise TypeError(
                'Expected integer for num_controls, got %s.'
                % type(num_controls),
            )

        if num_controls < 1:
            raise ValueError(
                'Expected positive integer for num_controls, got %d.'
                % num_controls,
            )

        if len(radixes) != 0 and not is_valid_radixes(radixes, num_controls):
            raise TypeError('Invalid radixes.')

        self.gate = gate
        self.size = gate.get_size() + num_controls
        self.num_controls = num_controls
        self.radixes = tuple(radixes or [2] * self.size) + gate.get_radixes()
        self.name = '%d-Controlled(%s)' % (num_controls, gate.get_name())
        self.num_params = gate.get_num_params()

        self.Ic = np.identity(2 ** num_controls)  # TODO: General radix support
        self.It = np.identity(gate.get_dim())
        self.OneProj = np.zeros(self.Ic.shape)
        self.OneProj[-1, -1] = 1
        self.left = np.kron((self.Ic - self.OneProj), self.It)

        # If input is a constant gate, we can cache the unitary.
        if self.num_params == 0:
            U = self.gate.get_unitary()
            right = np.kron(self.OneProj, U)
            self.utry = UnitaryMatrix(self.left + right, self.get_radixes())
Exemplo n.º 12
0
 def test_is_parameterized_gate(self, param_gate: Gate) -> None:
     assert not param_gate.is_constant()
     assert param_gate.is_parameterized()
Exemplo n.º 13
0
 def test_valid_1(self, gate: Gate) -> None:
     circuit = Circuit(gate.get_size(), gate.get_radixes())
     location = list(range(gate.get_size()))
     params = [0] * gate.get_num_params()
     circuit.check_valid_operation(Operation(gate, location, params))
Exemplo n.º 14
0
 def test_get_unitary(self, gate: Gate) -> None:
     params = np.random.rand(gate.get_num_params())
     utry = gate.get_unitary(params)
     assert isinstance(utry, UnitaryMatrix)
Exemplo n.º 15
0
 def test_unitary_dim_match(self, gate: Gate) -> None:
     params = np.random.rand(gate.get_num_params())
     utry = gate.get_unitary(params)
     assert utry.get_shape() == (gate.get_dim(), gate.get_dim())
Exemplo n.º 16
0
 def test_with_frozen_params(self, gate: Gate) -> None:
     num_params = gate.get_num_params()
     frozen_params = {i: float(j) for i, j in enumerate(range(num_params))}
     frozen_gate = gate.with_frozen_params(frozen_params)
     assert isinstance(frozen_gate, FrozenParameterGate)
     assert frozen_gate.frozen_params == frozen_params
Exemplo n.º 17
0
 def test_check_parameters_valid(self, gate: Gate) -> None:
     gate.check_parameters(np.random.rand(gate.get_num_params()))
     gate.check_parameters([0] * gate.get_num_params())
Exemplo n.º 18
0
 def test_get_radixes_qutrit(self, qutrit_gate: Gate) -> None:
     assert all(radix == 3 for radix in qutrit_gate.get_radixes())
Exemplo n.º 19
0
 def test_is_constant_parameterized(self, gate: Gate) -> None:
     assert gate.is_constant() or gate.is_parameterized()
Exemplo n.º 20
0
 def test_get_num_params_parameterized(self, param_gate: Gate) -> None:
     assert param_gate.get_num_params() != 0
Exemplo n.º 21
0
 def test_get_radixes(self, gate: Gate) -> None:
     assert isinstance(gate.get_radixes(), tuple)
     assert all(isinstance(radix, int) for radix in gate.get_radixes())
     assert all(radix > 0 for radix in gate.get_radixes())
Exemplo n.º 22
0
 def test_get_num_params(self, gate: Gate) -> None:
     assert isinstance(gate.get_num_params(), int)
     assert gate.get_num_params() >= 0
Exemplo n.º 23
0
 def test_repr(self, gate: Gate) -> None:
     assert isinstance(gate.__repr__(), str)
Exemplo n.º 24
0
 def test_with_all_frozen_params(self, gate: Gate) -> None:
     frozen_gate = gate.with_all_frozen_params([0] * gate.get_num_params())
     assert isinstance(frozen_gate, FrozenParameterGate)
     frozen_params = {i: 0 for i in range(gate.get_num_params())}
     assert frozen_gate.frozen_params == frozen_params
Exemplo n.º 25
0
 def test_valid_2(self, gate: Gate) -> None:
     circuit = Circuit(gate.get_size() + 2, (2, 2) + gate.get_radixes())
     location = [x + 2 for x in list(range(gate.get_size()))]
     params = [0] * gate.get_num_params()
     circuit.check_valid_operation(Operation(gate, location, params))
Exemplo n.º 26
0
 def test_gate_size_matches_radixes(self, gate: Gate) -> None:
     assert len(gate.get_radixes()) == gate.get_size()
Exemplo n.º 27
0
Arquivo: vlg.py Projeto: BQSKit/bqskit
    def __init__(
        self,
        gate: Gate,
        locations: Sequence[CircuitLocationLike],
        radixes: Sequence[int],
    ) -> None:
        """
        Create a gate that has parameterized location.

        Args:
            gate (Gate): The gate to parameterize location for.

            locations (Sequence[CircuitLocationLike]): A sequence of locations.
                Each location represents a valid placement for gate.

            radixes (Sequence[int]): The number of orthogonal
                states for each qudit. Defaults to qubits.

        Raises:
            ValueError: If there are not enough locations or the locations
                are incorrectly sized.

        Notes:
            The locations are calculated in their own space and are not
            relative to a circuit. This means you should consider the
            VariableLocationGate as its own circuit when deciding the
            locations. For example, if you want to multiplex the (2, 3)
            and (3, 5) placements of a CNOT on a 6-qubit circuit, then
            you would give the VariableLocationGate the (0, 1) and (1, 2)
            locations and place the VariableLocationGate on qubits
            (2, 3, 5) on the circuit.
        """
        if not isinstance(gate, Gate):
            raise TypeError('Expected gate object, got %s' % type(gate))

        if not all(CircuitLocation.is_location(l) for l in locations):
            raise TypeError('Expected a sequence of valid locations.')

        locations = [CircuitLocation(l) for l in locations]

        if not all(len(l) == gate.get_size() for l in locations):
            raise ValueError('Invalid sized location.')

        if len(locations) < 1:
            raise ValueError('VLGs require at least 1 locations.')

        self.gate = gate
        self.name = 'VariableLocationGate(%s)' % gate.get_name()
        self.locations = list(locations)

        if radixes is None:
            # Calculate radixes
            radix_map: dict[int,
                            int | None] = {i: None
                                           for i in range(self.size)}
            for l in locations:
                for radix, qudit_index in zip(gate.get_radixes(), l):
                    if radix_map[qudit_index] is None:
                        radix_map[qudit_index] = radix
                    elif radix_map[qudit_index] != radix:
                        raise ValueError(
                            'Gate cannot be applied to all locations'
                            ' due to radix mismatch.', )

            self.radixes = tuple(radix_map.values())
        else:
            for l in locations:
                for radix, qudit_index in zip(gate.get_radixes(), l):
                    if radixes[qudit_index] != radix:
                        raise ValueError(
                            'Gate cannot be applied to all locations'
                            ' due to radix mismatch.', )

            self.radixes = tuple(radixes)

        self.size = len(self.radixes)
        self.num_params = self.gate.get_num_params() + len(locations)

        self.extension_size = self.size - self.gate.get_size()
        # TODO: This needs to changed for radixes
        self.I = np.identity(2**self.extension_size)
        self.perms = np.array([
            PermutationMatrix.from_qubit_location(self.size, l)
            for l in self.locations
        ])
Exemplo n.º 28
0
 def test_get_dim(self, gate: Gate) -> None:
     assert isinstance(gate.get_dim(), int)
     assert gate.get_dim() > 0
Exemplo n.º 29
0
 def test_get_num_params_constant(self, constant_gate: Gate) -> None:
     assert constant_gate.get_num_params() == 0
Exemplo n.º 30
0
 def test_check_parameters_invalid(self, gate: Gate) -> None:
     with pytest.raises(TypeError):
         gate.check_parameters('a')  # type: ignore
     with pytest.raises(TypeError):
         gate.check_parameters(1)  # type: ignore
     if gate.is_parameterized():
         with pytest.raises(TypeError):
             error_list = ['a'] * gate.get_num_params()
             gate.check_parameters(error_list)  # type: ignore
     with pytest.raises(ValueError):
         gate.check_parameters(np.random.rand(gate.get_num_params() + 1))