QCOperations

Operations that can be applied on the Qcircuit class. The idea of the module is the following:

  • An Operation is whichever kind of operation applied to the circuit

  • A ClassicalCondition is a condition on the application of an Operation based on the measurement of previous qudits

The available operations in the library at the moment are:

  • QCMeasureProjective, apply a projective measurement on the system

  • QCRenormalize, renormalize the quantum state to \(\sqrt{<\psi|\psi>}=1\)

  • QCAddSite, add a site to the MPS.

  • QCRemoveSite, remove a site from the MPS. It must be in a product state with the rest.

  • QCObservablesStep, perform a step of measurement of the observables

The available gates instead are:

  • QCZpauli,

  • QCXpauli,

  • QCYpauli,

  • QCHadamard,

  • QCSgate,

  • QCTgate,

  • QCSadggate,

  • QCTadggate,

  • QCPgate,

  • QCSwap,

  • QCCnot,

  • QCCz

  • QCCp

You can always define your own gate through QCOperation.

In particular, for the definition of noisy gates, the procedure of the definition of a new operation is to be preferred over modifying an exsisting one.

Then, the list [QCOperation, sites] is called Instruction.

Classical conditioning

class qmatchatea.circuit.operations.ClassicalCondition(cregister=None, value=None, idx=None)[source]

Class to handle conditions on classically-controlled operations

Parameters

cregisterstr, optional

Name of the classical register relative to the condition

valueint, optional

Value that the register should assume

idxint, optional

If provided, the index of the register to check. If not provided, the decimal number connected to the binary representation of the register is used.

property is_initialized

Initialization property

is_satisfied(qcirc)[source]

Check if the classical condition is satisfied

Parameters

qcircQCircuit

Quantum circuit class

Returns

bool

True if the condition is satisfied, False otherwise

Operations

class qmatchatea.circuit.operations.QCOperation(name, operator, operator_parameters=None, conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]

Operation on the circuit class.

name: str

Unique name of the operation

operator: function

Python function which returns the array of the operator as np.ndarray

operator_parameters: list, optional

List of operator parameters if needed. Default to None.

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

property c_if

True if there is a classical condition on the application of the gate

property is_conditioned

True if there is a classical condition on the application of the gate

is_parametric()[source]

Returns True if the operation is parametrized

property name

Name property

property operator

Returns the operator matrix as np.ndarray

property string_rep

Return the string representation for printing

class qmatchatea.circuit.operations.QCMeasureProjective(cl_idx, selected_output=None, cregister='default', conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]

Apply a projective measurement to the circuit, possibly selecting its output

Parameters

cl_idxint

Position of the classical register where the measurement will be stored

selected_outputint, optional

Output selected a priori. Default to None

cregisterstr, optional

Classical register where the result of the measurement is stored. Default to ‘default’

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCRenormalize(conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]

Renormalize the state when this operation is encountered

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCAddSite(position, conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]

Add a site to the Qcircuit

Parameters

positionint

Position of the link where the site will be added

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCRemoveSite(position, conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]

Remove a site to the Qcircuit

Parameters

positionint

Position of the site to remove

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

Observables

Class to handle the intermediate measurement of observables.

It also handles the indexing of quantum registers and observables.

class qmatchatea.circuit.observables.QCObservableStep(name, observables, operators=<qmatchatea.utils.tn_utils.QCOperators object>, conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]

Perform a measurement of the observables TNObservables. The observables are applied on the WHOLE circuit, regardless of the register. Thus, this class also takes a snapshot of the current quantum registers, in such a way to be able to recover the desired indexes.

Parameters

namestr

Name of the observables step

observables: TNObservables

Observables to be measured at this step

operators: QCOperators, optional

Class containing the operators present in the Observables

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

Examples

For a detailed explanation of how the observable structure will change adapting to the qregisters see:

_adjust_tp_indexing(tp_obs)[source]

Adjust the indexing of a TNObsTensorProduct observable. This procedure works only if we have a single register in the snapshot.

Parameters

tp_obsTNObsTensorProduct

Tensor product observable

Returns

TNObsTensorProduct

The new observable with the correct indexing

_postprocess_local(local)[source]

Postprocess local observables. In input, you get a vector of local observables, one for each site. In output, the vector of local observable is transformed into a dictionary, where the key is the quantum register and the value the local measurement corresponding to that register

Example

Let us suppose that we have a chain of 4 qubits, and we want to measure \(\sigma_z\) locally. Qubits 0,1 are part of register 'default', while qubits 2,3 of 'ancilla'. Then:

# local is the local observable class
local_obs = local.results_buffer['sz']
print(local_obs)
>>>> [0, 1, -1, 0]
# qcobs is the parent class
postprocessed_local_obs = qcobs._postprocess_local(local)
post_proc_res = postprocessed_local_obs.results_buffer['sz']
print(post_proc_res)
>>>> {'default':[0, 1], 'ancilla':[-1, 0]}

Parameters

localTNObsLocal

Local observables to be postprocessed

Returns

TNObsLocal

Postprocessed local observables

_postprocess_probabilities(probabilities)[source]

Postprocess probability measurements. In input, you get the dictionary of the probabilities, in output a dictionary further divided by the quantum registers, as shown in the example. While probabilities are summed for the even and greedy case, when focusing on a quantum register, they are instead concatenated in the unbiased case, since in that scenario we measure the probability intervals

Examples

Let us suppose that we have a chain of 4 qubits. Qubits 0,1,2 are part of register ‘default’ and are in a GHZ state, while qubits 3 of ‘ancilla’ and is in the |1> state.

Even or greedy probabilities

Probabilities on the same state are summed.

