예제 #1
0
def circuit17(params, wires):
    """Circuit template #17 in 1905.10876

    Args:
        params (array): An array of shapes (2N + floor(N/2) + floor((N-1)/2), ). 
        wires (Iterable): Wires that the template acts on.
    """
    # Input Checks
    wires, size = Wires(wires), len(wires)

    check_shape(
        params,
        target_shape=(2 * size + floor(size / 2) + floor((size - 1) / 2), ),
        msg=
        f"params must be of shape {(2*size + floor(size/2) + floor((size-1)/2),)}."
    )

    # Define the circuit
    AngleEmbedding(params[:size], wires, rotation='X')
    AngleEmbedding(params[size:2 * size], wires, rotation='Z')

    pattern = [[i + 1, i] for i in range(0, len(wires) - 1, 2)]
    qml.broadcast(unitary=qml.CRX,
                  pattern=pattern,
                  wires=wires,
                  parameters=params[2 * size:2 * size + floor(size / 2)])

    pattern = [[i + 1, i] for i in range(1, len(wires) - 1, 2)]
    qml.broadcast(unitary=qml.CRX,
                  pattern=pattern,
                  wires=wires,
                  parameters=params[2 * size + floor(size / 2):])
예제 #2
0
def circuit12(params, wires):
    """Circuit template #12 in 1905.10876

    Args:
        params (array): An array of shapes (4N-4,). 
        wires (Iterable): Wires that the template acts on.
    """
    # Input Checks
    wires, size = Wires(wires), len(wires)

    check_shape(params,
                target_shape=(4 * size - 4, ),
                msg=f"params must be of shape {(4 * size - 4, )}.")

    # Define the circuit
    AngleEmbedding(params[:size], wires, rotation='Y')
    AngleEmbedding(params[size:2 * size], wires, rotation='Z')

    pattern = [[i + 1, i] for i in range(0, len(wires) - 1, 2)]
    qml.broadcast(unitary=qml.CZ, pattern=pattern, wires=wires)

    AngleEmbedding(params[2 * size:3 * size - 2],
                   wires=wires[1:-1],
                   rotation='Y')
    AngleEmbedding(params[3 * size - 2:4 * size - 4],
                   wires=wires[1:-1],
                   rotation='Z')

    pattern = [[i + 1, i] for i in range(1, len(wires) - 1, 2)]
    qml.broadcast(unitary=qml.CZ, pattern=pattern, wires=wires)
 def circuit(params):
     """Parametrized circuit."""
     for layer in range(n):
         qml.broadcast(qml.RX, pattern="single", wires=self.all_wires, parameters=params[layer])
     for _layer in range(n):
         qml.broadcast(qml.CNOT, pattern="double", wires=self.all_wires)
     return [bu.expval(qml.PauliZ(w)) for w in self.all_wires]
예제 #4
0
def circuit15(params, wires):
    """Circuit template #15 in 1905.10876

    Args:
        params (array): An array of shapes (2N, ). 
        wires (Iterable): Wires that the template acts on.
    """
    # Input Checks
    wires, size = Wires(wires), len(wires)

    check_shape(params,
                target_shape=(2 * size, ),
                msg=f"params must be of shape {(2*size,)}.")

    # Define the circuit
    AngleEmbedding(params[:size], wires, rotation='Y')

    pattern = [[i, (i + 1) % len(wires)] for i in reversed(range(len(wires)))]
    qml.broadcast(unitary=qml.CNOT, pattern=pattern, wires=wires)

    AngleEmbedding(params[size:], wires, rotation='Y')

    pattern = [[(i - 1) % len(wires), (i - 2) % len(wires)]
               for i in range(len(wires))]
    qml.broadcast(unitary=qml.CNOT, pattern=pattern, wires=wires)
