CUDA-Q Solvers Python API

cudaq_solvers.jordan_wigner(*args, **kwargs)

Overloaded function.

  1. jordan_wigner(hpq: Buffer, hpqrs: Buffer, core_energy: float = 0.0, **kwargs) -> SpinOperator

Perform the Jordan-Wigner transformation on fermionic operators.

This function applies the Jordan-Wigner transformation to convert fermionic operators (represented by one- and two-body integrals) into qubit operators.

Parameters:

hpqnumpy.ndarray

A 2D complex numpy array representing the one-body integrals. Shape should be (N, N) where N is the number of spin molecular orbitals.

hpqrsnumpy.ndarray

A 4D complex numpy array representing the two-body integrals. Shape should be (N, N, N, N) where N is the number of spin molecular orbitals.

core_energyfloat, optional

The core energy of the system when using active space Hamiltonian, nuclear energy otherwise. Default is 0.0.

tolerancefloat, optional

The threshold value for ignoring small coefficients. Can also be specified using ‘tol’. Coefficients with absolute values smaller than this tolerance are considered as zero. Default is 1e-15.

Returns:

cudaq.SpinOperator

A qubit operator (spin operator) resulting from the Jordan-Wigner transformation.

Raises:

ValueError

If the input arrays have incorrect shapes or types.

RuntimeError

If the Jordan-Wigner transformation fails for any reason.

Examples:

>>> import numpy as np
>>> h1 = np.array([[0, 1], [1, 0]], dtype=np.complex128)
>>> h2 = np.zeros((2, 2, 2, 2), dtype=np.complex128)
>>> h2[0, 1, 1, 0] = h2[1, 0, 0, 1] = 0.5
>>> qubit_op = jordan_wigner(h1, h2, core_energy=0.1, tolerance=1e-14)

Notes:

  • The input arrays hpq and hpqrs must be contiguous and in row-major order.

  • This function uses the “jordan_wigner” fermion compiler internally to perform the transformation.

  • The resulting qubit operator can be used directly in quantum algorithms or further manipulated using CUDA Quantum operations.

  1. jordan_wigner(hpq: Buffer, core_energy: float = 0.0, **kwargs) -> SpinOperator

Perform the Jordan-Wigner transformation on fermionic operators.

This function applies the Jordan-Wigner transformation to convert fermionic operators (represented by either one-body or two-body integrals) into qubit operators.

Parameters:

hpqnumpy.ndarray

A complex numpy array representing either: - One-body integrals: 2D array with shape (N, N) - Two-body integrals: 4D array with shape (N, N, N, N) where N is the number of orbitals.

core_energyfloat, optional

The core energy of the system. Default is 0.0.

tolerancefloat, optional

The threshold value for ignoring small coefficients. Can also be specified using ‘tol’. Coefficients with absolute values smaller than this tolerance are considered as zero. Default is 1e-15.

Returns:

cudaq.SpinOperator

A qubit operator (spin operator) resulting from the Jordan-Wigner transformation.

Raises:

ValueError

If the input array has an incorrect shape or type.

RuntimeError

If the Jordan-Wigner transformation fails for any reason.

Examples:

>>> import numpy as np
>>> # One-body integrals
>>> h1 = np.array([[0, 1], [1, 0]], dtype=np.complex128)
>>> qubit_op1 = jordan_wigner(h1, core_energy=0.1, tolerance=1e-14)
>>> # Two-body integrals
>>> h2 = np.zeros((2, 2, 2, 2), dtype=np.complex128)
>>> h2[0, 1, 1, 0] = h2[1, 0, 0, 1] = 0.5
>>> qubit_op2 = jordan_wigner(h2)

Notes:

  • The input array must be contiguous and in row-major order.

  • This function automatically detects whether the input represents one-body or two-body integrals based on its shape.

  • For one-body integrals input, a zero-initialized two-body tensor is used internally.

  • For two-body integrals input, a zero-initialized one-body tensor is used internally.

  • This function uses the “jordan_wigner” fermion compiler internally to perform the transformation.

  • The resulting qubit operator can be used directly in quantum algorithms or further manipulated using CUDA Quantum operations.

