Ansatz
The Ansatz class is the core building block for quantum variational algorithms in QuOp_MPI. It manages the quantum state, unitary operators, observables, and classical optimization.
Class Reference
- class quop_mpi.Ansatz(system_size: int, MPI_communicator: mpi4py.MPI.Intracomm = mpi4py.MPI.COMM_WORLD)
Bases:
Sampling,Logging,Communicator,Jacobian,Benchmark,BindableDefine and simulate a QVA.
Associated QuOp Functions:
Jacobian Function (
set_parallel_jacobian())Sampling Function (
set_sampling())
- Parameters:
- system_sizeint
number of quantum basis states in the simulated system
- MPI_communicatorIntracomm, optional
MPI Intracomm, by default MPI.COMM_WORLD
Examples
Minimal definition of an arbitrary QVA, of size system size. Where
[UQ, UW]defines the ansatz unitary andobservable_functionis an Observables Function.alg = Ansatz(system_size) alg.set_unitaries([UQ, UW]) alg.set_observables(observable_function)
- Attributes:
- system_sizeint
The size of the simulated quantum system.
- local_iint
parallel partition size of system state and observables
- local_i_offsetint
global index offset of the local parallel partition
- partition_tablendarray[int]
1-D integer array describing the global partitioning scheme such that for a given MPI rank
partition_table[rank + 1] - partition_table[rank] = local_i- observablesndarray[float64]
1-D real array of
local_iobservables- variational_parametersndarray[float64]
1-D real array of variational parameters, updated during optimisation
- ansatz_depthint
number of ansatz iterations, by default
1- total_paramsint
number of variational parameters associated with each ansatz iteration
- expectationfloat
last computed objective function value, updated during optimisation
- ansatz_initial_statendarray[complex128]
1-D complex array of
local_ivalues, the initial system state- final_statendarray[complex128]
1-D array of
local_ielements, the system state after computation of the state evolution under the action of an ansatz unitary.- last_evaluatedndarray[float]
1-D real array, the last variational parameters passed to
evolve_state()- objective_cntint
number of objective function evaluations during QVA simulation
- resultdict
last result returned by the
execute()method- seedint
seeds random number generation, incremented before each repeat in the
benchmark()method- sample_indexeslist[ndarray[int32]]
if simulating sampling, contains the global indexes for each block of sampled observables, resets to
[]when the objective function value is accepted- sampleslist[ndarray[float64]]
if simulating sampling, contains the observable value for each block of sampled observables, resets to
[]when the objective function value is accepted- sample_minimum_indexeslist[int]
if simulating sampling, contains the index of the minimum observable sampled for each computation of the objective function
Key Methods
Configuration
set_unitaries()- Define the sequence of unitary operatorsset_observables()- Set the observable for computing expectation valuesset_initial_state()- Define the initial quantum state
Execution
execute()- Run the variational algorithmbenchmark()- Study performance across ansatz depths
Results
save()- Save results to HDF5print_result()- Display optimization results
- evaluate(variational_parameters: list[float] | np.ndarray[float]) float
Lazily computes the objective function value.
The
Ansatzinstance stores the last variational parameters passed toevaluateand the corresponding objective function value. If the input variational parameters match, re-computation of the final state is skipped and the previously computed objective function value is returned.- Parameters:
- variational_parameterslist[float] or ndarray[float]
1-D
(ansatz_depth * total_params,)real array of variational parameters
- Returns:
- float
objective function value
- evolve_state(variational_parameters: list[float] | np.ndarray[float])
Compute the system state under the action of the ansatz unitary.
- Parameters:
- variational_parameterslist[float] or ndarray[float]
1-D
(ansatz_depth * total_params,)real array of variational parameters.
See also
- execute(variational_parameters: list[float] | np.ndarray[float] = None)
Simulate a QVA.
If
variational_parametersisNone, initial parameter values are generated using the Parameter Function of the correspondingunitaryinstances.- Parameters:
- variational_parameterslist[float] or ndarray[float]
1-D
(ansatz_depth * total_params,)real array of variational parameters
- gen_initial_params(ansatz_depth: int = None) np.ndarray[np.float64]
Generate initial variational parameters.
Values are generated using the Parameter Function associated with each
unitarypassed to theset_unitaries()method.Note
If
ansatz_depthisNonethe ansatz depth defaults to 1 or the depth specified by theset_depth()method.- Parameters:
- ansatz_depthint, optional
number of ansatz iterations
- Returns:
- ndarray[float64]
1-D
(ansatz_depth * total_params,)real array of variational parameters
- get_expectation_value() float
Compute the objective function at the current value of
variational_parameters.- Returns:
- float
objective function value
- get_final_state() np.ndarray[np.complex128] | None
Gather the final state to rank 0 of the
AnsatzMPI subcommunicator.Requires a previous call to
execute(),evolve_state()orbenchmark(). If called afterbenchmark()the gathered state will correspond to the last performed simulation.- Returns:
- ndarray[complex128] or None
the final state at rank 0 of the
Ansatzsubcommunicator,Noneotherwise
- get_probabilities() np.ndarray[np.float64] | None
Gather probabilities computed from the final state at rank 0 of the
AnsatzMPI subcommunicator.Requires a previous call to
execute(),evolve_state()orbenchmark(). If called afterbenchmark()the gathered state will correspond to the last performed simulation.- Returns:
- ndarray[float64] or None
1-D real array of state probabilities at rank 0 of the
Ansatzsubcommunicator,Noneotherwise
- property n_free_params
Number of free parameters presented to the optimizer.
Without a parameter map, this equals n_variational_parameters. With a parameter map, this is the size of the reduced parameter vector.
- objective(variational_parameters: list[float] | np.ndarray[float]) float
Compute the objective function at variational parameters
variational_parameters.- Parameters:
- variational_parameterslist or ndarray[float]
- Returns:
- float
objective function value
- prepare()
Fully initialize the Ansatz for inspection without running optimization.
This method runs both
setup()and internal preparation steps, bringing the Ansatz to its runtime state. After calling this method:All Unitary instances have their attributes populated
Observables, initial state, and operators are generated
print_all_bindable_attributes()shows actual runtime valuesget_expectation_value()can be called
This is useful for:
Debugging QuOp Functions before optimization
Inspecting the parallel partitioning scheme
Querying bindable attributes with their runtime values
Testing observables and initial state functions
See also
setupLower-level setup (parallel resources only)
executeRun optimization
Examples
>>> alg = qwoa(1024) >>> alg.set_qualities(my_observables) >>> alg.prepare() # Fully initialize >>> alg.print_all_bindable_attributes() # Now shows actual values >>> print(f"Observables range: {alg.observables.min():.2f} to {alg.observables.max():.2f}")
- print_all_bindable_attributes()
Print bindable attributes for this Ansatz AND all its Unitaries.
This shows the complete picture of what parameters can be bound in QuOp Functions:
Ansatz-level functions (Observables, Initial State, Parameter Map, Sampling, Objective) bind to Ansatz attributes
Unitary-level functions (Operator, Parameter) bind to Unitary attributes
Call this after
set_unitaries()to see Unitary attributes.See also
print_bindable_attributesAnsatz attributes only
- set_depth(depth: int)
Set the simulated ansatz depth.
- Parameters:
- depthint
number of ansatz iterations
- set_initial_state(function: Callable, initial_state_dict: dict | None = None)
Define the initial state.
- Parameters:
- functioncallable
- initial_state_dictFunctionDict, optional
FunctionDict for the Initial State Function
- set_objective(function: Callable, objective_dict: dict | None = None)
Set a custom objective function (i.e. an objective function other than the expectation value of the prepared state).
The function is called after state evolution - returning a scalar value that is passed to the minimizer.
- Parameters:
- function: callable
- objective_dict: FunctionDict, optional
FunctionDict for the Objective Function
- set_observables(function: Callable | int, observable_dict: dict | None = None)
Specify the observables.
- Parameters:
- functioncallable or int
an Observables Function or an integer specifying the index of a phase-shift unitary in the list passed to
set_unitaries()whose exponent contains the observable vector.- observable_dictFunctionDict, optional
FunctionDict for the Observables Function
- set_optimiser(optimiser: str, optimiser_args: dict | None = None, optimiser_log: list[str] | None = None)
Define the classical optimiser for QVA simulation.
Optionally allows for specification of arguments passed to the optimiser and fields in the optimiser dictionary to write to the log file (see
set_log()). QuOp_MPI supports optimisers provided by SciPy through its minimize method minimize and optimisers provided by the NLopt package with respect to minimisation with scalar constraints through a SciPy-like interface.- Parameters:
- optimiser: {‘scipy’, ‘nlopt’}
‘scipy’ to use the SciPy, ‘nlopt’ to use NLopt, or a callable QuOp_MPI-compatible optimisation function.
- optimiser_args: dict
arguments to pass to the optimiser
- optimiser_log: list[str]
results of the optimisation process are stored in a dictionary. These values may be logged by passing a list of the corresponding keys
Examples
The default optimiser is the BFGS algorithm, which is set internally as follows:
Ansatz.set_optimiser( 'scipy', {'method':'BFGS','options':{'gtol':1e-3}}, ['fun','nfev','success'])
- set_parameter_map(n_free_params: int, mapping_fn: Callable[[np.ndarray], np.ndarray], mapping_dict: dict | None = None)
Register a mapping from a subset of optimisable parameters to the full set of variational parameters.
- Parameters:
- n_free_paramsint
The number of free parameters in the reduced parameter vector. This is the dimensionality of the optimization problem.
- mapping_fncallable
mapping_fn(free_vec, *args, **kwargs) -> full_vec. free_vec is the vector presented to the optimiser; full_vec must have lengthansatz_depth * total_params.- mapping_dictFunctionDict, optional
FunctionDict supplying extra positional and keyword arguments to the mapping function.
- set_seed(seed: int)
Integer for seeding of random number generation.
- Parameters:
- seedint
seeds the generation of random parameters
- set_unitaries(unitaries: list[Unitary])
Define the ansatz unitary.
Unitaries are passed as a python list in order of application from left to right.
- Parameters:
- unitaries: list[unitary]
list of unitaries specifying the action of one ansatz iteration