예제 #5
0
    def mera(params, wires):
        # Reformat the parameters list into a list of lists.
        # Each two-qubit gate should receive a list of parameters.
        # Apply the two qubit gates into the pattern of a tree.

        num_gates = len(pattern)

        if fix_layers:
            gate_size = len(params) // (2 * depth - 1
                                        )  #determine 2qubit gate size
            parameters = []
            parameters.append(params[:gate_size])
            for layer in range(1, depth):
                gates_per_layer = 2**layer
                #isometry
                for i in range(gates_per_layer):
                    parameters.append(
                        params[gate_size * (2 * layer - 1):gate_size * 2 *
                               layer])
                #unitary
                for i in range(gates_per_layer - int(not periodic)):
                    parameters.append(params[gate_size * 2 * layer:gate_size *
                                             (2 * layer + 1)])
        else:
            parameters = params
            gate_size = len(params) // num_gates  # determine 2qubit gate size

        parameters = np.reshape(parameters, [num_gates, gate_size])
        qml.broadcast(unitary=two_qubit_gate, pattern=pattern, wires=wires, parameters=parameters,\
                kwargs=None)
예제 #6
0
    def ttn(params, wires):
        # Reformat the parameters list into a list of lists.
        # Each two-qubit gate should receive a list of parameters.
        parameters = []
        if fix_layers:
            num_params_per_layer = len(params) // depth
            for layer in range(depth):
                num_gates_in_layer = 2**layer
                params_gate = [
                    params[j]
                    for j in range(layer * num_params_per_layer, (layer + 1) *
                                   num_params_per_layer)
                ]
                parameters.extend([params_gate] * num_gates_in_layer)
        else:
            num_params_per_gate = len(params) // len(pattern)
            parameters = [[
                params[i * num_params_per_gate + j]
                for j in range(num_params_per_gate)
            ] for i in range(len(pattern))]

        # Apply the two qubit gates into the pattern of a tree.
        qml.broadcast(two_qubit_gate,
                      wires,
                      pattern,
                      parameters=parameters,
                      kwargs=None)
예제 #7
0
def circuit06(params, wires):
    """Circuit template #06 in 1905.10876

    Args:
        params (array): An array of shapes (N^2 + 3N, 1). 
        wires (Iterable): Wires that the template acts on.
    """
    # Input Checks
    wires, size = Wires(wires), len(wires)

    check_shape(params,
                target_shape=(size * (size + 3), ),
                msg=f"params must be of shape {(size * (size + 3), )}.")

    # Define the circuit
    AngleEmbedding(params[:size], wires, rotation='X')
    AngleEmbedding(params[size:2 * size], wires, rotation='Z')

    idx_start = 2 * size
    for cnt, controlled in enumerate(reversed(range(len(wires)))):
        pattern = [[controlled, j] for j in reversed(range(len(wires)))
                   if j != controlled]
        qml.broadcast(unitary=qml.CRX,
                      pattern=pattern,
                      wires=wires,
                      parameters=params[idx_start:idx_start + (size - 1)])
        idx_start += size - 1

    AngleEmbedding(params[idx_start:idx_start + size], wires, rotation='X')
    AngleEmbedding(params[idx_start + size:idx_start + 2 * size],
                   wires,
                   rotation='Z')
예제 #8
0
 def layer(self, features, weights):
     for k in range(self.n_qubits):
         upload = weights[k * 6:k * 6 +
                          3] + weights[k * 6 + 3:(k + 1) *
                                       6] * features[k * 3:(k + 1) * 3]
         qml.Rot(*upload, wires=self.wires[k])
     qml.broadcast(unitary=qml.CNOT, wires=self.wires, pattern='ring')
예제 #9
0
def random_embed(x, wires, n_layers=1):
    """random enbedding circuit

    Args:
      weights: trainable weights
      x: input, len(x) is <= len(wires)
      wires: list of wires on which the feature map acts
      n_layers: number of repetitions of the first layer (Default value = 1)

    Returns:

    """
    n_wires = len(wires)
    weights = pars_random(x, n_wires, n_layers)

    n_weights_needed = n_layers * n_wires

    if len(weights) != n_weights_needed:
        raise ValueError("Feat map needs {} weights, got {}.".format(
            n_weights_needed, len(weights)))

    gate_set = [qml.RX, qml.RY, qml.RZ]
    for l in range(n_layers):
        i = 0
        while i < len(x):
            gate = np.random.choice(gate_set)
            gate(x[i], wires=wires[i])
            i = i + 1
        for i in range(n_wires):
            gate = np.random.choice(gate_set)
            gate(weights[l * n_wires + i - n_wires], wires=wires[i])
        qml.broadcast(qml.CNOT, wires=range(n_wires), pattern="ring")