class cudaq_solvers.MolecularHamiltonian
property energies

Dictionary of energies from classical computation.

property hamiltonian

The qubit representation of the molecular Hamiltonian.

This is the full electronic Hamiltonian of the molecule, transformed into qubit operators using a specific mapping (e.g., Jordan-Wigner).

Type:

cudaq.SpinOperator

property hpq

One-electron integrals.

A 2D complex array of shape (n_orbitals, n_orbitals), where n_orbitals is the number of spin molecular orbitals, representing the one-electron integrals in the molecular orbital basis. These include kinetic energy and electron-nuclear attraction terms.

Type:

numpy.ndarray

property hpqrs

Two-electron integrals.

A 4D complex array of shape (n_orbitals, n_orbitals, n_orbitals, n_orbitals), where n_orbitals is the number of spin molecular orbitals, representing the two-electron integrals in the molecular orbital basis. These describe electron-electron interactions.

Type:

numpy.ndarray

property n_electrons

The number of electrons in the molecule.

This represents the total number of electrons in the molecular system, which is crucial for determining the filling of orbitals and the overall electronic structure.

Type:

int

property n_orbitals

The number of molecular orbitals.

This is the total number of molecular orbitals considered in the calculation, which determines the size of the Hamiltonian and the complexity of the quantum simulation.

Type:

int

cudaq_solvers.get_operator_pool(arg0: str, **kwargs) list[SpinOperator]

Get and generate an operator pool based on the specified name and configuration.

This function retrieves an operator pool implementation by name and generates a set of operators using the provided configuration.

Parameters:

namestr

The name of the operator pool implementation to use.

configdict

Keyword arguments representing the configuration for operator pool generation. Supported value types: - int: Converted to std::size_t in C++. - list: Converted to std::vector<double> in C++.

Returns:

list

A list of generated operators (cudaq.SpinOperator objects).

Raises:

RuntimeError

If the specified operator pool implementation is not found.

TypeError

If an unsupported configuration value type is provided.

Examples:

>>> ops = get_operator_pool("uccsd", n_qubits=4, n_electrons=2)
>>> ops = get_operator_pool("custom_pool", cutoff=1e-5, parameters=[0.1, 0.2, 0.3])

Notes:

The function internally converts Python types to C++ types and uses the cudaq::operator_pool extension point system to retrieve and generate the operator pool. Only integer and list configuration values are currently supported.

cudaq_solvers.optim.optimize(function: Callable, initial_parameters: list[float], method: str = 'cobyla', **kwargs) tuple[float, list[float]]

Optimize a given objective function using various optimization methods.

This function performs optimization on a user-provided objective function using the specified optimization method. It supports both gradient-based and gradient-free optimization algorithms.

Parameters:

functioncallable

The objective function to be minimized. It should take a list of parameters as input and return either: - A single float value (for gradient-free methods) - A tuple (float, list[float]) where the first element is the function value and the second is the gradient (for gradient-based methods)

initial_parameterslist[float]

Initial guess for the parameters to be optimized.

methodstr, optional

The optimization method to use. Default is ‘cobyla’. Must be a valid, registered cudaq-x optimizer.

optionsdict

Additional options for the optimizer. These are method-specific.

Returns:

OptimizationResult

An object containing the results of the optimization process.

Raises:

RuntimeError

If an invalid optimization method is specified or if the objective function returns an incorrect format for gradient-based optimizers.

Examples:

>>> def objective(x):
...     return sum([xi**2 for xi in x]), [2*xi for xi in x]
>>> result = optimize(objective, [1.0, 2.0, 3.0], method='l-bfgs-b')
>>> print(result.optimal_parameters)
[0.0, 0.0, 0.0]
>>> def simple_objective(x):
...     return sum([xi**2 for xi in x])
>>> result = optimize(simple_objective, [1.0, 2.0, 3.0], method='cobyla')
>>> print(result.optimal_value)
0.0

