MatchCake

matchcake.devices package

Subpackages

Submodules

matchcake.devices.device_utils module

matchcake.devices.device_utils.circuit_or_fop_matmul(first_matrix: Any, second_matrix: Any, *, fop_direction: MatmulDirectionType = MatmulDirectionType.RL, circuit_direction: MatmulDirectionType = MatmulDirectionType.LR, operator: Literal['einsum', 'matmul', '@'] = '@')

Matmul two operators together. The direction of the matmul will depend on the type of the operators. If both operators are MatchgateOperations, the direction of the matmul will be determined by the circuit_direction parameter. If both operators are SingleParticleTransitionMatrixOperations, the direction of the matmul will be determined by the fop_direction parameter. If one operator is a MatchgateOperation and the other is a SingleParticleTransitionMatrixOperation, the MatchgateOperation will be converted to a SingleParticleTransitionMatrixOperation and the matmul will be performed in the direction of the SingleParticleTransitionMatrixOperation.

If the type of the operator is not recognized, a ValueError will be raised.

matchcake.devices.nif_device module

class matchcake.devices.nif_device.NonInteractingFermionicDevice(wires: int | Wires | List[int] = 2, *, r_dtype=torch.float64, c_dtype=torch.complex128, analytic=None, shots: int | None = None, **kwargs)

Bases: QubitDevice

The Non-Interacting Fermionic Simulator device. This device simulates non-interacting fermions using matchgate operations and single particle transition matrices.

The initial state of the device is the Z-zero state \(|0\rangle_{Z}^{\otimes N}\) unless a state preparation operation is applied at the beginning of the circuit.

Parameters:
  • wires (Union[int, Wires, List[int]]) – The number of wires of the device

  • r_dtype (np.dtype) – The data type for the real part of the state vector

  • c_dtype (np.dtype) – The data type for the complex part of the state vector

Kwargs:

Additional keyword arguments

Keyword Arguments:
  • prob_strategy – The strategy to compute the probabilities. Can be either “lookup_table” or “explicit_sum”. Defaults to “lookup_table”.

  • majorana_getter – The Majorana getter to use. Defaults to a new instance of MajoranaGetter.

  • contraction_method – The contraction method to use. Can be either None or “neighbours”. Defaults to None.

  • pfaffian_method – The method to compute the Pfaffian. Can be either “det” or “P”. Defaults to “det”.

  • n_workers – The number of workers to use for multiprocessing. Defaults to 0.

  • star_state_finding_strategy – The strategy to find the star state.

Note:

This device is a simulator for non-interacting fermions. It is based on the default.qubit device.

Note:

This device supports batch execution.

Note:

This device is in development, and its API is subject to change.

TODO: Remove all kind of state storage and only use the state_prep_op. Then add properties like: binary_state, initial_product_state. TODO: Dynamically update the wires when applying operations on different wires -> wires input becomes optional.

DEFAULT_CONTRACTION_METHOD = 'neighbours'
DEFAULT_PFAFFIAN_METHOD = 'det'
DEFAULT_PROB_STRATEGY = 'LookupTable'
DEFAULT_SAMPLING_STRATEGY = '2QubitBy2QubitSampling'
DEFAULT_STAR_STATE_FINDING_STRATEGY = 'FromSampling'
__init__(wires: int | Wires | List[int] = 2, *, r_dtype=torch.float64, c_dtype=torch.complex128, analytic=None, shots: int | None = None, **kwargs)
analytic_probability(wires=None)

Return the (marginal) probability of each computational basis state from the last run of the device.

PennyLane uses the convention \(|q_0,q_1,\dots,q_{N-1}\rangle\) where \(q_0\) is the most significant bit.

If no wires are specified, then all the basis states representable by the device are considered and no marginalization takes place.

Note

marginal_prob() may be used as a utility method to calculate the marginal probability distribution.

Parameters:

wires (Iterable[Number, str], Number, str, Wires) – wires to return marginal probabilities for. Wires not provided are traced out of the system.