예제 #10
0
    def hea(params, wires):

        n_qubits = len(wires)
        n_rotations = len(params)

        if n_rotations > 1:
            n_layers = n_rotations // n_qubits
            #n_extra_rots = n_rotations - n_layers * n_qubits

            # Alternating layers of unitary rotations on every qubit followed by a
            # ring cascade of CNOTs.
            for layer_idx in range(n_layers):
                layer_params = params[layer_idx *
                                      n_qubits:layer_idx * n_qubits +
                                      n_qubits, :]
                qml.broadcast(qml.Rot,
                              wires,
                              pattern="single",
                              parameters=layer_params)
                qml.broadcast(qml.CNOT, wires, pattern="ring")

            # There may be "extra" parameter sets required for which it's not necessarily
            # to perform another full alternating cycle. Apply these to the qubits as needed.
            #extra_params = params[-n_extra_rots:, :]
            #extra_wires = wires[: n_qubits - 1 - n_extra_rots : -1]
            #qml.broadcast(qml.Rot, extra_wires, pattern="single", parameters=extra_params)
        else:
            # For 1-qubit case, just a single rotation to the qubit
            qml.Rot(*params[0], wires=wires[0])
예제 #11
0
    def layer(self, features, weights):
        for k in range(self.n_qubits):
            qml.RY(weights[k] * features[k], wires=self.wires[k])

        qml.broadcast(qml.CNOT, wires=self.wires, pattern='ring')

        for k in range(self.n_qubits):
            qml.RX(weights[self.n_qubits + k], wires=self.wires[k])
예제 #12
0
def initialize_fields(angles, wires):
    qml.broadcast(qml.RX,
                  wires=wires,
                  pattern='single',
                  parameters=np.array(angles)[:, 0])
    qml.broadcast(qml.RZ,
                  wires=wires,
                  pattern='single',
                  parameters=np.array(angles)[:, 1])
예제 #13
0
def evaluate_to_ancillary(params, wires):
    unitary_params = np.split(params, len(wires) - 1)
    pattern = [[i, wires[-1]] for i in wires[:-1]]
    if floq:
        for i, used_wires in enumerate(pattern):
            CRX(params[i], used_wires)
    else:
        qml.broadcast(unitary=qml.CRX,
                      pattern=pattern,
                      wires=wires,
                      parameters=unitary_params)
예제 #14
0
def layer(x, params, wires, i0=0, inc=1):
    """Building block of the embedding Ansatz"""
    i = i0
    for j, wire in enumerate(wires):
        qml.Hadamard(wires=[wire])
        qml.RZ(x[i % len(x)], wires=[wire])
        i += inc
        qml.RY(params[0, j], wires=[wire])

    qml.broadcast(unitary=qml.CRZ,
                  pattern="ring",
                  wires=wires,
                  parameters=params[1])
def unitary_layer(all_wires, params, k=2):
    """
    Layers of unitaries
    The first and last qubits are ancilla qubits
    Input:
        all_wires: list of wires to be used
        params: parameters for unitaries
        k: every kth qubit, we apply an aribtrary unitary gate to k+1 qubit
    """
    qml.broadcast(ArbitraryUnitary,
                  wires=all_wires,
                  pattern="double",
                  parameters=params)
예제 #16
0
def circuit(params):
    qml.RX(params[0], wires=0)
    qml.RY(params[1], wires=1)
    qml.RZ(params[2], wires=2)

    qml.broadcast(qml.CNOT, wires=[0, 1, 2], pattern="ring")

    qml.RX(params[3], wires=0)
    qml.RY(params[4], wires=1)
    qml.RZ(params[5], wires=2)

    qml.broadcast(qml.CNOT, wires=[0, 1, 2], pattern="ring")
    return qml.expval(qml.PauliY(0) @ qml.PauliZ(2))
예제 #17
0
    def layer(self, features, weights):
        upload = features
        if self.angle_scaling:
            upload = weights[0:self.n_scaling_weights] * upload

        qml.broadcast(unitary=qml.RX,
                      wires=self.feature_wires,
                      pattern='single',
                      parameters=upload)
        qml.broadcast(unitary=qml.Hadamard,
                      wires=self.latent_wires,
                      pattern='single')

        if self.n_total_qubits >= 2:
            qml.broadcast(
                unitary=qml.MultiRZ,
                wires=self.wires,
                pattern='ring',
                parameters=weights[self.
                                   n_scaling_weights:self.n_scaling_weights +
                                   self.n_entangling_weights])

        qml.broadcast(unitary=qml.RY,
                      wires=self.wires,
                      pattern='single',
                      parameters=weights[self.n_scaling_weights +
                                         self.n_entangling_weights:])