Notes:

  • The function automatically detects whether the optimization method requires gradients and expects the objective function to return the appropriate format.

  • For gradient-based methods, the objective function must return a tuple of (value, gradient).

  • For gradient-free methods, the objective function should return only the value.

  • The optimization process uses the cudaq-x backend, which must be properly set up and have the specified optimization method registered.

class cudaq_solvers.ObserveExecutionType

An enumeration representing different types of execution in an optimization process.

This enum defines the various types of operations that can occur during an optimization iteration, specifically distinguishing between function evaluations and gradient computations.

Usage:

This enum is typically used in conjunction with optimization algorithms and observation mechanisms to indicate the nature of a particular step or evaluation in the optimization process.

Examples:

>>> def callback(iteration):
...     if iteration.type == ObserveExecutionType.function:
...         print("Function evaluation")
...     elif iteration.type == ObserveExecutionType.gradient:
...         print("Gradient computation")
>>> # In an optimization loop
>>> for step in optimization_steps:
...     if step.type == ObserveExecutionType.function:
...         # Process function evaluation
...     elif step.type == ObserveExecutionType.gradient:
...         # Process gradient information

Notes:

  • The distinction between function evaluations and gradient computations is particularly important for gradient-based optimization methods.

  • Some optimization algorithms may only use function evaluations (gradient-free methods), while others rely heavily on gradient information.

  • This enum can be used for logging, debugging, or implementing custom behaviors based on the type of operation being performed during optimization.

Members:

function : Represents a standard function evaluation of the objective function.

This typically involves computing the value of the objective function at a given point in the parameter space.

gradient : Represents a gradient computation.

This involves calculating the partial derivatives of the objective

function = <ObserveExecutionType.function: 0>
gradient = <ObserveExecutionType.gradient: 1>
property name
property value
class cudaq_solvers.ObserveIteration

A class representing a single iteration of an optimization process.

This class encapsulates the state of an optimization iteration, including the current parameter values, the result of the objective function evaluation, and the type of iteration

property parameters

The current values of the optimization parameters at this iteration. These represent the point in the parameter space being evaluated.

property result

The value of the objective function evaluated at the current parameters. For minimization problems, lower values indicate better solutions.

property type

A string indicating the type or purpose of this iteration. Common types might include: - ‘function’: A standard function evaluation - ‘gradient’: An iteration where gradients were computed The exact set of possible types may depend on the specific optimization algorithm used.

cudaq_solvers.vqe(kernel: Callable, spin_op: SpinOperator, initial_parameters: list[float], **kwargs) tuple

Execute the Variational Quantum Eigensolver (VQE) algorithm.

This function implements the VQE algorithm, a hybrid quantum-classical algorithm used to find the ground state energy of a given Hamiltonian using a parameterized quantum circuit.

Parameters:

kernelcallable

A function representing the parameterized quantum circuit (ansatz). It should take a list of parameters as input and prepare the quantum state.

spin_opcudaq.SpinOperator

The Hamiltonian operator for which to find the ground state energy.

initial_parametersList[float]

Initial values for the variational parameters of the quantum circuit.

optionsdict

Additional options for the VQE algorithm. Supported options include: - shots : int, optional, Number of measurement shots. Default is -1 (use maximum available). - max_iterations : int, optional Maximum number of optimization iterations. Default is -1 (no limit). - verbose : bool, optional Whether to print verbose output. Default is False. - optimizer : str, optional Name of the classical optimizer to use. Default is ‘cobyla’. - gradient : str, optional Method for gradient computation (for gradient-based optimizers). Default is ‘parameter_shift’.

Returns:

Tuple[float, List[float], List[ObserveIteration]]