Returns:

list of the probabilities

Return type:

array[float]

apply(operations, rotations=None, **kwargs)

This method applies a list of operations to the device. It will update the _transition_matrix attribute of the device.

Note:

if the number of workers is different from 0, this method will use multiprocessing method apply_mp() to apply the operations.

Parameters:
  • operations – The operations to apply

  • rotations – The rotations to apply

  • kwargs – Additional keyword arguments.

Returns:

None

apply_generator(op_iterator: Iterable[Operation], **kwargs) NonInteractingFermionicDevice

Apply a generator of gates to the device.

Parameters:
  • op_iterator (Iterable[qml.operation.Operation]) – The generator of operations to apply

  • kwargs – Additional keyword arguments

Returns:

None

apply_op(op: Operation) SingleParticleTransitionMatrixOperation

Applies a given quantum operation to compute and update the single-particle transition matrix representation.

This method processes the input operation, converts it into its corresponding single-particle transition matrix operation, and updates the global single- particle transition matrix attribute. It also determines if batching is enabled by checking the dimensions of the resulting matrix.

Parameters:

op – The quantum operation to be applied, represented as an instance of qml.operation.Operation.

Returns:

The updated single-particle transition matrix, represented as an instance of SingleParticleTransitionMatrixOperation.

apply_state_prep(operation, **kwargs) bool

Apply a state preparation operation to the device. Will set the internal state of the device only if the operation is a state preparation operation and then return True. Otherwise, it will return False.

Parameters:
  • operation – The operation to apply

  • kwargs – Additional keyword arguments

Returns:

True if the operation was applied, False otherwise

Return type:

bool

author = 'Jérémie Gince'
batch_transform(circuit: QuantumTape)

Apply a differentiable batch transform for preprocessing a circuit prior to execution. This method is called directly by the QNode, and should be overwritten if the device requires a transform that generates multiple circuits prior to execution.

By default, this method contains logic for generating multiple circuits, one per term, of a circuit that terminates in expval(H), if the underlying device does not support Hamiltonian expectation values, or if the device requires finite shots.

Warning

This method will be tracked by autodifferentiation libraries, such as Autograd, JAX, TensorFlow, and Torch. Please make sure to use qml.math for autodiff-agnostic tensor processing if required.

Parameters:

circuit (.QuantumTape) – the circuit to preprocess

Returns:

Returns a tuple containing the sequence of circuits to be executed, and a post-processing function to be applied to the list of evaluated circuit results.

Return type:

tuple[Sequence[.QuantumTape], callable]

property binary_state: ndarray
classmethod capabilities()

Get the capabilities of this device class.

Inheriting classes that change or add capabilities must override this method, for example via

@classmethod
def capabilities(cls):
    capabilities = super().capabilities().copy()
    capabilities.update(
        supports_a_new_capability=True,
    )
    return capabilities
Returns:

results

Return type:

dict[str->*]

casting_priorities = ['numpy', 'autograd', 'jax', 'tf', 'torch']
close_p_bar()
compute_star_state(**kwargs)

Compute the star state of the device. The star state is the state that has the highest probability.

Parameters:

kwargs – Additional keyword arguments

Returns:

The star state and its probability

default_expand_fn(circuit: QuantumTape, max_expansion=10)

Method for expanding or decomposing an input circuit. This method should be overwritten if custom expansion logic is required.

By default, this method expands the tape if:

  • state preparation operations are called mid-circuit,

  • nested tapes are present,

  • any operations are not supported on the device, or

  • multiple observables are measured on the same wire.

Parameters:
  • circuit (.QuantumTape) – the circuit to expand.

  • max_expansion (int) – The number of times the circuit should be expanded. Expansion occurs when an operation or measurement is not supported, and results in a gate decomposition. If any operations in the decomposition remain unsupported by the device, another expansion occurs.

Returns:

The expanded/decomposed circuit, such that the device will natively support all operations.

