cutqc2.core package¶
Submodules¶
cutqc2.core.compute_graph module¶
- class cutqc2.core.compute_graph.ComputeGraph[source]¶
Bases:
object- property effective_qubits¶
- get_edges(from_node, to_node)[source]¶
Get edges in the graph based on some given conditions: 1. If from_node is given. Only retain edges from the node. 2. If to_node is given. Only retain edges to the node.
- incoming_to_outgoing_graph()[source]¶
Get a more compact representation of the Compute Graph as a dict of 2-tuples to 2-tuples: (to_subcircuit, to_subcircuit_qubit) => (from_subcircuit, from_subcircuit_qubit)
Any “holes” in indexing are plugged, so that the indices of both the incoming qubits as well as the outgoing qubits are continuous, and start at 0.
- Return type:
dict[tuple[int,int],tuple[int,int]]
cutqc2.core.cut_circuit module¶
cutqc2.core.dag module¶
- class cutqc2.core.dag.DAGEdge(first, second)[source]¶
Bases:
objectRepresents an edge in a quantum circuit DAG, connecting two DagNodes.
- class cutqc2.core.dag.DagNode(wire_index, gate_index)[source]¶
Bases:
objectRepresents a node in a quantum circuit DAG (Directed Acyclic Graph), corresponding to a specific gate on a specific wire (qubit/register).
Since only inter-wire gates are important for the cut algorithm, any mention of gate_index refers to the index wrt inter-wire gates only.
- wire_index¶
The index of the wire (qubit/register).
- Type:
int
- gate_index¶
The index of the gate on the wire. Note: gate_index assumes that only inter-wire gates are considered.
- Type:
int
- classmethod from_string(s)[source]¶
Create a DagNode from a string representation.
- Parameters:
s (str) – The string representation of the node in the format ‘[wire_index]gate_index’.
- Returns:
The created DagNode instance.
- Return type:
- locate(dag_circuit)[source]¶
Locate the position of the DagNode in the DAGCircuit. :type dag_circuit:
DAGCircuit:param dag_circuit: The DAGCircuit containing the node. :type dag_circuit: DAGCircuit- Returns:
A tuple containing the Qubit and the index of the gate on that wire.
- Return type:
tuple[Qubit, int]
- Raises:
ValueError – If the node cannot be found in the DAGCircuit.
cutqc2.core.dynamic_definition module¶
- class cutqc2.core.dynamic_definition.Bin(qubit_spec, probabilities)[source]¶
Bases:
objectA Bin represents a collection of qubits with a specific configuration (given by qubit_spec) and the associated probabilities.
- class cutqc2.core.dynamic_definition.DynamicDefinition(num_qubits, capacity, prob_fn, epsilon=0.0001)[source]¶
Bases:
objectDynamicDefinition is a class that implements the dynamic definition algorithm for quantum probability distribution reconstruction. It recursively zooms-in on qubits (initially “merged”) that have a high probability mass.
cutqc2.core.mip module¶
- class cutqc2.core.mip.MIPCutSearcher(*, n_vertices, edges, id_to_dag_edge, num_subcircuit, max_subcircuit_width, num_qubits, max_cuts)[source]¶
Bases:
object- add_constraints()[source]¶
Add all optimization variable constraints to the model. We follow the same notation is in section 4.1 of the CutQc paper
- add_variables()[source]¶
Add all optimization variables to the model. We follow the same notation is in section 4.1 of the CutQc paper
cutqc2.core.utils module¶
- cutqc2.core.utils.attribute_shots(subcircuit_measured_probs, subcircuit_entries)[source]¶
Aggregate measured probabilities for symbolic subcircuit entries by linear combination of their contributing instances.
Each entry key maps to a list of terms (coefficient, instance_key). The function forms entry_prob = sum_i coefficient_i * subcircuit_measured_probs[instance_key_i] for every entry.
- Parameters:
subcircuit_measured_probs (dict) – Mapping from (init, meas) instance keys to measured probability vectors (or scalars).
subcircuit_entries (dict) – Mapping from entry keys to a list of (coefficient, instance_key) terms.
- Returns:
Mapping from entry keys to aggregated probability vectors (or scalars).
- Return type:
dict
- cutqc2.core.utils.chunked(gen, chunk_size)[source]¶
Yield lists of length chunk_size from generator gen.
- cutqc2.core.utils.compress_bits(arr, mask)[source]¶
Apply a bit mask that drops bits. mask is an array/list of 0/1, where bit 0 = LSB, bit[-1] = MSB.
- Return type:
ndarray
- cutqc2.core.utils.measure_prob(unmeasured_prob, meas)[source]¶
Project a probability vector from mixed measurement bases onto the computational subspace defined by entries equal to “comp”.
If all bases are computational (or unmeasured_prob is a scalar), the input is returned unchanged. Otherwise, for each full state index, the state is mapped to an effective computational-basis index using measure_state and accumulated with the appropriate sign.
- Parameters:
unmeasured_prob (np.ndarray | float) – Probability vector over all 2^n basis states (MSB-to-LSB convention) or a scalar probability.
meas (Sequence[str]) – Per-qubit measurement basis labels, MSB to LSB (e.g., “comp”, “X”, “Y”, “I”).
- Returns:
Measured probability vector over 2^k states, where k is the number of entries equal to “comp” in meas. If the input is a scalar or meas is entirely computational, the input is returned.
- Return type:
np.ndarray | float
- cutqc2.core.utils.measure_sign(full_states, meas)[source]¶
Vectorized version of sign measurement. full_states: array of ints (shape (…,)) meas: tuple/list of strings, e.g. (“X”, “I”, “Y”) Returns array of ±1 with same shape as full_states.
- Return type:
ndarray
- cutqc2.core.utils.merge_prob_vector(unmerged_prob_vector, qubit_spec, qubit_spec_lsb_first=False)[source]¶
Compress quantum probability vector by merging specified qubits and conditioning on fixed qubit values.
- Parameters:
unmerged_prob_vector (np.ndarray) – Original probability vector (2^num_qubits,)
qubit_spec (str) – String of length num_qubits, MSB to LSB, with each character indicating: - “A”: qubit is preserved in output - “M”: qubit is summed over - “0”/”1”: qubit is fixed to that value
qubit_spec_lsb_first (bool) – If True, qubit_spec is given LSB to MSB instead of MSB to LSB.
- Returns:
Compressed probability vector (2^num_active,) with marginalization and conditioning applied.
- Return type:
np.ndarray
- cutqc2.core.utils.modify_subcircuit_instance(subcircuit, init, meas)[source]¶
Create a runnable instance of subcircuit with specified initialization and measurement-basis rotations applied.
For each qubit i, the corresponding entry in init determines the state preparation inserted at the front of the circuit DAG.
For each qubit i, the corresponding entry in meas determines a basis rotation appended to the back of the circuit so that subsequent computational basis measurement is equivalent to measuring in that basis.
- Parameters:
subcircuit (qiskit.QuantumCircuit) – Base subcircuit to modify.
init (Sequence[str]) – Per-qubit initialization labels. Length must equal the number of qubits in subcircuit.
meas (Sequence[str]) – Per-qubit measurement basis labels. Length must equal the number of qubits in subcircuit.
- Returns:
A new circuit with the requested preparations and basis rotations applied.
- Return type:
qiskit.QuantumCircuit
- cutqc2.core.utils.mutate_measurement_basis(bases)[source]¶
Expand a measurement-basis specification by replacing identity entries with both identity and Z bases.
If all entries are non-identity (no “I” present), the function returns a singleton list containing the original meas. Otherwise, for each qubit position with basis “I”, it generates two alternatives: “I” and “Z”. The Cartesian product across positions yields all mutated basis tuples.
- Parameters:
bases (Sequence[str]) – Per-qubit measurement bases (e.g., “comp”, “X”, “Y”, “I”).
- Returns:
All mutated measurement-basis tuples. If no mutation is needed, this is [meas].
- Return type:
list[tuple[str, …]]
- cutqc2.core.utils.run_subcircuit_instance(subcircuit_index, subcircuit, initialization, measurement, backend=None)[source]¶
Evaluate a subcircuit instance for the given initializations and measurement bases, returning their measured probability distributions.
The function expects one (init, meas) specification, creates a runnable subcircuit instance via modify_subcircuit_instance, simulates it using evaluate_circ, and then projects the resulting state/probabilities into the requested measurement bases. If a measurement specification contains “Z”, that instance is skipped. Any identity basis entries “I” are expanded into both “I” and “Z” via mutate_measurement_basis and each mutation is measured separately.
- Parameters:
subcircuit_index (int) – 0-index of the subcircuit instance to simulate. Useful to collate results in the caller.
subcircuit (QuantumCircuit) – Subcircuit to instantiate and simulate.
initialization (tuple[str]) –
- A tuple of state labels per qubit (e.g., “zero”, “one”,
”plus”, “minus”, “plusI”, “minusI”).
measurement (tuple[str]) – A tuple of measurement basis labels per qubit (e.g., “comp”, “X”, “Y”, “I”). If any entry is “Z”, the instance is skipped.
backend (str or Backend, optional) – Backend identifier for evaluation of circuits.
- Returns:
- A 2-tuple with elements:
0: The passed-in subcircuit index 1: A mapping from (init, meas) to the measured probability vector (or a scalar if the circuit evaluates to a single probability).
- Return type:
tuple[int, dict[tuple[tuple[str], tuple[str]], np.ndarray | float]]
- cutqc2.core.utils.unmerge_prob_vector(merged_prob_vector, qubit_spec, full_states=None, qubit_spec_lsb_first=False)[source]¶
Expand a merged quantum probability vector back to a full vector by evenly distributing over merged qubits and conditioning on fixed ones.
- Parameters:
merged_prob_vector (np.ndarray) – Compressed probability vector (2^num_active,)
qubit_spec (str) – String of length num_qubits, MSB to LSB, with each character indicating: - “A”: active (preserved) - “M”: merged (marginalized out) - “0”/”1”: fixed bits
full_states (np.ndarray or None) – Array of full states to fill in. If None, all 2**|num_qubits| states are filled-in.
qubit_spec_lsb_first (bool) – If True, qubit_spec is given LSB to MSB instead of MSB to LSB.
- Return type:
None