Je crée Blueqat, une bibliothèque de calcul quantique, et je prévois de lire le code source de Qiskit, une bibliothèque de calcul quantique. J'ai lu la partie qui m'inquiétait habituellement mais que je ne savais pas lire.
Comme le titre l'indique, cette fois, nous lirons le processus de création d'un circuit et d'ajouter des portes et des mesures au circuit. Donc, cette fois, je ne lirai que la partie très frontale, qui ne montre rien de tel que la méthode de calcul quantique.
Qiskit est une bibliothèque informatique quantique open source développée par IBM.
Qiskit est divisé en paquets comme indiqué ci-dessous, mais lors de l'installation, il est moins gênant de les installer avec pip install qiskit
que de les faire séparément.
paquet | rôle |
---|---|
Qiskit Terra | Ceci est le package principal. Il comprend une classe pour créer un circuit, une fonction pour transpiler le circuit pour la machine réelle, une fonction pour atteindre l'API et la lancer sur la machine réelle, etc. |
Qiskit Aer | Comprend un simulateur de circuit quantique, généralement appelé depuis Qiskit Terra |
Qiskit Ignis | Ceci est une bibliothèque pour ceux qui veulent lutter contre le bruit lors de l'exécution d'un circuit quantique sur une machine réelle. Je n'ai jamais utilisé |
Qiskit Aqua | Une bibliothèque qui facilite l'utilisation des algorithmes quantiques |
Cette fois, je lis une partie de Qiskit Terra.
https://github.com/Qiskit/qiskit-terra
Plus précisément, le code écrit en README.md
from qiskit import *
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0,1], [0,1])
backend_sim = BasicAer.get_backend('qasm_simulator')
result = execute(qc, backend_sim).result()
print(result.get_counts(qc))
Parmi ceux-ci, lisez le flux jusqu'à qc.measure ([0,1], [0,1])
.
Continuez à lire la branche principale sur GitHub. L'ID de validation pour le moment est e7be587, mais il est mis à jour assez souvent et peut changer à la fin de l'article. Notez s'il vous plaît.
Jetez un coup d'œil à qiskit / circuit / quantumcircuit.py.
Saviez-vous tous qu'il n'y a rien qui devrait être là? Notez le code ci-dessus.
qc = QuantumCircuit(2, 2)
qc.h(0)
qc.cx(0, 1)
qc.measure([0,1], [0,1])
Je devrais avoir QuantumCircuit.h
, QuantumCircuit.cx
, QuantumCircuit.measure
, mais je ne le trouve nulle part.
Puisqu'il y a tellement de ces portes quantiques, je comprends vraiment le désir de les définir séparément. Alors, où est-il défini?
À ʻimport,
qiskit.extensions. * ʻEst chargé et la porte y est ajoutée.
Les principales portes sont situées dans qiskit / extensions / standard.
La mesure sera également ajoutée au Circuit Quantum
sur qiskit / circuit / measure.py.
(Je voulais que vous mettiez ces choses ensemble en un seul endroit)
Maintenant que nous avons résolu le mystère des portes et des méthodes de mesure, revenons au sujet principal.
qc = QuantumCircuit(2, 2)
Je lirai.
Lisez QuantumCircuit .__ init__
sur qiskit / circuit / quantumcircuit.py.
def __init__(self, *regs, name=None):
if name is None:
name = self.cls_prefix() + str(self.cls_instances())
# pylint: disable=not-callable
# (known pylint bug: https://github.com/PyCQA/pylint/issues/1699)
if sys.platform != "win32" and isinstance(mp.current_process(), mp.context.ForkProcess):
name += '-{}'.format(mp.current_process().pid)
self._increment_instances()
if not isinstance(name, str):
raise CircuitError("The circuit name should be a string "
"(or None to auto-generate a name).")
self.name = name
# Data contains a list of instructions and their contexts,
# in the order they were applied.
self._data = []
# This is a map of registers bound to this circuit, by name.
self.qregs = []
self.cregs = []
self.add_register(*regs)
# Parameter table tracks instructions with variable parameters.
self._parameter_table = ParameterTable()
self._layout = None
Hmm, vous avez besoin d'un nom pour le circuit. Si vous ne le spécifiez pas, il sera joint sans autorisation.
Aussi, c'est terrible, mais j'étais inquiet en tant que personne épuisée chaque jour par la programmation.
raise CircuitError("The circuit name should be a string "
"(or None to auto-generate a name).")
S'il y a beaucoup de caractères dans une ligne, je me fâche contre pylint, mais je le divise probablement en deux lignes pour l'éviter. Je pense toujours: "Cela ne me dérange pas si je me fâche. Est-il possible d'améliorer la lisibilité en divisant ce qui est initialement affiché sur une ligne en deux lignes? Est-il censé rechercher des messages avec grep?" .. C'est pour les adultes.
Le reste est l'initialisation du contenu. Lisons également ʻadd_register`.
def add_register(self, *regs):
"""Add registers."""
if not regs:
return
if any([isinstance(reg, int) for reg in regs]):
# QuantumCircuit defined without registers
if len(regs) == 1 and isinstance(regs[0], int):
# QuantumCircuit with anonymous quantum wires e.g. QuantumCircuit(2)
regs = (QuantumRegister(regs[0], 'q'),)
elif len(regs) == 2 and all([isinstance(reg, int) for reg in regs]):
# QuantumCircuit with anonymous wires e.g. QuantumCircuit(2, 3)
regs = (QuantumRegister(regs[0], 'q'), ClassicalRegister(regs[1], 'c'))
else:
raise CircuitError("QuantumCircuit parameters can be Registers or Integers."
" If Integers, up to 2 arguments. QuantumCircuit was called"
" with %s." % (regs,))
for register in regs:
if register.name in [reg.name for reg in self.qregs + self.cregs]:
raise CircuitError("register name \"%s\" already exists"
% register.name)
if isinstance(register, QuantumRegister):
self.qregs.append(register)
elif isinstance(register, ClassicalRegister):
self.cregs.append(register)
else:
raise CircuitError("expected a register")
À l'origine, Qiskit devait créer un «registre quantique» et un «registre classique», mais avec la mise à niveau de Qiskit, il est devenu préférable d'utiliser uniquement des nombres. ~~ Est-ce le pakuri de Blueqat? ~~ Un exemple est montré dans lequel le code qui apparaît en premier dans README.md de Qiskit-Terra est également fait numériquement sans créer de registre. ~~ Est-ce le pakuri de Blueqat? ~~ Cependant, la structure interne semble supposer qu'il existe un registre, et s'il n'est pas spécifié, un registre quantique nommé «q» et un registre classique nommé «c» seront créés.
En ce qui concerne la pièce jointe après cela. Comme vous pouvez le voir dans les commentaires, c'est une sensation très subtile.
Pas avec un trait de soulignement comme _add_register
, mais avec ʻadd_register` et pas de trait de soulignement, cela devrait être une fonction qui est censée être appelée non seulement en interne mais aussi en externe.
Cependant, en regardant les commentaires et les messages d'exception dans la partie qui transmet les nombres au lieu des registres, il semble qu'il est peu probable qu'il soit appelé de l'extérieur. J'ai pensé qu'il aurait été préférable de faire la partie "Créer des registres'q'et'c 's'il s'agit d'un entier" dans __init__
.
...... Eh bien, le problème réel avec l'implémentation actuelle est que cela ne me dérange pas vraiment, donc c'est très bien.
from qiskit import *
q = QuantumRegister(3, 'q')
c = QuantumRegister(3, 'c')
qc = QuantumCircuit(4, 4)
qc.add_register(q)
# => QiskitError: 'register name "q" already exists'
qc.add_register(c)
# => QiskitError: 'register name "c" already exists'
qc = QuantumCircuit(q)
qc.add_register(4)
# => QiskitError: 'register name "q" already exists'
Uhehehehe.
Ensuite, regardons-les.
qc.h(0)
qc.cx(0, 1)
qc.measure([0,1], [0,1])
[Qiskit / extensions / standard / h.py] avec QuantumCircuit.h
implémenté (https://github.com/Qiskit/qiskit-terra/blob/master/qiskit/extensions/standard/h.py) Quand tu regardes
def h(self, q): # pylint: disable=invalid-name
"""Apply H to q."""
return self.append(HGate(), [q], [])
QuantumCircuit.h = h
C'est déroutant, mais ici «soi» devient «circuit quantique».
Jetons un coup d'œil à QuantumCircuit.append
.
QuantumCircuit.append
def append(self, instruction, qargs=None, cargs=None):
"""Append one or more instructions to the end of the circuit, modifying
the circuit in place. Expands qargs and cargs.
Args:
instruction (Instruction or Operation): Instruction instance to append
qargs (list(argument)): qubits to attach instruction to
cargs (list(argument)): clbits to attach instruction to
Returns:
Instruction: a handle to the instruction that was just added
"""
# Convert input to instruction
if not isinstance(instruction, Instruction) and hasattr(instruction, 'to_instruction'):
instruction = instruction.to_instruction()
expanded_qargs = [self.qbit_argument_conversion(qarg) for qarg in qargs or []]
expanded_cargs = [self.cbit_argument_conversion(carg) for carg in cargs or []]
instructions = InstructionSet()
for (qarg, carg) in instruction.broadcast_arguments(expanded_qargs, expanded_cargs):
instructions.add(self._append(instruction, qarg, carg), qarg, carg)
return instructions
to_instruction ()
?Commençons depuis le début.
if not isinstance(instruction, Instruction) and hasattr(instruction, 'to_instruction'):
instruction = instruction.to_instruction()
Les portes et les mesures sont des «instructions», donc elles sont passées.
(Plus précisément, classe HGate
est [classe Gate
] Il hérite de (https://github.com/Qiskit/qiskit-terra/blob/master/qiskit/circuit/gate.py#L24) et la classe Gate
est la [classe ʻInstruction](https: / Puisqu'il hérite de /github.com/Qiskit/qiskit-terra/blob/master/qiskit/circuit/instruction.py#L51),
HGate est ʻInstruction
. Les autres portes et mesures sont également des classes parentes. Si vous suivez, vous atteindrez ʻInstruction`)
Sinon, il semble que si vous avez une méthode to_instruction
, elle sera appelée.
Il semble que l'idée soit de vous permettre d'ajouter une sorte de "porte étendue".
Quand j'ai cherché la méthode to_instruction
avec grep, j'ai trouvé quelque chose lié aux impulsions pour le contrôle matériel, et quelque chose pour faire des non-portes telles que les matrices de Pauli et les représentations Claus en circuits.
Au fait, suis-je le seul à avoir pensé: "Si vous n'avez pas de méthode to_instruction
au lieu de ʻInstruction`, je veux que vous lanciez une exception ici." (Il semble y avoir une histoire que vous n'avez pas à la lancer ici car elle sortira plus tard)
Allons-y ensuite.
expanded_qargs = [self.qbit_argument_conversion(qarg) for qarg in qargs or []]
expanded_cargs = [self.cbit_argument_conversion(carg) for carg in cargs or []]
Regardez ces contenus. (Supprimer docstring et quote)
def qbit_argument_conversion(self, qubit_representation):
return QuantumCircuit._bit_argument_conversion(qubit_representation, self.qubits)
def cbit_argument_conversion(self, clbit_representation):
return QuantumCircuit._bit_argument_conversion(clbit_representation, self.clbits)
Les deux appellent simplement «_bit_argument_conversion», mais avant cela, que sont «self.qubits» et «self.clbits»? Je regarderai.
@property
def qubits(self):
"""
Returns a list of quantum bits in the order that the registers were added.
"""
return [qbit for qreg in self.qregs for qbit in qreg]
@property
def clbits(self):
"""
Returns a list of classical bits in the order that the registers were added.
"""
return [cbit for creg in self.cregs for cbit in creg]
Tout le contenu du registre est organisé dans une seule liste.
Par exemple, si vous avez deux registres, [QuantumRegister (3, 'q1'), QuantumRegister (2, 'q2')]
, alors` [q1 [0], q1 [1], q1 [2], q2 [0] ], q2 [1]] ʻest retourné.
Ensuite, lisez _bit_argument_conversion
.
@staticmethod
def _bit_argument_conversion(bit_representation, in_array):
ret = None
try:
if isinstance(bit_representation, Bit):
# circuit.h(qr[0]) -> circuit.h([qr[0]])
ret = [bit_representation]
elif isinstance(bit_representation, Register):
# circuit.h(qr) -> circuit.h([qr[0], qr[1]])
ret = bit_representation[:]
elif isinstance(QuantumCircuit.cast(bit_representation, int), int):
# circuit.h(0) -> circuit.h([qr[0]])
ret = [in_array[bit_representation]]
elif isinstance(bit_representation, slice):
# circuit.h(slice(0,2)) -> circuit.h([qr[0], qr[1]])
ret = in_array[bit_representation]
elif _is_bit(bit_representation):
# circuit.h((qr, 0)) -> circuit.h([qr[0]])
ret = [bit_representation[0][bit_representation[1]]]
elif isinstance(bit_representation, list) and \
all(_is_bit(bit) for bit in bit_representation):
ret = [bit[0][bit[1]] for bit in bit_representation]
elif isinstance(bit_representation, list) and \
all(isinstance(bit, Bit) for bit in bit_representation):
# circuit.h([qr[0], qr[1]]) -> circuit.h([qr[0], qr[1]])
ret = bit_representation
elif isinstance(QuantumCircuit.cast(bit_representation, list), (range, list)):
# circuit.h([0, 1]) -> circuit.h([qr[0], qr[1]])
# circuit.h(range(0,2)) -> circuit.h([qr[0], qr[1]])
# circuit.h([qr[0],1]) -> circuit.h([qr[0], qr[1]])
ret = [index if isinstance(index, Bit) else in_array[
index] for index in bit_representation]
else:
raise CircuitError('Not able to expand a %s (%s)' % (bit_representation,
type(bit_representation)))
except IndexError:
raise CircuitError('Index out of range.')
except TypeError:
raise CircuitError('Type error handling %s (%s)' % (bit_representation,
type(bit_representation)))
return ret
C'est long, mais ce que vous faites est comme indiqué dans les commentaires. Il prend en charge diverses méthodes d'appel, donc ce n'est pas grave si vous le comprenez dans une certaine mesure.
La fin de QuantumCircuit.append
touche à sa fin.
instructions = InstructionSet()
for (qarg, carg) in instruction.broadcast_arguments(expanded_qargs, expanded_cargs):
instructions.add(self._append(instruction, qarg, carg), qarg, carg)
return instructions
Maintenant. Lisez ʻInstructionSet .__ init__` dans qiskit / circuit / instructionset.py.
class InstructionSet:
"""Instruction collection, and their contexts."""
def __init__(self):
"""New collection of instructions.
The context (qargs and cargs that each instruction is attached to),
is also stored separately for each instruction.
"""
self.instructions = []
self.qargs = []
self.cargs = []
J'ai l'impression que vous ne faites pas grand-chose. Si vous regardez également ʻInstructionSet.add`
def add(self, gate, qargs, cargs):
"""Add an instruction and its context (where it's attached)."""
if not isinstance(gate, Instruction):
raise CircuitError("attempt to add non-Instruction" +
" to InstructionSet")
self.instructions.append(gate)
self.qargs.append(qargs)
self.cargs.append(cargs)
C'est à peu près comme prévu.
Un peu à gauche!
for (qarg, carg) in instruction.broadcast_arguments(expanded_qargs, expanded_cargs):
instructions.add(self._append(instruction, qarg, carg), qarg, carg)
return instructions
Continuez à lire broadcast_arguments
.
Ceci est implémenté dans qiskit / circuit / instruction.py, mais qiskit / circuit / Puisqu'il est remplacé par gate.py, il s'appellera cette fois Gate.broadcast_arguments
. Je vais.
def broadcast_arguments(self, qargs, cargs):
"""Validation and handling of the arguments and its relationship.
For example:
`cx([q[0],q[1]], q[2])` means `cx(q[0], q[2]); cx(q[1], q[2])`. This method
yields the arguments in the right grouping. In the given example::
in: [[q[0],q[1]], q[2]],[]
outs: [q[0], q[2]], []
[q[1], q[2]], []
The general broadcasting rules are:
* If len(qargs) == 1::
[q[0], q[1]] -> [q[0]],[q[1]]
* If len(qargs) == 2::
[[q[0], q[1]], [r[0], r[1]]] -> [q[0], r[0]], [q[1], r[1]]
[[q[0]], [r[0], r[1]]] -> [q[0], r[0]], [q[0], r[1]]
[[q[0], q[1]], [r[0]]] -> [q[0], r[0]], [q[1], r[0]]
* If len(qargs) >= 3::
[q[0], q[1]], [r[0], r[1]], ...] -> [q[0], r[0], ...], [q[1], r[1], ...]
Args:
qargs (List): List of quantum bit arguments.
cargs (List): List of classical bit arguments.
Returns:
Tuple(List, List): A tuple with single arguments.
Raises:
CircuitError: If the input is not valid. For example, the number of
arguments does not match the gate expectation.
"""
if len(qargs) != self.num_qubits or cargs:
raise CircuitError(
'The amount of qubit/clbit arguments does not match the gate expectation.')
if any([not qarg for qarg in qargs]):
raise CircuitError('One or more of the arguments are empty')
if len(qargs) == 1:
return Gate._broadcast_single_argument(qargs[0])
elif len(qargs) == 2:
return Gate._broadcast_2_arguments(qargs[0], qargs[1])
elif len(qargs) >= 3:
return Gate._broadcast_3_or_more_args(qargs)
else:
raise CircuitError('This gate cannot handle %i arguments' % len(qargs))
Ce que vous faites est comme vous pouvez le voir dans les commentaires. Le traitement change en fonction du nombre de bits quantiques spécifié dans la porte. Dans le cas de la porte H, il n'y en a qu'une, mais regardons-les toutes.
@staticmethod
def _broadcast_single_argument(qarg):
"""Expands a single argument.
For example: [q[0], q[1]] -> [q[0]], [q[1]]
"""
# [q[0], q[1]] -> [q[0]]
# -> [q[1]]
for arg0 in qarg:
yield [arg0], []
@staticmethod
def _broadcast_2_arguments(qarg0, qarg1):
if len(qarg0) == len(qarg1):
# [[q[0], q[1]], [r[0], r[1]]] -> [q[0], r[0]]
# -> [q[1], r[1]]
for arg0, arg1 in zip(qarg0, qarg1):
yield [arg0, arg1], []
elif len(qarg0) == 1:
# [[q[0]], [r[0], r[1]]] -> [q[0], r[0]]
# -> [q[0], r[1]]
for arg1 in qarg1:
yield [qarg0[0], arg1], []
elif len(qarg1) == 1:
# [[q[0], q[1]], [r[0]]] -> [q[0], r[0]]
# -> [q[1], r[0]]
for arg0 in qarg0:
yield [arg0, qarg1[0]], []
else:
raise CircuitError('Not sure how to combine these two qubit arguments:\n %s\n %s' %
(qarg0, qarg1))
@staticmethod
def _broadcast_3_or_more_args(qargs):
if all(len(qarg) == len(qargs[0]) for qarg in qargs):
for arg in zip(*qargs):
yield list(arg), []
else:
raise CircuitError(
'Not sure how to combine these qubit arguments:\n %s\n' % qargs)
Dans le cas d'un, vous les mettez simplement dans une liste un par un.
Dans le cas de trois, «[[q [0], r [0]], [q [1], r [1]], [q [2], r [2]]]» est «[q [ C'est aussi simple que 0], q [1], q [2]] ʻet[r [0], r [1], r [2]]
.
Dans le cas de deux, il semble que l'abréviation soit autorisée comme indiqué dans le commentaire.
qc = QuantumCircuit(3, 3)
qc.cx([0, 1], 2)
print(qc.draw())
'''résultat(Omis là où vous n'avez pas besoin):
q_0: |0>──■───────
│
q_1: |0>──┼────■──
┌─┴─┐┌─┴─┐
q_2: |0>┤ X ├┤ X ├
└───┘└───┘
'''
qc = QuantumCircuit(3, 3)
qc.cx(0, [1, 2])
print(qc.draw())
'''résultat(Omis là où vous n'avez pas besoin):
q_0: |0>──■────■──
┌─┴─┐ │
q_1: |0>┤ X ├──┼──
└───┘┌─┴─┐
q_2: |0>─────┤ X ├
└───┘
'''
Comme vous pouvez le voir, for (qarg, carg) in instruction.broadcast_arguments (extended_qargs, extended_cargs):
extrait séquentiellement les bits quantiques auxquels la porte est appliquée.
QuantumCircuit._append
Tout d'abord
for (qarg, carg) in instruction.broadcast_arguments(expanded_qargs, expanded_cargs):
instructions.add(self._append(instruction, qarg, carg), qarg, carg)
Comme vous pouvez le voir dans le code
for (qarg, carg) in instruction.broadcast_arguments(expanded_qargs, expanded_cargs):
self._append(instruction, qarg, carg)
instructions.add(instruction, qarg, carg)
Il vaut mieux le faire. Je comprends que je veux couper une ligne parce que je suis programmeur.
Ensuite, quand vous pensez que c'est fini, jetons un coup d'œil à la longueur inattendue _append
.
def _append(self, instruction, qargs, cargs):
"""Append an instruction to the end of the circuit, modifying
the circuit in place.
Args:
instruction (Instruction or Operator): Instruction instance to append
qargs (list(tuple)): qubits to attach instruction to
cargs (list(tuple)): clbits to attach instruction to
Returns:
Instruction: a handle to the instruction that was just added
Raises:
CircuitError: if the gate is of a different shape than the wires
it is being attached to.
"""
if not isinstance(instruction, Instruction):
raise CircuitError('object is not an Instruction.')
# do some compatibility checks
self._check_dups(qargs)
self._check_qargs(qargs)
self._check_cargs(cargs)
# add the instruction onto the given wires
instruction_context = instruction, qargs, cargs
self._data.append(instruction_context)
self._update_parameter_table(instruction)
return instruction
Premier _check_dups
def _check_dups(self, qubits):
"""Raise exception if list of qubits contains duplicates."""
squbits = set(qubits)
if len(squbits) != len(qubits):
raise CircuitError("duplicate qubit arguments")
Ceci vérifie les doublons dans qarg
.
Un seul bitgate quantique comme H ne peut pas se dupliquer, mais il joue quelque chose comme qc.cx (0, 0)
.
Puis _check_qargs
et _check_cargs
def _check_qargs(self, qargs):
"""Raise exception if a qarg is not in this circuit or bad format."""
if not all(isinstance(i, Qubit) for i in qargs):
raise CircuitError("qarg is not a Qubit")
if not all(self.has_register(i.register) for i in qargs):
raise CircuitError("register not in this circuit")
def _check_cargs(self, cargs):
"""Raise exception if clbit is not in this circuit or bad format."""
if not all(isinstance(i, Clbit) for i in cargs):
raise CircuitError("carg is not a Clbit")
if not all(self.has_register(i.register) for i in cargs):
raise CircuitError("register not in this circuit")
Pour Qubit
et Clbit
, c'est un objet qui est retourné lorsque vous prenez l'index du registre et faites quelque chose commeq [0]
.
J'ai confirmé qu'il s'agit d'un registre quantique correctement inclus dans le circuit.
C'est la fin de l'ajout de la porte H.
qc.h(0)
qc.cx(0, 1)
qc.measure([0,1], [0,1])
Jetons un coup d'œil à cx.
La méthode cx
est implémentée dans qiskit / extensions / standard / cx.py Cependant, c'est presque la même chose que la porte H.
def cx(self, ctl, tgt): # pylint: disable=invalid-name
"""Apply CX from ctl to tgt."""
return self.append(CnotGate(), [ctl, tgt], [])
QuantumCircuit.cx = cx
QuantumCircuit.cnot = cx
Le déroulement de l'appel ʻappend` lorsqu'il est appelé est le même que celui de la porte H.
Regardons également mesure
. Lisez qiskit / circuit / measure.py.
def measure(self, qubit, cbit):
"""Measure quantum bit into classical bit (tuples).
Args:
qubit (QuantumRegister|list|tuple): quantum register
cbit (ClassicalRegister|list|tuple): classical register
Returns:
qiskit.Instruction: the attached measure instruction.
Raises:
CircuitError: if qubit is not in this circuit or bad format;
if cbit is not in this circuit or not creg.
"""
return self.append(Measure(), [qubit], [cbit])
QuantumCircuit.measure = measure
Oui, c'est juste «ajouter». Cependant, notez que broadcast_arguments
est de la classe Measure
au lieu de la classe Gate
.
def broadcast_arguments(self, qargs, cargs):
qarg = qargs[0]
carg = cargs[0]
if len(carg) == len(qarg):
for qarg, carg in zip(qarg, carg):
yield [qarg], [carg]
elif len(qarg) == 1 and carg:
for each_carg in carg:
yield qarg, [each_carg]
else:
raise CircuitError('register size error')
Dans le cas de qc.measure ([0,1], [0,1])
, celle au-dessus de l'instruction if est appelée.
La partie elif correspond au cas où un registre est passé, tel que qc.measure (q, c)
.
Vous pouvez maintenant lire l'objectif du jour, qc = QuantumCircuit (2, 2)
à qc.measure ([0,1], [0,1])
.
Cette fois, j'ai lu de la création d'un circuit quantique à l'ajout de portes et de mesures. Dans les bibliothèques de calcul quantique, l'addition de méthode dynamique est souvent effectuée afin d'implémenter l'addition de porte, etc. sous la forme de méthodes. Nous avons regardé comment il a été ajouté dans Qiskit. De plus, les registres quantiques sont importants pour implémenter les circuits quantiques de Qiskit. J'ai eu l'impression que le code était compliqué à cause de la manipulation autour de cela.
Je suis toujours curieux de connaître l'implémentation de Qiskit, alors j'aimerais en savoir plus sur la suite.
Recommended Posts