Return type:

.QuantumTape

exact_expval(observable)

Computes the expectation value of a given observable.

This method evaluates the expectation value of the provided observable by using appropriate execution strategies or by splitting its terms. If the observable cannot be computed using any of the defined strategies, an error is raised.

Parameters:

observable (object) – The observable for which the expectation value is to be computed. It must be of a compatible type such as BasisStateProjector or BatchProjector, or match the supported execution strategies.

Returns:

The computed expectation value of the given observable.

Return type:

float

Raises:

qml.DeviceError – If the expectation value of the observable cannot be computed on the current device due to compatibility issues.

execute_generator(op_iterator: Iterable[Operation], observable: Optional = None, output_type: Literal['samples', 'expval', 'probs', 'star_state', '*state'] | None = None, **kwargs)

Execute a generator of operations on the device and return the result in the specified output type.

Parameters:
  • op_iterator (Iterable[qml.operation.Operation]) – A generator of operations to execute

  • observable (Optional) – The observable to measure

  • output_type (Optional[Literal["samples", "expval", "probs"]]) – The type of output to return. Supported types are “samples”, “expval”, and “probs”

  • kwargs – Additional keyword arguments

Keyword Arguments:
  • reset – Whether to reset the device before applying the operations. Default is False.

  • apply – Whether to apply the operations. Where “auto” will apply the operations if the transition matrix is None which means that no operations have been applied yet. Default is “auto”.

  • wires – The wires to measure the observable on. Default is None.

  • shot_range – The range of shots to measure the observable on. Default is None.

  • bin_size – The size of the bins to measure the observable on. Default is None.

Returns:

The result of the execution in the specified output type

execute_output(observable: Optional = None, output_type: Literal['samples', 'expval', 'probs', 'star_state', '*state'] | None = None, **kwargs)

Return the result of the execution in the specified output type.

Parameters:
  • observable (Optional) – The observable to measure

  • output_type (Optional[Literal["samples", "expval", "probs"]]) – The type of output to return. Supported types are “samples”, “expval”, and “probs”

  • kwargs – Additional keyword arguments

Keyword Arguments:
  • reset – Whether to reset the device before applying the operations. Default is False.

  • apply – Whether to apply the operations. Where “auto” will apply the operations if the transition matrix is None which means that no operations have been applied yet. Default is “auto”.

  • wires – The wires to measure the observable on. Default is None.

  • shot_range – The range of shots to measure the observable on. Default is None.

  • bin_size – The size of the bins to measure the observable on. Default is None.

Returns:

The result of the execution in the specified output type

expval(observable, shot_range=None, bin_size=None)

Calculates the expectation value of a given observable.

This method computes the expectation value of the provided observable. If the shots attribute is set to None, it uses an exact method to calculate the expectation value. Otherwise, it leverages the parent class method with the specified shot range and bin size.

Parameters:
  • observable – Observable for which the expectation value is being calculated.

  • shot_range – Tuple specifying the range of shots to consider.

  • bin_size – Integer specifying the number of shots per bin.

Returns:

The computed expectation value.

generate_samples()

Returns the computational basis samples generated for all wires.

Note that PennyLane uses the convention \(|q_0,q_1,\dots,q_{N-1}\rangle\) where \(q_0\) is the most significant bit.

Warning

This method should be overwritten on devices that generate their own computational basis samples, with the resulting computational basis samples stored as self._samples.

Returns:

array of samples in the shape (dev.shots, dev.num_wires)

Return type:

array[complex]

get_state_probability(target_binary_state: TensorLike | Tensor | Number, wires: Wires | None = None)

Calculates the probability of the system being in a specific binary state for the given wires.

This method determines how likely the system’s quantum state corresponds to the provided target binary state. The functionality supports different formats for the input state: integer, list, string, or a tensor-like object. It also processes the specified wires to pinpoint the relevant parts of the quantum state and computes the probability using internally defined strategies.