예제 #18
0
def quantum_circuit(rotation_params, coupling_params, sample=None):

    # Prepares the initial basis state corresponding to the sample
    qml.templates.BasisStatePreparation(sample, wires=range(nr_qubits))

    # Prepares the variational ansatz for the circuit
    for i in range(0, depth):
        single_rotation(rotation_params[i], range(nr_qubits))
        qml.broadcast(unitary=qml.CRX,
                      pattern="ring",
                      wires=range(nr_qubits),
                      parameters=coupling_params[i])

    # Calculates the expectation value of the Hamiltonian with respect to the prepared states
    return qml.expval(qml.Hermitian(ham_matrix, wires=range(nr_qubits)))
 def circuit(params1, params2):
     """Parametrized circuit with nearest-neighbour gates."""
     for layer in range(n):
         qml.broadcast(
             qml.RX,
             pattern="single",
             wires=self.all_wires,
             parameters=params1[layer],
         )
         qml.broadcast(
             qml.CRY,
             pattern="chain",
             wires=self.all_wires,
             parameters=params2[layer],
         )
     return bu.expval(qml.PauliZ(0))
예제 #20
0
def variational_circuit(params):
    """A layered variational circuit. The first layer comprises of x, y, and z rotations on wires
    0, 1, and 2, respectively. The second layer is a ring of CNOT gates. The final layer comprises 
    of x, y, and z rotations on wires 0, 1, and 2, respectively.
    """

    # DO NOT MODIFY anything in this code block
    qml.RX(params[0], wires=0)
    qml.RY(params[1], wires=1)
    qml.RZ(params[2], wires=2)

    qml.broadcast(qml.CNOT, wires=[0, 1, 2], pattern="ring")

    qml.RX(params[3], wires=0)
    qml.RY(params[4], wires=1)
    qml.RZ(params[5], wires=2)

    qml.broadcast(qml.CNOT, wires=[0, 1, 2], pattern="ring")
예제 #21
0
def circuit04(params, wires):
    """Circuit template #04 in 1905.10876

    Args:
        params (array): An array of shapes (3N-1, 1). 
        wires (Iterable): Wires that the template acts on.
    """
    # Input Checks
    wires, size = Wires(wires), len(wires)

    check_shape(params, target_shape=(3 * size - 1,),
                msg=f"params must be of shape {(3 * size - 1,)}.")

    # Define the circuit    
    AngleEmbedding(params[:size], wires, rotation='X')
    AngleEmbedding(params[size:2 * size], wires, rotation='Z')

    pattern = [[i + 1, i] for i in reversed(range(len(wires) - 1))]
    qml.broadcast(unitary=qml.CRX, pattern=pattern, wires=wires, parameters=params[2 * size:])
예제 #22
0
    def variational_ansatz(params, wires, *, state_n):
        """
        Args:
            params (np.ndarray): An array of floating-point numbers with size (n, 3),
                where n is the number of parameter sets required (this is determined by
                the problem Hamiltonian).
            wires (qml.Wires): The device wires this circuit will run on.
        """
        n_qubits = len(wires)
        n_rotations = len(params)

        state = np.repeat([0], n_qubits)
        state[0:state_n] = 1
        qml.BasisState(state, wires=wires)

        if n_rotations > 1:
            n_layers = n_rotations // n_qubits
            n_extra_rots = n_rotations - n_layers * n_qubits

            # Alternating layers of unitary rotations on every qubit followed by a
            # ring cascade of CNOTs.
            for layer_idx in range(n_layers):
                layer_params = params[layer_idx *
                                      n_qubits: layer_idx * n_qubits + n_qubits, :]
                qml.broadcast(qml.RY, wires, pattern="single",
                              parameters=layer_params[:, 0])
                qml.broadcast(qml.RZ, wires, pattern="single",
                              parameters=layer_params[:, 1])
                qml.broadcast(qml.CNOT, wires, pattern="ring")

            if n_extra_rots > 0:
                # There may be "extra" parameter sets required for which it's not necessarily
                # to perform another full alternating cycle. Apply these to the qubits as needed.
                extra_params = params[-n_extra_rots:, :]
                extra_wires = wires[: n_qubits - 1 - n_extra_rots: -1]
                qml.broadcast(qml.RY, extra_wires, pattern="single",
                              parameters=extra_params[:, 0])
                qml.broadcast(qml.RZ, extra_wires, pattern="single",
                              parameters=extra_params[:, 1])
        else:
            # For 1-qubit case, just a single rotation to the qubit
            qml.Rot(*params[0], wires=wires[0])