# prob is the probability measuremenent observable class
prob_obs = prob.results_buffer['even_probabilities']
print(prob_obs)
>>>> {'1111' : 0.5, '1000' : 0.5}
# qcobs is the parent class
pp_prob = qcobs._postprocess_probabilities(prob)
post_proc_res = pp_prob.results_buffer['even_probabilities']
print(post_proc_res)
>>>> {'default':{'000':0.5, '111':0.5}, 'ancilla':{'1':1}}

Unbiased probabilities

In this specific case the intervals could be summed, since they are contigous, but in the more general case they simply cannot, without losing informations.

# prob is the probability measuremenent observable class
prob_obs = prob.results_buffer['unbiased_probabilities']
print(prob_obs)
>>>> {'1000' : (0, 0.5), '1111' : (0.5, 1)}
# qcobs is the parent class
pp_prob = qcobs._postprocess_probabilities(prob)
post_proc_res = pp_prob.results_buffer['unbiased_probabilities']
print(post_proc_res)
>>>> {'default':{'000':(0, 0.5), '111':(0.5, 1)},
>>>>    'ancilla':{'1':(0, 0.5, 0.5, 1) }}

Parameters

probabilitiesTNObsProbabilities

Probabilities measurement observables to be postprocessed

Returns

TNObsProbabilities

Postprocessed probabilities measurement observables

_postprocess_projective(projective)[source]

Postprocess projective measurements. In input, you get the dictionary of the measurement, in output a dictionary further divided by the quantum registers, as shown in the example.

Example

Let us suppose that we have a chain of 4 qubits. Qubits 0,1,2 are part of register ‘default’ and are in a GHZ state, while qubits 3 of ‘ancilla’ and is in the |1> state. Then:

# proj is the projective measuremenent observable class
proj_obs = proj.results_buffer['projective_measurements']
print(proj_obs)
>>>> {'1111' : 512, '1000' : 512}
# qcobs is the parent class
pp_proj = qcobs._postprocess_projective(proj)
post_proc_res = pp_proj.results_buffer['projective_measurements']
print(post_proc_res)
>>>> {'default':{'000':512, '111':512}, 'ancilla':{'1':1024}}

Parameters

localTNObsProjective

Projective measurement observables to be postprocessed

Returns

TNObsProjective

Postprocessed projective measurement observables

adjust_obs_indexing()[source]

Modify the indexing of the observables that targets a specific site index, such as the TNObsTensorProduct and TNObsWeightedSum.

property has_single_qreg

True if the observable is specific to a single register, False otherwise

postprocess_obs_indexing()[source]

Postprocess the indexing of the observables, after the computation, due to the quantum registers.

snap_current_qregisters(qregisters)[source]

Save the current quantum registers in the quantum circuit to recover the correct pattern of observable-register afterwards

Parameters

qregistersdict

Dictionaty of the quantum registers

Gates

class qmatchatea.circuit.operations.QCZpauli(conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Pauli Z operation.

Its matrix representation is as follows:

\[\begin{split}\mathrm{Z} = \begin{pmatrix} 1 & 0 \\ 0 & -1 \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCXpauli(conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Pauli X operation.

Its matrix representation is as follows:

\[\begin{split}\mathrm{X} = \begin{pmatrix} 0 & 1 \\ 1 & 0 \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCYpauli(conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Pauli Y operation.

Its matrix representation is as follows:

\[\begin{split}\mathrm{Y} = \begin{pmatrix} 0 & -i \\ i & 0 \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCSgate(conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Phase gate with phase \(\pi/2\).

Its matrix representation is as follows:

\[\begin{split}\mathrm{S} = \begin{pmatrix} 1 & 0 \\ 0 & i \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCTgate(conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Phase gate with phase \(\pi/4\).

Its matrix representation is as follows:

\[\begin{split}\mathrm{T} = \begin{pmatrix} 1 & 0 \\ 0 & \frac{1}{\sqrt{2}}(1+i) \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCSadggate(conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Adjoint of the phase gate with phase \(3\pi/2\).

Its matrix representation is as follows:

\[\begin{split}\mathrm{S}^\dagger = \begin{pmatrix} 1 & 0 \\ 0 & -i \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCTadggate(conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Phase gate with phase \(-\pi/4\).

Its matrix representation is as follows:

\[\begin{split}\mathrm{T}^\dagger = \begin{pmatrix} 1 & 0 \\ 0 & \frac{1}{\sqrt{2}}(1-i) \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCPgate(theta, conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Phase gate with phase \(\theta\).

Its matrix representation is as follows:

\[\begin{split}\mathrm{P}(\theta) = \begin{pmatrix} 1 & 0 \\ 0 & e^{i\theta} \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCSwap(conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Swap operation between adjacent qubits.

Its matrix representation is as follows:

\[\begin{split}\mathrm{SWAP} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCCnot(swap=True, conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Cnot operation between adjacent qubits.

Its matrix representation is as follows:

\[\begin{split}\mathrm{CNOT} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 0 & 1 \\ 0 & 0 & 1 & 0 \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCCz(conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Cz operation between adjacent qubits.

Its matrix representation is as follows:

\[\begin{split}\mathrm{CZ} = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & -1 \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.

class qmatchatea.circuit.operations.QCCp(theta, conditioned=<qmatchatea.circuit.operations.ClassicalCondition object>)[source]
Controlled Phase gate with phase \(\theta\).

Its matrix representation is as follows:

\[\begin{split}\mathrm{CP}(\theta) = \begin{pmatrix} 1 & 0 & 0 & 0 \\ 0 & 1 & 0 & 0 \\ 0 & 0 & 1 & 0 \\ 0 & 0 & 0 & e^{i\theta} \\ \end{pmatrix}\end{split}\]

Parameters

conditionedClassicalCondition, optional

Classical condition to be checked for applying the operation on the simulation.