A tuple containing: 1. The optimized ground state energy. 2. The optimal variational parameters. 3. A list of ObserveIteration objects containing data from each iteration.

Raises:

RuntimeError

If an invalid optimizer or gradient method is specified.

Examples:

>>> def ansatz(params):
...     # Define your quantum circuit here
...     pass
>>> hamiltonian = cudaq.SpinOperator(...)  # Define your Hamiltonian
>>> initial_params = [0.1, 0.2, 0.3]
>>> energy, opt_params, iterations = vqe(ansatz, hamiltonian, initial_params,
...                                      optimizer='cobyla', shots=1000)
>>> print(f"Ground state energy: {energy}")
>>> print(f"Optimal parameters: {opt_params}")

Notes:

  • The function automatically selects between gradient-free and gradient-based optimization based on the chosen optimizer.

  • For gradient-based optimization, the ‘parameter_shift’ method is used by default, but can be changed using the ‘gradient’ option.

  • The ObserveIteration objects in the returned list contain detailed information about each optimization step, useful for analysis and visualization.

  • The performance of VQE heavily depends on the choice of ansatz, initial parameters, and optimization method.

cudaq_solvers.adapt_vqe(arg0: object, arg1: SpinOperator, arg2: list[SpinOperator], **kwargs) tuple[float, list[float], list[SpinOperator]]

Perform ADAPT-VQE (Adaptive Derivative-Assembled Pseudo-Trotter Variational Quantum Eigensolver) optimization.

Parameters:
  • initialStateKernel (object) – Python object representing the initial state kernel.

  • op (cudaq.SpinOperator) – The Hamiltonian operator to be optimized.

  • pool (list of cudaq.SpinOperator) – Pool of operators for ADAPT-VQE.

  • options – Additional options for the optimization process.

Keyword Arguments:
  • optimizer (str) – Optional name of the optimizer to use. Defaults to cobyla.

  • gradient (str) – Optional name of the gradient method to use. Defaults to empty.

Returns:

The result of the ADAPT-VQE optimization.

Note

This function wraps the C++ implementation of ADAPT-VQE in CUDA-QX. It compiles and registers the initial state kernel, sets up the optimizer, and performs the ADAPT-VQE optimization using the provided parameters.

cudaq_solvers.stateprep.uccsd(arg0: cudaq.mlir._mlir_libs._quakeDialects.cudaq_runtime.qview, arg1: list[float], arg2: int, arg3: int) None

Unitary Coupled Cluster Singles Doubles Ansatz. Takes as input the qubits to apply the ansatz on, the rotational parameters, the number of electrons in the system, and the total spin (the number of unpaired electrons).

cudaq_solvers.stateprep.single_excitation(arg0: cudaq.mlir._mlir_libs._quakeDialects.cudaq_runtime.qview, arg1: float, arg2: int, arg3: int) None

Perform a single fermionic excitation.

cudaq_solvers.stateprep.double_excitation(arg0: cudaq.mlir._mlir_libs._quakeDialects.cudaq_runtime.qview, arg1: float, arg2: int, arg3: int, arg4: int, arg5: int) None

Perform a double fermionic excitation.

cudaq_solvers.stateprep.get_num_uccsd_parameters(num_electrons: int, num_qubits: int, spin: int = 0) int

Calculate the number of UCCSD parameters

Parameters:
  • num_electrons (int) – Number of electrons

  • num_qubits (int) – Number of qubits

  • spin (int) – Spin value. Optional, defaults to 0.

Returns:

Number of UCCSD parameters

Return type:

int

cudaq_solvers.stateprep.get_uccsd_excitations(arg0: int, arg1: int, arg2: int) tuple[list[list[int]], list[list[int]], list[list[int]], list[list[int]], list[list[int]]]
cudaq_solvers.get_num_qaoa_parameters(arg0: SpinOperator, arg1: int, **kwargs) int

Return the number of required QAOA rotation parameters.