예제 #23
0
def random_embed(weights, x, wires, n_layers=1):
    """ random enbedding circuit
  :param weights: trainable weights
  :param x: input, len(x) is <= len(wires)
  :param wires: list of wires on which the feature map acts
  :param n_layers: number of repetitions of the first layer
  """
    n_wires = len(wires)
    n_weights_needed = n_layers * n_wires
    gate_set = [qml.RX, qml.RY, qml.RZ]
    for l in range(n_layers):
        i = 0
        while i < len(x):
            gate = np.random.choice(gate_set)
            gate(x[i], wires=wires[i])
            i = i + 1
        for i in range(n_wires):
            gate = np.random.choice(gate_set)
            gate(weights[l * n_wires + i - n_wires], wires=wires[i])
        qml.broadcast(qml.CNOT, wires=range(n_wires), pattern="ring")
예제 #24
0
def circuit09(params, wires):
    """Circuit template #09 in 1905.10876

    Args:
        params (array): An array of shapes (N,). 
        wires (Iterable): Wires that the template acts on.
    """
    # Input Checks
    wires, size = Wires(wires), len(wires)

    check_shape(params, target_shape=(size,),
                msg=f"params must be of shape {(size,)}.")

    # Define the circuit    
    qml.broadcast(unitary=qml.Hadamard, pattern="single", wires=wires)

    pattern = [[i + 1, i] for i in reversed(range(len(wires) - 1))]
    qml.broadcast(unitary=qml.CZ, pattern=pattern, wires=wires)

    AngleEmbedding(params, wires, rotation='X')
def classifier(params, wires):
    # qml.RZ(params, wires=wires[0])
    # qml.RY(params, wires=wires[0])
    n_qubits = len(wires)
    n_rotations = len(params)
    n_layers = n_rotations // n_qubits

    if n_rotations % n_qubits != 0:
        raise Exception("Last layer is incomplete, not all qubits are rotated")

    # Alternating layers of unitary rotations on every qubit followed by a
    # ring cascade of CNOTs.
    for layer_idx in range(n_layers):
        layer_params = params[layer_idx * n_qubits:layer_idx * n_qubits +
                              n_qubits, :]
        qml.broadcast(qml.Rot,
                      wires,
                      pattern="single",
                      parameters=layer_params)
        if n_qubits > 1:
            qml.broadcast(qml.CNOT, wires, pattern="ring")
예제 #26
0
    def variational_ansatz2(params, wires):
        rot = params[0]
        params = params[1:]

        n_qubits = len(wires)
        n_rotations = len(params)

        qml.PauliX(wires=0)
        qml.PauliX(wires=1)
        qml.RY(rot[2], wires=2)

        if n_rotations > 1:
            n_layers = n_rotations // n_qubits
            n_extra_rots = n_rotations - n_layers * n_qubits
            for layer_idx in range(n_layers):
                layer_params = params[layer_idx *
                                      n_qubits:layer_idx * n_qubits +
                                      n_qubits, :]
                qml.broadcast(qml.Rot,
                              wires,
                              pattern="single",
                              parameters=layer_params)
                qml.broadcast(qml.CNOT, wires, pattern="ring")
            extra_params = params[-n_extra_rots:, :]
            extra_wires = wires[:n_qubits - 1 - n_extra_rots:-1]
            qml.broadcast(qml.Rot,
                          extra_wires,
                          pattern="single",
                          parameters=extra_params)
        else:
            qml.Rot(*params[0], wires=wires[0])
