tensorcircuit.abstractcircuit#
Methods for abstract circuits independent of nodes, edges and contractions
- class tensorcircuit.abstractcircuit.AbstractCircuit[source]#
Bases:
object
- append(c: tensorcircuit.abstractcircuit.AbstractCircuit, indices: Optional[List[int]] = None) tensorcircuit.abstractcircuit.AbstractCircuit [source]#
append circuit
c
before- Example
>>> c1 = tc.Circuit(2) >>> c1.H(0) >>> c1.H(1) >>> c2 = tc.Circuit(2) >>> c2.cnot(0, 1) >>> c1.append(c2) <tensorcircuit.circuit.Circuit object at 0x7f8402968970> >>> c1.draw() ┌───┐ q_0:┤ H ├──■── ├───┤┌─┴─┐ q_1:┤ H ├┤ X ├ └───┘└───┘
- Parameters
c (BaseCircuit) – The other circuit to be appended
indices (Optional[List[int]], optional) – the qubit indices to which
c
is appended on. Defaults to None, which means plain concatenation.
- Returns
The composed circuit
- Return type
- append_from_qir(qir: List[Dict[str, Any]]) None [source]#
Apply the ciurict in form of quantum intermediate representation after the current cirucit.
- Example
>>> c = tc.Circuit(3) >>> c.H(0) >>> c.to_qir() [{'gatef': h, 'gate': Gate(...), 'index': (0,), 'name': 'h', 'split': None, 'mpo': False}] >>> c2 = tc.Circuit(3) >>> c2.CNOT(0, 1) >>> c2.to_qir() [{'gatef': cnot, 'gate': Gate(...), 'index': (0, 1), 'name': 'cnot', 'split': None, 'mpo': False}] >>> c.append_from_qir(c2.to_qir()) >>> c.to_qir() [{'gatef': h, 'gate': Gate(...), 'index': (0,), 'name': 'h', 'split': None, 'mpo': False}, {'gatef': cnot, 'gate': Gate(...), 'index': (0, 1), 'name': 'cnot', 'split': None, 'mpo': False}]
- Parameters
qir (List[Dict[str, Any]]) – The quantum intermediate representation.
- apply_general_gate(gate: Union[tensorcircuit.gates.Gate, tensorcircuit.quantum.QuOperator], *index: int, name: Optional[str] = None, split: Optional[Dict[str, Any]] = None, mpo: bool = False, ir_dict: Optional[Dict[str, Any]] = None) None [source]#
An implementation of this method should also append gate directionary to self._qir
- static apply_general_gate_delayed(gatef: Callable[[], tensorcircuit.gates.Gate], name: Optional[str] = None, mpo: bool = False) Callable[[...], None] [source]#
- static apply_general_variable_gate_delayed(gatef: Callable[[...], tensorcircuit.gates.Gate], name: Optional[str] = None, mpo: bool = False) Callable[[...], None] [source]#
- barrier_instruction(*index: List[int]) None [source]#
add a barrier instruction flag, no effect on numerical simulation
- Parameters
index (List[int]) – the corresponding qubits
- circuit_param: Dict[str, Any]#
- cond_measure(index: int) Any #
Measurement on z basis at
index
qubit based on quantum amplitude (not post-selection). The highlight is that this method can return the measured result as a int Tensor and thus maintained a jittable pipeline.- Example
>>> c = tc.Circuit(2) >>> c.H(0) >>> r = c.cond_measurement(0) >>> c.conditional_gate(r, [tc.gates.i(), tc.gates.x()], 1) >>> c.expectation([tc.gates.z(), [0]]), c.expectation([tc.gates.z(), [1]]) # two possible outputs: (1, 1) or (-1, -1)
Note
In terms of
DMCircuit
, this method returns nothing and the density matrix after this method is kept in mixed state without knowing the measuremet resuslts- Parameters
index (int) – the qubit for the z-basis measurement
- Returns
0 or 1 for z measurement on up and down freedom
- Return type
Tensor
- cond_measurement(index: int) Any [source]#
Measurement on z basis at
index
qubit based on quantum amplitude (not post-selection). The highlight is that this method can return the measured result as a int Tensor and thus maintained a jittable pipeline.- Example
>>> c = tc.Circuit(2) >>> c.H(0) >>> r = c.cond_measurement(0) >>> c.conditional_gate(r, [tc.gates.i(), tc.gates.x()], 1) >>> c.expectation([tc.gates.z(), [0]]), c.expectation([tc.gates.z(), [1]]) # two possible outputs: (1, 1) or (-1, -1)
Note
In terms of
DMCircuit
, this method returns nothing and the density matrix after this method is kept in mixed state without knowing the measuremet resuslts- Parameters
index (int) – the qubit for the z-basis measurement
- Returns
0 or 1 for z measurement on up and down freedom
- Return type
Tensor
- conditional_gate(which: Any, kraus: Sequence[tensorcircuit.gates.Gate], *index: int) None #
Apply
which
-th gate fromkraus
list, i.e. apply kraus[which]- Parameters
which (Tensor) – Tensor of shape [] and dtype int
kraus (Sequence[Gate]) – A list of gate in the form of
tc.gate
or Tensorindex (int) – the qubit lines the gate applied on
- draw(**kws: Any) Any [source]#
Visualise the circuit. This method recevies the keywords as same as qiskit.circuit.QuantumCircuit.draw. More details can be found here: https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.draw.html. Interesting kws options include: ``idle_wires``(bool)
- Example
>>> c = tc.Circuit(3) >>> c.H(1) >>> c.X(2) >>> c.CNOT(0, 1) >>> c.draw(output='text') q_0: ───────■── ┌───┐┌─┴─┐ q_1: ┤ H ├┤ X ├ ├───┤└───┘ q_2: ┤ X ├───── └───┘
- expectation(*ops: Tuple[tensornetwork.network_components.Node, List[int]], reuse: bool = True, noise_conf: Optional[Any] = None, nmc: int = 1000, status: Optional[Any] = None, **kws: Any) Any [source]#
- expectation_ps(x: Optional[Sequence[int]] = None, y: Optional[Sequence[int]] = None, z: Optional[Sequence[int]] = None, ps: Optional[Sequence[int]] = None, reuse: bool = True, noise_conf: Optional[Any] = None, nmc: int = 1000, status: Optional[Any] = None, **kws: Any) Any [source]#
Shortcut for Pauli string expectation. x, y, z list are for X, Y, Z positions
- Example
>>> c = tc.Circuit(2) >>> c.X(0) >>> c.H(1) >>> c.expectation_ps(x=[1], z=[0]) array(-0.99999994+0.j, dtype=complex64)
>>> c = tc.Circuit(2) >>> c.cnot(0, 1) >>> c.rx(0, theta=0.4) >>> c.rx(1, theta=0.8) >>> c.h(0) >>> c.h(1) >>> error1 = tc.channels.generaldepolarizingchannel(0.1, 1) >>> error2 = tc.channels.generaldepolarizingchannel(0.06, 2) >>> noise_conf = NoiseConf() >>> noise_conf.add_noise("rx", error1) >>> noise_conf.add_noise("cnot", [error2], [[0, 1]]) >>> c.expectation_ps(x=[0], noise_conf=noise_conf, nmc=10000) (0.46274087-3.764033e-09j)
- Parameters
x (Optional[Sequence[int]], optional) – sites to apply X gate, defaults to None
y (Optional[Sequence[int]], optional) – sites to apply Y gate, defaults to None
z (Optional[Sequence[int]], optional) – sites to apply Z gate, defaults to None
ps (Optional[Sequence[int]], optional) – or one can apply a ps structures instead of
x
,y
,z
, e.g. [0, 1, 3, 0, 2, 2] for X_1Z_2Y_4Y_5 defaults to None,ps
can overwritex
,y
andz
reuse (bool, optional) – whether to cache and reuse the wavefunction, defaults to True
noise_conf (Optional[NoiseConf], optional) – Noise Configuration, defaults to None
nmc (int, optional) – repetition time for Monte Carlo sampling for noisfy calculation, defaults to 1000
status (Optional[Tensor], optional) – external randomness given by tensor uniformly from [0, 1], defaults to None, used for noisfy circuit sampling
- Returns
Expectation value
- Return type
Tensor
- classmethod from_json(jsonstr: str, circuit_params: Optional[Dict[str, Any]] = None) tensorcircuit.abstractcircuit.AbstractCircuit [source]#
load json str as a Circuit
- Parameters
jsonstr (str) – _description_
circuit_params (Optional[Dict[str, Any]], optional) – Extra circuit parameters in the format of
__init__
, defaults to None
- Returns
_description_
- Return type
- classmethod from_json_file(file: str, circuit_params: Optional[Dict[str, Any]] = None) tensorcircuit.abstractcircuit.AbstractCircuit [source]#
load json file and convert it to a circuit
- Parameters
file (str) – filename
circuit_params (Optional[Dict[str, Any]], optional) – _description_, defaults to None
- Returns
_description_
- Return type
- classmethod from_openqasm(qasmstr: str, circuit_params: Optional[Dict[str, Any]] = None, keep_measure_order: bool = False) tensorcircuit.abstractcircuit.AbstractCircuit [source]#
- classmethod from_openqasm_file(file: str, circuit_params: Optional[Dict[str, Any]] = None, keep_measure_order: bool = False) tensorcircuit.abstractcircuit.AbstractCircuit [source]#
- classmethod from_qir(qir: List[Dict[str, Any]], circuit_params: Optional[Dict[str, Any]] = None) tensorcircuit.abstractcircuit.AbstractCircuit [source]#
Restore the circuit from the quantum intermediate representation.
- Example
>>> c = tc.Circuit(3) >>> c.H(0) >>> c.rx(1, theta=tc.array_to_tensor(0.7)) >>> c.exp1(0, 1, unitary=tc.gates._zz_matrix, theta=tc.array_to_tensor(-0.2), split=split) >>> len(c) 7 >>> c.expectation((tc.gates.z(), [1])) array(0.764842+0.j, dtype=complex64) >>> qirs = c.to_qir() >>> >>> c = tc.Circuit.from_qir(qirs, circuit_params={"nqubits": 3}) >>> len(c._nodes) 7 >>> c.expectation((tc.gates.z(), [1])) array(0.764842+0.j, dtype=complex64)
- Parameters
qir (List[Dict[str, Any]]) – The quantum intermediate representation of a circuit.
circuit_params (Optional[Dict[str, Any]]) – Extra circuit parameters.
- Returns
The circuit have same gates in the qir.
- Return type
- classmethod from_qiskit(qc: Any, n: Optional[int] = None, inputs: Optional[List[float]] = None, circuit_params: Optional[Dict[str, Any]] = None, binding_params: Optional[Union[Sequence[float], Dict[Any, float]]] = None) tensorcircuit.abstractcircuit.AbstractCircuit [source]#
Import Qiskit QuantumCircuit object as a
tc.Circuit
object.- Example
>>> from qiskit import QuantumCircuit >>> qisc = QuantumCircuit(3) >>> qisc.h(2) >>> qisc.cswap(1, 2, 0) >>> qisc.swap(0, 1) >>> c = tc.Circuit.from_qiskit(qisc)
- Parameters
qc (QuantumCircuit in Qiskit) – Qiskit Circuit object
n (int) – The number of qubits for the circuit
inputs (Optional[List[float]], optional) – possible input wavefunction for
tc.Circuit
, defaults to Nonecircuit_params (Optional[Dict[str, Any]]) – kwargs given in Circuit.__init__ construction function, default to None.
binding_params (Optional[Union[Sequence[float], Dict[Any, float]]]) – (variational) parameters for the circuit. Could be either a sequence or dictionary depending on the type of parameters in the Qiskit circuit. For
ParameterVectorElement
use sequence. ForParameter
use dictionary
- Returns
The same circuit but as tensorcircuit object
- Return type
- classmethod from_qsim_file(file: str, circuit_params: Optional[Dict[str, Any]] = None) tensorcircuit.abstractcircuit.AbstractCircuit [source]#
- gate_aliases = [['cnot', 'cx'], ['fredkin', 'cswap'], ['toffoli', 'ccnot'], ['toffoli', 'ccx'], ['any', 'unitary'], ['sd', 'sdg'], ['td', 'tdg']]#
- gate_count(gate_list: Optional[Union[str, Sequence[str]]] = None) int [source]#
count the gate number of the circuit
- Example
>>> c = tc.Circuit(3) >>> c.h(0) >>> c.multicontrol(0, 1, 2, ctrl=[0, 1], unitary=tc.gates._x_matrix) >>> c.toffolli(1, 2, 0) >>> c.gate_count() 3 >>> c.gate_count(["multicontrol", "toffoli"]) 2
- Parameters
gate_list (Optional[Sequence[str]], optional) – gate name or gate name list to be counted, defaults to None (counting all gates)
- Returns
the total number of all gates or gates in the
gate_list
- Return type
int
- gate_count_by_condition(cond_func: Callable[[Dict[str, Any]], bool]) int [source]#
count the number of gates that satisfy certain condition
- Example
>>> c = tc.Circuit(3) >>> c.x(0) >>> c.h(0) >>> c.multicontrol(0, 1, 2, ctrl=[0, 1], unitary=tc.gates._x_matrix) >>> c.gate_count_by_condition(lambda qir: qir["index"] == (0, )) 2 >>> c.gate_count_by_condition(lambda qir: qir["mpo"]) 1
- Parameters
cond_func (Callable[[Dict[str, Any]], bool]) – the condition for counting the gate
- Returns
the total number of all gates which satisfy the
condition
- Return type
int
- gate_summary() Dict[str, int] [source]#
return the summary dictionary on gate type - gate count pair
- Returns
the gate count dict by gate type
- Return type
Dict[str, int]
- get_positional_logical_mapping() Dict[int, int] [source]#
Get positional logical mapping dict based on measure instruction. This function is useful when we only measure part of the qubits in the circuit, to process the count result from partial measurement, we must be aware of the mapping, i.e. for each position in the count bitstring, what is the corresponding qubits (logical) defined on the circuit
- Returns
positional_logical_mapping
- Return type
Dict[int, int]
- initial_mapping(logical_physical_mapping: Dict[int, int], n: Optional[int] = None, circuit_params: Optional[Dict[str, Any]] = None) tensorcircuit.abstractcircuit.AbstractCircuit [source]#
generate a new circuit with the qubit mapping given by
logical_physical_mapping
- Parameters
logical_physical_mapping (Dict[int, int]) – how to map logical qubits to the physical qubits on the new circuit
n (Optional[int], optional) – number of qubit of the new circuit, can be different from the original one, defaults to None
circuit_params (Optional[Dict[str, Any]], optional) – _description_, defaults to None
- Returns
_description_
- Return type
- inputs: Any#
- inverse(circuit_params: Optional[Dict[str, Any]] = None) tensorcircuit.abstractcircuit.AbstractCircuit [source]#
inverse the circuit, return a new inversed circuit
- EXAMPLE
>>> c = tc.Circuit(2) >>> c.H(0) >>> c.rzz(1, 2, theta=0.8) >>> c1 = c.inverse()
- Parameters
circuit_params (Optional[Dict[str, Any]], optional) – keywords dict for initialization the new circuit, defaults to None
- Returns
the inversed circuit
- Return type
- is_mps: bool#
- measure_instruction(*index: int) None [source]#
add a measurement instruction flag, no effect on numerical simulation
- Parameters
index (int) – the corresponding qubits
- mpogates = ['multicontrol', 'mpo']#
- prepend(c: tensorcircuit.abstractcircuit.AbstractCircuit) tensorcircuit.abstractcircuit.AbstractCircuit [source]#
prepend circuit
c
before- Parameters
c (BaseCircuit) – The other circuit to be prepended
- Returns
The composed circuit
- Return type
- reset_instruction(*index: int) None [source]#
add a reset instruction flag, no effect on numerical simulation
- Parameters
index (int) – the corresponding qubits
- select_gate(which: Any, kraus: Sequence[tensorcircuit.gates.Gate], *index: int) None [source]#
Apply
which
-th gate fromkraus
list, i.e. apply kraus[which]- Parameters
which (Tensor) – Tensor of shape [] and dtype int
kraus (Sequence[Gate]) – A list of gate in the form of
tc.gate
or Tensorindex (int) – the qubit lines the gate applied on
- sgates = ['i', 'x', 'y', 'z', 'h', 't', 's', 'td', 'sd', 'wroot', 'cnot', 'cz', 'swap', 'cy', 'ox', 'oy', 'oz', 'toffoli', 'fredkin']#
- static standardize_gate(name: str) str [source]#
standardize the gate name to tc common gate sets
- Parameters
name (str) – non-standard gate name
- Returns
the standard gate name
- Return type
str
- tex(**kws: Any) str #
Generate latex string based on quantikz latex package
- Returns
Latex string that can be directly compiled via, e.g. latexit
- Return type
str
- to_cirq(enable_instruction: bool = False) Any [source]#
Translate
tc.Circuit
to a cirq circuit object.- Parameters
enable_instruction (bool, defaults to False) – whether also export measurement and reset instructions
- Returns
A cirq circuit of this circuit.
- to_json(file: Optional[str] = None, simplified: bool = False) Any [source]#
circuit dumps to json
- Parameters
file (Optional[str], optional) – file str to dump the json to, defaults to None, return the json str
simplified (bool) – If False, keep all info for each gate, defaults to be False. If True, suitable for IO since less information is required
- Returns
None if dumps to file otherwise the json str
- Return type
Any
- to_openqasm(**kws: Any) str [source]#
transform circuit to openqasm via qiskit circuit, see https://qiskit.org/documentation/stubs/qiskit.circuit.QuantumCircuit.qasm.html for usage on possible options for
kws
- Returns
circuit representation in openqasm format
- Return type
str
- to_qir() List[Dict[str, Any]] [source]#
Return the quantum intermediate representation of the circuit.
- Example
>>> c = tc.Circuit(2) >>> c.CNOT(0, 1) >>> c.to_qir() [{'gatef': cnot, 'gate': Gate( name: 'cnot', tensor: array([[[[1.+0.j, 0.+0.j], [0.+0.j, 0.+0.j]], [[0.+0.j, 1.+0.j], [0.+0.j, 0.+0.j]]], [[[0.+0.j, 0.+0.j], [0.+0.j, 1.+0.j]], [[0.+0.j, 0.+0.j], [1.+0.j, 0.+0.j]]]], dtype=complex64), edges: [ Edge(Dangling Edge)[0], Edge(Dangling Edge)[1], Edge('cnot'[2] -> 'qb-1'[0] ), Edge('cnot'[3] -> 'qb-2'[0] ) ]), 'index': (0, 1), 'name': 'cnot', 'split': None, 'mpo': False}]
- Returns
The quantum intermediate representation of the circuit.
- Return type
List[Dict[str, Any]]
- to_qiskit(enable_instruction: bool = False, enable_inputs: bool = False) Any [source]#
Translate
tc.Circuit
to a qiskit QuantumCircuit object.- Parameters
enable_instruction (bool, defaults to False) – whether also export measurement and reset instructions
enable_inputs (bool, defaults to False) – whether also export the inputs
- Returns
A qiskit object of this circuit.
- vgates = ['r', 'cr', 'u', 'cu', 'rx', 'ry', 'rz', 'phase', 'rxx', 'ryy', 'rzz', 'cphase', 'crx', 'cry', 'crz', 'orx', 'ory', 'orz', 'iswap', 'any', 'exp', 'exp1']#