mindquantum.algorithm.library.amplitude_encoder 源代码

# Copyright 2021 Huawei Technologies Co., Ltd
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ============================================================================

"""Amplitude encoder for quantum machine learning."""

import math

import numpy as np

from mindquantum.core.circuit import Circuit
from mindquantum.core.gates import RY, X
from mindquantum.core.parameterresolver import ParameterResolver
from mindquantum.utils.type_value_check import _check_input_type


def controlled_gate(circuit, gate, t_qubit, c_qubits, zero_qubit):
    """Add an extended quantum controlled gate."""
    tmp = []
    for i, control in enumerate(c_qubits):
        tmp.append(control)
        if control < 0 or (control == 0 and zero_qubit == 0):
            circuit += X.on(abs(control))
            tmp[i] = -tmp[i]

    circuit += gate.on(t_qubit, tmp)

    for control in c_qubits:
        if control < 0 or (control == 0 and zero_qubit == 0):
            circuit += X.on(abs(control))


[文档]def amplitude_encoder(x, n_qubits): """ Quantum circuit for amplitude encoding. Note: The length of classic data ought to be the power of 2, otherwise will be filled up with 0. The vector should be normalized. Args: x (list[float] or numpy.array(list[float])): the vector of data you want to encode, which should be normalized. n_qubits (int): the number of qubits of the encoder circuit. Returns: Circuit, the parameterized quantum circuit that do amplitude encoder. ParameterResolver, the parameter for parameterized quantum circuit to do amplitude encoder. Examples: >>> from mindquantum.algorithm.library import amplitude_encoder >>> from mindquantum.simulator import Simulator >>> sim = Simulator('mqvector', 8) >>> encoder, parameterResolver = amplitude_encoder([0.5, -0.5, 0.5, 0.5], 8) >>> sim.apply_circuit(encoder, parameterResolver) >>> print(sim.get_qs(True)) 1/2¦00000000⟩ -1/2¦00000001⟩ 1/2¦00000010⟩ 1/2¦00000011⟩ >>> sim.reset() >>> encoder, parameterResolver = amplitude_encoder([0, 0, 0.5, 0.5, -0.5, 0.5], 8) >>> sim.apply_circuit(encoder, parameterResolver) >>> print(sim.get_qs(True)) 1/2¦00000010⟩ 1/2¦00000011⟩ -1/2¦00000100⟩ 1/2¦00000101⟩ """ _check_input_type('amplitude_encoder', (np.ndarray, list), x) _check_input_type('n_qubits', (int), n_qubits) if isinstance(x, np.ndarray): x = x.tolist() if len(x) > 2**n_qubits: x = x[: (2**n_qubits)] while 2**n_qubits != len(x): x.append(0) circuit = Circuit() tree = [] for i in range(len(x) - 1): tree.append(0) for x_val in x: tree.append(x_val) for i in range(len(x) - 2, -1, -1): tree[i] += math.sqrt(tree[i * 2 + 1] * tree[i * 2 + 1] + tree[i * 2 + 2] * tree[i * 2 + 2]) path = [[]] num = {} cnt = 0 for i in range(1, 2 * len(x) - 1, 2): path.append(path[(i - 1) // 2] + [-1]) path.append(path[(i - 1) // 2] + [1]) tmp = path[(i - 1) // 2] controls = [] for j, tmp_j in enumerate(tmp): controls.append(tmp_j * j) theta = 0 if tree[(i - 1) // 2] > 1e-10: amp_0 = tree[i] / tree[(i - 1) // 2] theta = 2 * math.acos(amp_0) if tree[i + 1] < 0 < math.sin(theta / 2): theta = -theta num[f'alpha{cnt}'] = theta controlled_gate(circuit, RY(f'alpha{cnt}'), len(tmp), controls, (0 if tmp and tmp[0] == -1 else 1)) cnt += 1 return circuit.reverse_qubits(), ParameterResolver(num)