def variational_ansatz(params, wires):
    """

    This is a custom ansatz. It applies alternating layers of rotations and CNOTs.

    Args:
        params (np.ndarray): An array of floating-point numbers with size (n, 3),
            where n is the number of parameter sets required (this is determined by
            the problem Hamiltonian).
        wires (qml.Wires): The device wires this circuit will run on.
    """
    n_qubits = len(wires)
    n_rotations = len(params)

    if n_rotations > 1:
        n_layers = n_rotations // n_qubits
        n_extra_rots = n_rotations - n_layers * n_qubits

        # Alternating layers of unitary rotations on every qubit followed by a
        # ring cascade of CNOTs.
        for layer_idx in range(n_layers):
            layer_params = params[layer_idx * n_qubits : layer_idx * n_qubits + n_qubits, :]
            qml.broadcast(qml.Rot, wires, pattern="single", parameters=layer_params)
            qml.broadcast(qml.CNOT, wires, pattern="ring")

        extra_params = params[-n_extra_rots:, :]
        extra_wires = wires[: n_qubits - 1 - n_extra_rots : -1]
        qml.broadcast(qml.Rot, extra_wires, pattern="single", parameters=extra_params)
    else:
        # For 1-qubit case, just a single rotation to the qubit
        qml.Rot(*params[0], wires=wires[0])
예제 #28
0
def variational_ansatz(params, wires):
    """
    DO NOT MODIFY anything in this function! It is used to judge your solution.
    This is ansatz is used to help with the problem structure. It applies
    alternating layers of rotations and CNOTs.
    Don't worry about the contents of this function for now—you'll be designing
    your own ansatze in a later problem.
    Args:
        params (np.ndarray): An array of floating-point numbers with size (n, 3),
            where n is the number of parameter sets required (this is determined by
            the problem Hamiltonian).
        wires (qml.Wires): The device wires this circuit will run on.
    """
    n_qubits = len(wires)
    n_rotations = len(params)

    if n_rotations > 1:
        n_layers = n_rotations // n_qubits
        n_extra_rots = n_rotations - n_layers * n_qubits

        # Alternating layers of unitary rotations on every qubit followed by a
        # ring cascade of CNOTs.
        for layer_idx in range(n_layers):
            layer_params = params[layer_idx * n_qubits : layer_idx * n_qubits + n_qubits, :]
            qml.broadcast(qml.Rot, wires, pattern="single", parameters=layer_params)
            qml.broadcast(qml.CNOT, wires, pattern="ring")

        # There may be "extra" parameter sets required for which it's not necessarily
        # to perform another full alternating cycle. Apply these to the qubits as needed.
        extra_params = params[-n_extra_rots:, :]
        extra_wires = wires[: n_qubits - 1 - n_extra_rots : -1]
        qml.broadcast(qml.Rot, extra_wires, pattern="single", parameters=extra_params)
    else:
        # For 1-qubit case, just a single rotation to the qubit
        qml.Rot(*params[0], wires=wires[0])
예제 #29
0
def generator(w):
    qml.broadcast(unitary=qml.RY,
                  pattern='single',
                  wires=wires,
                  parameters=w[0:32])
    for k in range(1, 4):
        qml.broadcast(unitary=qml.RY,
                      pattern='single',
                      wires=wires,
                      parameters=w[(32 * k):(32 * (k + 1))])
        qml.broadcast(unitary=qml.CZ, pattern='ring', wires=wires)
    def get_state(params, wires=w2):
        n_qubits = len(wires)
        n_rotations = len(params)

        if n_rotations > 1:
            n_layers = n_rotations // n_qubits
            n_extra_rots = n_rotations - n_layers * n_qubits

            for layer_idx in range(n_layers):
                layer_params = params[layer_idx * n_qubits : layer_idx * n_qubits + n_qubits, :]
                qml.broadcast(qml.Rot, wires, pattern="single", parameters=layer_params)
                qml.broadcast(qml.CNOT, wires, pattern="ring")

            extra_params = params[-n_extra_rots:, :]
            extra_wires = wires[: n_qubits - 1 - n_extra_rots : -1]
            qml.broadcast(qml.Rot, extra_wires, pattern="single", parameters=extra_params)
        else:
            qml.Rot(*params[0], wires=wires[0])
        return qml.state()