Parameters:
  • target_binary_state (TensorLike) – The desired binary state of the system to calculate the probability for. Can be provided as an integer, list, string, or tensor-like object.

  • wires (Optional[Wires]) – Optional argument specifying which wires to consider when computing the probability. If not provided, defaults to all wires in the system.

Returns:

Probability associated with the target binary state on the given wires. Returns None if the state has not been initialized.

Return type:

float or None

get_states_probability(target_binary_states: TensorLike | Tensor | Number, batch_wires: Wires | None = None, **kwargs)

Calculates the probability of the provided binary states with respect to the current system state. This function supports various input formats for the target binary states, including integers, strings, lists, and NumPy arrays, and performs necessary conversions to ensure compatibility. It handles batch processing of wires in conjunction with target states to compute the resulting probabilities. If the system state is uninitialized, the function returns None.

Parameters:
  • target_binary_states – Tensor-like object representing the target binary states. May be an integer, string, list, or NumPy array. If provided as an integer or string, it is converted into a vectorized binary format.

  • batch_wires – Optional; defines the wires to process in batch. Defaults to the current set of system wires. Expected to match the shape of target_binary_states.

  • kwargs – Additional keyword arguments for fine-tuning the probability computation process. Includes parameters like show_progress, which controls the display of progress feedback, and others related to the internal state representation and computation strategies.

Returns:

If successful, returns probabilities of the provided binary states as computed by the configured probability strategy. In case the system state is not initialized, returns None.

property global_sptm: SingleParticleTransitionMatrixOperation | None
initialize_p_bar(*args, **kwargs) tqdm | None
property is_state_initialized: bool
property lookup_table: NonInteractingFermionicLookupTable
name = 'Non-Interacting Fermionic Simulator'
observables = {'BatchHamiltonian', 'Hermitian', 'Identity', 'PauliX', 'PauliY', 'PauliZ', 'Prod', 'Projector', 'Sprod', 'Sum'}
operations = {'BasisEmbedding', 'BasisState', 'CompHH', 'CompPauli', 'CompRotation', 'CompRxRx', 'CompRyRy', 'CompRzRz', 'CompXX', 'CompYY', 'CompZZ', 'MatchgateIdentity', 'MatchgateOperation', 'Rxx', 'Rzz', 'SingleParticleTransitionMatrixOperation', 'Snapshot', 'SptmCompHH', 'SptmCompRxRx', 'SptmCompRyRy', 'SptmCompRzRz', 'SptmFSwap', 'SptmFSwapHH', 'SptmFermionicSuperposition', 'SptmIdentity', 'StatePrep', 'fSWAP'}
p_bar_set_n(n: int)
p_bar_set_postfix(*args, **kwargs)
p_bar_set_postfix_str(*args, **kwargs)
p_bar_set_total(total: int)
pennylane_requires = '==0.39'
pfaffian_methods = {'PfaffianFDBPf', 'cuda_det', 'det'}
reset()

Reset the device

property samples: TensorLike | Tensor | Number | None
short_name = 'nif.qubit'
property star_probability: TensorLike | Tensor | Number | None
property star_state: TensorLike | Tensor | Number | None
property state: ndarray

NIF device does not support dense state representation.

Returns:

state vector of the device

Return type:

array[complex]

Note:

This function comes from the default.qubit device.

property state_prep_op: StatePrepBase
property transition_matrix
update_p_bar(*args, **kwargs)
classmethod update_single_particle_transition_matrix(old_sptm: SingleParticleTransitionMatrixOperation | TensorLike | Tensor | Number | None, new_sptm: SingleParticleTransitionMatrixOperation | TensorLike | Tensor | Number) TensorLike | Tensor | Number

Update the old single particle transition matrix by performing a matrix multiplication with the new single particle transition matrix. :param old_sptm: The old single particle transition matrix :param new_sptm: The new single particle transition matrix

Returns:

The updated single particle transition matrix.

version = '0.2.1'

Module contents