quop_mpi
- class quop_mpi.Ansatz(system_size: int, MPI_communicator: mpi4py.MPI.Intracomm = mpi4py.MPI.COMM_WORLD)
Define and simulate a QVA.
Associated QuOp Functions:
Free Parameters Function (
set_free_params())
- 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
- benchmark(ansatz_depths: iterable[int], repeats: int, initial_parameters: list[float] | np.ndarray[float] = None, param_persist: bool = False, verbose: bool = True, filename: str = None, label: str = 'test', save_action: str = 'a', time_limit: int = None, suspend_path: str = None)
A method by which to study how a QVA performs as the number of ansatz iterations<ansatz depth> increases.
- Parameters:
- ansatz_depthsiterable[int]
integers specifying a sequence of ansatz depths<ansatz depth>
- repeatsint
number of repeats at each ansatz depth
- initial_parameters: list[float] or ndarray[float], optional
** Must be defined if a parameter mapping function is set. ** initial variational parameter values, if not present these are generated using the default parameter generation methods of the ansatz unitaries.
- param_persistbool, optional
if True the optimised variational parameter values which achieved the lowest objective function value for all repeats at ansatz_depth will be used as starting parameters for the first ansatz_depth * total_params at ansatz_depth += 1. if a parameter map is set, the initial parameters will update whenever the objective function reaches a new minimum.
- verbosebool, optional
if True, print current the ansatz depth, repeat number and optimisation results (default True)
- filenamestr or None, optional
name of *.h5 file in which to save the optimised system state and observables
- labelstr, optional
if filename is not None, *.h5 data will be saved as “filename/label_depth_repeat” (default “test”)
- save_action{‘a’, ‘w’}, optional
action taken during first file write: ‘a’ to append, ‘w’ to overwrite (default ‘a’)
- time_limitint or None, optional
total allocated in-program time in seconds; if exceeded, the benchmark is suspended
- suspend_pathstr or None, optional
path to the suspend file if time_limit is not None
- 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
- 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
- save(file_name: str, config_name: str, action: str = 'a')
Write the final state, observables and results summary to a HDf5 file.
- Parameters:
- file_namestr
file path to saved data
- config_namestr
simulation identifier
- action{‘a’, ‘w’}, optional
‘a’ to append or ‘w’ to overwrite, by default ‘a’
Notes
Data is saved into a
*.h5file with the following structure.├── config_name ├── final_state ├── observablesThe minimization result is saved in the ‘minimize_result’ attribute of ‘config_name’ as a formatted string.
Multiple configurations with a unique config_name can be stored in the same .h5 file. HDF5 files are supported in python by the h5py package. With it, a saved configuration can be accessed as follows:
import h5py config_name = "my_simulation" f = h5py.File(file_name + ".h5", "r") final_state = np.array(f[config_name]['final_state']).view(np.complex128) eigenvalues = np.array(f[config_name]['eigenvalues']).view(np.complex128) observables = np.array(f[config_name]['observables']).view(np.float64) print(f["my_simulation"].attrs["minimize_result"])
Warning
The
"final_state"and"observables"datasets are saved using Fortran subroutines which make use of parallel HDF5.The complex values of the final_state array are saved as a compound datatype consisting of contiguous double precision reals. This is equivalent to the np.complex128 NumPy datatype. To access this data without a loss of precision in python, the user must set the view of the NumPy array to np.complex128, rather than casting it to np.complex128 using the dtype keyword.
Similarly, the observables array, which is saved as an array of double-precision reals, should have its view set to np.float64.
- 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_log(filename: str, label: str, action: str = 'a')
Creates a CSV in which to save simulation results after a call to
execute().- Parameters:
- filenamestr
path to the log file
- labelstr
simulation identifier
- action{‘a’, ‘w’}, optional
‘a’ to append or ‘w’ overwrite, by default ‘a’
- 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 the
set_observables()whose exponent contains the observable vector.- observables_dict: FunctionDict, 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_parallel_jacobian(nodes_per_subcomm: int, processes_per_node: int, maxcomm: int, method: str | Callable = 'forward', h: float | None = None)
Specify optimisation of the variational parameters using parallel computation of the jacobian.
This creates MPI subcommunicators containing duplicates of the
Ansatzinstance which return partial derivative information to the root MPI process during optimisation.- Parameters:
- nodes_per_subcommint
MPI nodes per subcommunicator
- processes_per_nodeint
MPI processors associated with each node
- maxcommint
maximum number of created MPI subcommunicators (and
Ansatzinstance duplicates) if nodes_per_subcomm > 1, or the maximum number of MPI subcommunicators per node if nodes_per_subcomm = 1- method :{‘forward’, ‘central’} or callable, optional
‘forward’ or ‘central’ to used the forward difference or central difference method for numerical approximation of the partial derivatives, or a QuOp Jacobian Function, by default ‘forward’
- hfloat, optional
step-size used by the forward or central difference methods, by default
np.sqrt(np.finfo(float).eps)
- set_parameter_map(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:
- 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_sampling(sample_block_size: int, function: Callable | None = None, max_sample_iterations: int = 100, sampling_dict: dict | None = None)
Compute the objective function using simulated sampling.
Samples are taken in blocks of sample_block_size. These are passed as a list of lists to
function(a Sampling Function), which returns a value for expectation value/objective function and a boolean that indicates wether the sampled result should be passed to the classical optimiser.If
functionisNone, the objective function is computed as the mean ofsample_block_sizeshots.- Parameters:
- sample_block_sizeint
number of shots taken between successive computation of the expectation value/objective function
- functioncallable, optional
- max_sample_iterationsint, optional
maximum number of sample blocks per computation of the expectation value/objective function, overrides the boolean returned by
function, by default 100- sampling_dictFunctionDict, optional
FunctionDict for the Sampling 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
- unset_sampling()
Revert to simulation using exact computation of the objective function.
- class quop_mpi.Unitary(operator_function: Callable, operator_n_params: int = 0, operator_dict: dict | None = None, parameter_function: Callable | None = None, param_dict: dict | None = None, unitary_n_params: int = 1)
Base class for a
unitary.A
unitaryis derived from theUnitaryclass and implements simulation of a specfic unitary through definition of the following methods:A list of
unitaryinstances passed toquop_mpi.Ansatz.set_unitaries()defines the ansatz unitary of a QVA. After initialisation,unitaryinstances are managed by thequop_mpi.Ansatzclass and calls tounitarymethods are not made explicitly.See
quop_mpi.propagatorfor predefinedunitarysubclasses.Associated QuOp Functions:
The following attributes are common to all
unitaryinstances.- Attributes:
- final_state
The system state after the action of the unitary.
- initial_parameters
Initial variational parameters returned from the user-defined Parameter Function.
- initial_state
The initial state of the quantum system.
- n_params
The total number of unitary and operator parameterising the unitary.
- operator_function
The user-defined Operator Function.
- operator_dict
A FunctionDict of additional position and keyword arguments for the Operator Function.
- operator
The operator object returned by the Operator Function.
- operator_n_params
Number of variational operator parameters.
- parameter_function
The user-defined Parameter Function.
- param_dict
A FunctionDict of additional position and keyword arguments for the Parameter Function.
- planner
If
True, the parallel partitioning scheme returned byplan()takes precedence over non-plannerunitariesandunitariesthat appear later in the ansatz unitary list supplied toquop_mpi.Ansatz.set_unitaries().- seed
Integer for seeding random number generation, shared with
quop_mpi.Ansatz.- system_size
The size of the simulated quantum system, shared with
quop_mpi.Ansatz.- unitary_n_params
The number of unitary parameters.
- unitary_type
A string labeling the
unitarytype (e.g. “diagonal” or “sparse”).- variational_parameters
Operator variational parameters. If present as an argument of the Operator Function, a real array of size
operator_n_paramsis passed to the Operator Function.- MPI_COMM
MPI Intracommunicator, shared with
quop_mpi.Ansatz.- alloc_local
The size of the array storing the :term`operator` if the operator is an array (equal to
local_iotherwise). The second return value ofplan().- lb
The lower global index of the local system state partition.
- ub
The upper global index of the local system state partition.
- local_i
The size of the local system state partition. The first return value of
plan()- local_i_offset
The global index offset of the local system state partition.
- partition_table
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
- copy_plan(ex_unitary: Unitary)
Perform any setup required by the propagation method called in
propagate().When implemented,
copy_planperforms the same internal operations asplan()using thelocal_iandalloc_localattributes ofex_unitary. Does not return[local_i, alloc_local].Warning
Not implemented by the base
Unitaryclass.- Parameters:
- ex_unitaryunitary
a
unitaryinstance with computedlocal_iandalloc_localattributes
- destroy()
Free memory allocated by Python extension modules in
plan()orcopy_plan(). collector.Memory allocated by compiled Python extension modules is typically not managed by the Python garbage collector. These allocations must be freed via relevant methods in the extension module to prevent the occurrence of memory leaks.
Warning
Not implemented by the base
Unitaryclass.
- plan(system_size: int, MPI_COMM: mpi4py.MPI.Intracomm)
Plan the partitioning scheme used by an
quop_mpi.Ansatzinstance and performs any other tasks required bypropagate().An implemented
planreturns (local_i,alloc_local). Data structures and allocation required by the propagation method called inpropagate()are assigned to attributes of theUnitaryinstance.The
alloc_localreturn value specifies the size of the local system state arraysinitial_stateandfinal_state. In most casesalloc_local == local_i, howeveralloc_local > local_imay be required by particular external propagation methods (e.g. the parallel FFTW).Warning
Not implemented by the base
Unitaryclass.- Parameters:
- system_sizeint
size of the simulated quantum system.
- MPI_COMMIntracomm
MPI communicator over which the
Ansatzobservables, initial state and final state are partitioned.
- Returns:
- (int, int)
number of elements in a row-wise partitioning of the system state and size to allocate for the
initial_stateandfinal_statearrays
Examples
def plan(self, system_size, MPI_COMM): local_i = system_size // MPI_COMM.size local_i = ( system_size - local_i * MPI_COMM.rank if MPI_COMM.rank == 0 else local_i ) alloc_local = local_i return local_i, alloc_local
- propagate(x: np.ndarray[np.float64])
Simulation of the action of a :term`unitary`.
When implemented,
propagatecontains a call to a method (typically a contained in a complied Python extension module) that takes the class attributesinitial_state,final_stateandMPI_COMM, together with attributes describing the parallel partitioning scheme and variational parametersx, as input. The action of the unitary is computed in MPI parallel, with the computed result written tofinal_state.Warning
Not implemented by the base
Unitaryclass.- Parameters:
- xndarray[float64]
a 1-D real array of
n_paramsvariational parameters
Examples
def propagate(self, x): external_propagator( x, self.partition_table, self.initial_state, self.final_state, self.MPI_COMM )
algorithm
combinatorial
Predefined QVAs for combinatorial optimisation problems.
- class quop_mpi.algorithm.combinatorial.qaoa(system_size: int, MPI_communicator: mpi4py.MPI.Intracomm = mpi4py.MPI.COMM_WORLD)
Simulate the QAOA.
See
quop_mpi.Ansatz.- Parameters:
- system_sizeint
system size of the simulated QVA
- MPI_COMMIntracomm, optional
MPI communicator, default
mpi4py.MPI.COMM_WORLD
- benchmark(ansatz_depths: iterable[int], repeats: int, initial_parameters: list[float] | np.ndarray[float] = None, param_persist: bool = False, verbose: bool = True, filename: str = None, label: str = 'test', save_action: str = 'a', time_limit: int = None, suspend_path: str = None)
A method by which to study how a QVA performs as the number of ansatz iterations<ansatz depth> increases.
- Parameters:
- ansatz_depthsiterable[int]
integers specifying a sequence of ansatz depths<ansatz depth>
- repeatsint
number of repeats at each ansatz depth
- initial_parameters: list[float] or ndarray[float], optional
** Must be defined if a parameter mapping function is set. ** initial variational parameter values, if not present these are generated using the default parameter generation methods of the ansatz unitaries.
- param_persistbool, optional
if True the optimised variational parameter values which achieved the lowest objective function value for all repeats at ansatz_depth will be used as starting parameters for the first ansatz_depth * total_params at ansatz_depth += 1. if a parameter map is set, the initial parameters will update whenever the objective function reaches a new minimum.
- verbosebool, optional
if True, print current the ansatz depth, repeat number and optimisation results (default True)
- filenamestr or None, optional
name of *.h5 file in which to save the optimised system state and observables
- labelstr, optional
if filename is not None, *.h5 data will be saved as “filename/label_depth_repeat” (default “test”)
- save_action{‘a’, ‘w’}, optional
action taken during first file write: ‘a’ to append, ‘w’ to overwrite (default ‘a’)
- time_limitint or None, optional
total allocated in-program time in seconds; if exceeded, the benchmark is suspended
- suspend_pathstr or None, optional
path to the suspend file if time_limit is not None
- 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
- 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
- save(file_name: str, config_name: str, action: str = 'a')
Write the final state, observables and results summary to a HDf5 file.
- Parameters:
- file_namestr
file path to saved data
- config_namestr
simulation identifier
- action{‘a’, ‘w’}, optional
‘a’ to append or ‘w’ to overwrite, by default ‘a’
Notes
Data is saved into a
*.h5file with the following structure.├── config_name ├── final_state ├── observablesThe minimization result is saved in the ‘minimize_result’ attribute of ‘config_name’ as a formatted string.
Multiple configurations with a unique config_name can be stored in the same .h5 file. HDF5 files are supported in python by the h5py package. With it, a saved configuration can be accessed as follows:
import h5py config_name = "my_simulation" f = h5py.File(file_name + ".h5", "r") final_state = np.array(f[config_name]['final_state']).view(np.complex128) eigenvalues = np.array(f[config_name]['eigenvalues']).view(np.complex128) observables = np.array(f[config_name]['observables']).view(np.float64) print(f["my_simulation"].attrs["minimize_result"])
Warning
The
"final_state"and"observables"datasets are saved using Fortran subroutines which make use of parallel HDF5.The complex values of the final_state array are saved as a compound datatype consisting of contiguous double precision reals. This is equivalent to the np.complex128 NumPy datatype. To access this data without a loss of precision in python, the user must set the view of the NumPy array to np.complex128, rather than casting it to np.complex128 using the dtype keyword.
Similarly, the observables array, which is saved as an array of double-precision reals, should have its view set to np.float64.
- 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_log(filename: str, label: str, action: str = 'a')
Creates a CSV in which to save simulation results after a call to
execute().- Parameters:
- filenamestr
path to the log file
- labelstr
simulation identifier
- action{‘a’, ‘w’}, optional
‘a’ to append or ‘w’ overwrite, by default ‘a’
- 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 the
set_observables()whose exponent contains the observable vector.- observables_dict: FunctionDict, 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_parallel_jacobian(nodes_per_subcomm: int, processes_per_node: int, maxcomm: int, method: str | Callable = 'forward', h: float | None = None)
Specify optimisation of the variational parameters using parallel computation of the jacobian.
This creates MPI subcommunicators containing duplicates of the
Ansatzinstance which return partial derivative information to the root MPI process during optimisation.- Parameters:
- nodes_per_subcommint
MPI nodes per subcommunicator
- processes_per_nodeint
MPI processors associated with each node
- maxcommint
maximum number of created MPI subcommunicators (and
Ansatzinstance duplicates) if nodes_per_subcomm > 1, or the maximum number of MPI subcommunicators per node if nodes_per_subcomm = 1- method :{‘forward’, ‘central’} or callable, optional
‘forward’ or ‘central’ to used the forward difference or central difference method for numerical approximation of the partial derivatives, or a QuOp Jacobian Function, by default ‘forward’
- hfloat, optional
step-size used by the forward or central difference methods, by default
np.sqrt(np.finfo(float).eps)
- set_parameter_map(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:
- 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_params(param_function: Callable, param_dict: dict | None = None)
Define the Parameter Function for the phase-shift and mixing unitaries.
- Parameters:
- param_functionCallable
- param_dictFunctionDict
FunctionDict for
param_function
- set_qualities(function: Callable, observables_dict: dict | None = None)
Define the observables and phase-shift unitary operator
- Parameters:
- functionCallable
- observables_dictFunctionDict, optional
FunctionDict for
function
- set_sampling(sample_block_size: int, function: Callable | None = None, max_sample_iterations: int = 100, sampling_dict: dict | None = None)
Compute the objective function using simulated sampling.
Samples are taken in blocks of sample_block_size. These are passed as a list of lists to
function(a Sampling Function), which returns a value for expectation value/objective function and a boolean that indicates wether the sampled result should be passed to the classical optimiser.If
functionisNone, the objective function is computed as the mean ofsample_block_sizeshots.- Parameters:
- sample_block_sizeint
number of shots taken between successive computation of the expectation value/objective function
- functioncallable, optional
- max_sample_iterationsint, optional
maximum number of sample blocks per computation of the expectation value/objective function, overrides the boolean returned by
function, by default 100- sampling_dictFunctionDict, optional
FunctionDict for the Sampling 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
- unset_sampling()
Revert to simulation using exact computation of the objective function.
- class quop_mpi.algorithm.combinatorial.qwoa(system_size: int, MPI_communicator: mpi4py.MPI.Intracomm = mpi4py.MPI.COMM_WORLD)
Simulate the QWOA.
See
quop_mpi.Ansatz.- Parameters:
- system_sizeint
system size of the simulated QVA
- MPI_COMMIntracomm, optional
MPI communicator, default
mpi4py.MPI.COMM_WORLD
- benchmark(ansatz_depths: iterable[int], repeats: int, initial_parameters: list[float] | np.ndarray[float] = None, param_persist: bool = False, verbose: bool = True, filename: str = None, label: str = 'test', save_action: str = 'a', time_limit: int = None, suspend_path: str = None)
A method by which to study how a QVA performs as the number of ansatz iterations<ansatz depth> increases.
- Parameters:
- ansatz_depthsiterable[int]
integers specifying a sequence of ansatz depths<ansatz depth>
- repeatsint
number of repeats at each ansatz depth
- initial_parameters: list[float] or ndarray[float], optional
** Must be defined if a parameter mapping function is set. ** initial variational parameter values, if not present these are generated using the default parameter generation methods of the ansatz unitaries.
- param_persistbool, optional
if True the optimised variational parameter values which achieved the lowest objective function value for all repeats at ansatz_depth will be used as starting parameters for the first ansatz_depth * total_params at ansatz_depth += 1. if a parameter map is set, the initial parameters will update whenever the objective function reaches a new minimum.
- verbosebool, optional
if True, print current the ansatz depth, repeat number and optimisation results (default True)
- filenamestr or None, optional
name of *.h5 file in which to save the optimised system state and observables
- labelstr, optional
if filename is not None, *.h5 data will be saved as “filename/label_depth_repeat” (default “test”)
- save_action{‘a’, ‘w’}, optional
action taken during first file write: ‘a’ to append, ‘w’ to overwrite (default ‘a’)
- time_limitint or None, optional
total allocated in-program time in seconds; if exceeded, the benchmark is suspended
- suspend_pathstr or None, optional
path to the suspend file if time_limit is not None
- 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
- 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
- save(file_name: str, config_name: str, action: str = 'a')
Write the final state, observables and results summary to a HDf5 file.
- Parameters:
- file_namestr
file path to saved data
- config_namestr
simulation identifier
- action{‘a’, ‘w’}, optional
‘a’ to append or ‘w’ to overwrite, by default ‘a’
Notes
Data is saved into a
*.h5file with the following structure.├── config_name ├── final_state ├── observablesThe minimization result is saved in the ‘minimize_result’ attribute of ‘config_name’ as a formatted string.
Multiple configurations with a unique config_name can be stored in the same .h5 file. HDF5 files are supported in python by the h5py package. With it, a saved configuration can be accessed as follows:
import h5py config_name = "my_simulation" f = h5py.File(file_name + ".h5", "r") final_state = np.array(f[config_name]['final_state']).view(np.complex128) eigenvalues = np.array(f[config_name]['eigenvalues']).view(np.complex128) observables = np.array(f[config_name]['observables']).view(np.float64) print(f["my_simulation"].attrs["minimize_result"])
Warning
The
"final_state"and"observables"datasets are saved using Fortran subroutines which make use of parallel HDF5.The complex values of the final_state array are saved as a compound datatype consisting of contiguous double precision reals. This is equivalent to the np.complex128 NumPy datatype. To access this data without a loss of precision in python, the user must set the view of the NumPy array to np.complex128, rather than casting it to np.complex128 using the dtype keyword.
Similarly, the observables array, which is saved as an array of double-precision reals, should have its view set to np.float64.
- 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_log(filename: str, label: str, action: str = 'a')
Creates a CSV in which to save simulation results after a call to
execute().- Parameters:
- filenamestr
path to the log file
- labelstr
simulation identifier
- action{‘a’, ‘w’}, optional
‘a’ to append or ‘w’ overwrite, by default ‘a’
- 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 the
set_observables()whose exponent contains the observable vector.- observables_dict: FunctionDict, 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_parallel_jacobian(nodes_per_subcomm: int, processes_per_node: int, maxcomm: int, method: str | Callable = 'forward', h: float | None = None)
Specify optimisation of the variational parameters using parallel computation of the jacobian.
This creates MPI subcommunicators containing duplicates of the
Ansatzinstance which return partial derivative information to the root MPI process during optimisation.- Parameters:
- nodes_per_subcommint
MPI nodes per subcommunicator
- processes_per_nodeint
MPI processors associated with each node
- maxcommint
maximum number of created MPI subcommunicators (and
Ansatzinstance duplicates) if nodes_per_subcomm > 1, or the maximum number of MPI subcommunicators per node if nodes_per_subcomm = 1- method :{‘forward’, ‘central’} or callable, optional
‘forward’ or ‘central’ to used the forward difference or central difference method for numerical approximation of the partial derivatives, or a QuOp Jacobian Function, by default ‘forward’
- hfloat, optional
step-size used by the forward or central difference methods, by default
np.sqrt(np.finfo(float).eps)
- set_parameter_map(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:
- 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_params(param_function, param_dict=None)
Define the Parameter Function for the phase-shift and mixing unitaries.
- Parameters:
- param_functionCallable
- param_dictFunctionDict
FunctionDict for
param_function
- set_qualities(function, observable_dict=None)
Define the observables and phase-shift unitary operator
- Parameters:
- functionCallable
- observable_dictFunctionDict, optional
FunctionDict for
function
- set_sampling(sample_block_size: int, function: Callable | None = None, max_sample_iterations: int = 100, sampling_dict: dict | None = None)
Compute the objective function using simulated sampling.
Samples are taken in blocks of sample_block_size. These are passed as a list of lists to
function(a Sampling Function), which returns a value for expectation value/objective function and a boolean that indicates wether the sampled result should be passed to the classical optimiser.If
functionisNone, the objective function is computed as the mean ofsample_block_sizeshots.- Parameters:
- sample_block_sizeint
number of shots taken between successive computation of the expectation value/objective function
- functioncallable, optional
- max_sample_iterationsint, optional
maximum number of sample blocks per computation of the expectation value/objective function, overrides the boolean returned by
function, by default 100- sampling_dictFunctionDict, optional
FunctionDict for the Sampling 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
- unset_sampling()
Revert to simulation using exact computation of the objective function.
multivariable
Predefined QVAs for the optimisation of continuous multivariable functions.
Note
The following compatible Operator Functions may
be imported from the multivariable :
setup_cartesian()cartesian()cartesian_scaled()
- class quop_mpi.algorithm.multivariable.qmoa(Ns: list[int], MPI_COMM: mpi4py.MPI.Intracomm = mpi4py.MPI.COMM_WORLD)
Simulate the QMOA.
A QVA for the optimisation of continuous multivariable functions.
- Parameters:
- Nslist[int]
the number of grid points in each each coordinate dimension
- MPI_communicatorIntracomm, optional
MPI Intracomm, by default MPI.COMM_WORLD
- benchmark(ansatz_depths: iterable[int], repeats: int, initial_parameters: list[float] | np.ndarray[float] = None, param_persist: bool = False, verbose: bool = True, filename: str = None, label: str = 'test', save_action: str = 'a', time_limit: int = None, suspend_path: str = None)
A method by which to study how a QVA performs as the number of ansatz iterations<ansatz depth> increases.
- Parameters:
- ansatz_depthsiterable[int]
integers specifying a sequence of ansatz depths<ansatz depth>
- repeatsint
number of repeats at each ansatz depth
- initial_parameters: list[float] or ndarray[float], optional
** Must be defined if a parameter mapping function is set. ** initial variational parameter values, if not present these are generated using the default parameter generation methods of the ansatz unitaries.
- param_persistbool, optional
if True the optimised variational parameter values which achieved the lowest objective function value for all repeats at ansatz_depth will be used as starting parameters for the first ansatz_depth * total_params at ansatz_depth += 1. if a parameter map is set, the initial parameters will update whenever the objective function reaches a new minimum.
- verbosebool, optional
if True, print current the ansatz depth, repeat number and optimisation results (default True)
- filenamestr or None, optional
name of *.h5 file in which to save the optimised system state and observables
- labelstr, optional
if filename is not None, *.h5 data will be saved as “filename/label_depth_repeat” (default “test”)
- save_action{‘a’, ‘w’}, optional
action taken during first file write: ‘a’ to append, ‘w’ to overwrite (default ‘a’)
- time_limitint or None, optional
total allocated in-program time in seconds; if exceeded, the benchmark is suspended
- suspend_pathstr or None, optional
path to the suspend file if time_limit is not None
- 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
- grid_point_from_index(index: int) np.ndarray[np.float64]
Retrieve the corresponding coordinate point from a global index of the system state.
- Parameters:
- indexint
global index of the system state
- Returns:
- ndarray[float64]
a 1-D real array containing a grid point in Cartesian coordinates
- 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
- save(file_name: str, config_name: str, action: str = 'a')
Write the final state, observables and results summary to a HDf5 file.
- Parameters:
- file_namestr
file path to saved data
- config_namestr
simulation identifier
- action{‘a’, ‘w’}, optional
‘a’ to append or ‘w’ to overwrite, by default ‘a’
Notes
Data is saved into a
*.h5file with the following structure.├── config_name ├── final_state ├── observablesThe minimization result is saved in the ‘minimize_result’ attribute of ‘config_name’ as a formatted string.
Multiple configurations with a unique config_name can be stored in the same .h5 file. HDF5 files are supported in python by the h5py package. With it, a saved configuration can be accessed as follows:
import h5py config_name = "my_simulation" f = h5py.File(file_name + ".h5", "r") final_state = np.array(f[config_name]['final_state']).view(np.complex128) eigenvalues = np.array(f[config_name]['eigenvalues']).view(np.complex128) observables = np.array(f[config_name]['observables']).view(np.float64) print(f["my_simulation"].attrs["minimize_result"])
Warning
The
"final_state"and"observables"datasets are saved using Fortran subroutines which make use of parallel HDF5.The complex values of the final_state array are saved as a compound datatype consisting of contiguous double precision reals. This is equivalent to the np.complex128 NumPy datatype. To access this data without a loss of precision in python, the user must set the view of the NumPy array to np.complex128, rather than casting it to np.complex128 using the dtype keyword.
Similarly, the observables array, which is saved as an array of double-precision reals, should have its view set to np.float64.
- set_depth(depth: int)
Set the simulated ansatz depth.
- Parameters:
- depthint
number of ansatz iterations
- set_independent_t(independent: bool)
Specify simulation with or without independent unitary parameters (walk times) over each coordinate dimension.
- Parameters:
- independentbool
simulate a unique walk time in each coordinate dimension if
True, all walk times share the same value ifFalse
- 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_log(filename: str, label: str, action: str = 'a')
Creates a CSV in which to save simulation results after a call to
execute().- Parameters:
- filenamestr
path to the log file
- labelstr
simulation identifier
- action{‘a’, ‘w’}, optional
‘a’ to append or ‘w’ overwrite, by default ‘a’
- set_mixer(Cs: list[int])
Set the circulant mixing unitary operator in each coordinate dimension.
- Parameters:
- Cslist[int]
specifies the “i-th” symmetric circulant matrix with edges weights
1,Cs[j] == 1cycle graph,Cs[j] > system_size // 2complete graph
See also
quop_mpi.propagator.composite.ith()
- 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 the
set_observables()whose exponent contains the observable vector.- observables_dict: FunctionDict, 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_parallel_jacobian(nodes_per_subcomm: int, processes_per_node: int, maxcomm: int, method: str | Callable = 'forward', h: float | None = None)
Specify optimisation of the variational parameters using parallel computation of the jacobian.
This creates MPI subcommunicators containing duplicates of the
Ansatzinstance which return partial derivative information to the root MPI process during optimisation.- Parameters:
- nodes_per_subcommint
MPI nodes per subcommunicator
- processes_per_nodeint
MPI processors associated with each node
- maxcommint
maximum number of created MPI subcommunicators (and
Ansatzinstance duplicates) if nodes_per_subcomm > 1, or the maximum number of MPI subcommunicators per node if nodes_per_subcomm = 1- method :{‘forward’, ‘central’} or callable, optional
‘forward’ or ‘central’ to used the forward difference or central difference method for numerical approximation of the partial derivatives, or a QuOp Jacobian Function, by default ‘forward’
- hfloat, optional
step-size used by the forward or central difference methods, by default
np.sqrt(np.finfo(float).eps)
- set_parameter_map(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:
- 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_params(param_function: Callable, param_dict: dict | None = None)
Define the Parameter Function for the phase-shift and mixing unitaries.
- Parameters:
- param_functionCallable
- param_dictFunctionDict
FunctionDict for
param_function
- set_qualities(function: Callable, operator_dict: dict | None = None)
Define the observables and phase-shift unitary operator
- Parameters:
- functionCallable
- operator_dictFunctionDict, optional
FunctionDict for
function
- set_sampling(sample_block_size: int, function: Callable | None = None, max_sample_iterations: int = 100, sampling_dict: dict | None = None)
Compute the objective function using simulated sampling.
Samples are taken in blocks of sample_block_size. These are passed as a list of lists to
function(a Sampling Function), which returns a value for expectation value/objective function and a boolean that indicates wether the sampled result should be passed to the classical optimiser.If
functionisNone, the objective function is computed as the mean ofsample_block_sizeshots.- Parameters:
- sample_block_sizeint
number of shots taken between successive computation of the expectation value/objective function
- functioncallable, optional
- max_sample_iterationsint, optional
maximum number of sample blocks per computation of the expectation value/objective function, overrides the boolean returned by
function, by default 100- sampling_dictFunctionDict, optional
FunctionDict for the Sampling 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
- unset_sampling()
Revert to simulation using exact computation of the objective function.
- class quop_mpi.algorithm.multivariable.qowe(Ns: list[int], deltas: list[float], mins: list[float], MPI_COMM: mpi4py.MPI.Intracomm = mpi4py.MPI.COMM_WORLD)
- benchmark(ansatz_depths: iterable[int], repeats: int, initial_parameters: list[float] | np.ndarray[float] = None, param_persist: bool = False, verbose: bool = True, filename: str = None, label: str = 'test', save_action: str = 'a', time_limit: int = None, suspend_path: str = None)
A method by which to study how a QVA performs as the number of ansatz iterations<ansatz depth> increases.
- Parameters:
- ansatz_depthsiterable[int]
integers specifying a sequence of ansatz depths<ansatz depth>
- repeatsint
number of repeats at each ansatz depth
- initial_parameters: list[float] or ndarray[float], optional
** Must be defined if a parameter mapping function is set. ** initial variational parameter values, if not present these are generated using the default parameter generation methods of the ansatz unitaries.
- param_persistbool, optional
if True the optimised variational parameter values which achieved the lowest objective function value for all repeats at ansatz_depth will be used as starting parameters for the first ansatz_depth * total_params at ansatz_depth += 1. if a parameter map is set, the initial parameters will update whenever the objective function reaches a new minimum.
- verbosebool, optional
if True, print current the ansatz depth, repeat number and optimisation results (default True)
- filenamestr or None, optional
name of *.h5 file in which to save the optimised system state and observables
- labelstr, optional
if filename is not None, *.h5 data will be saved as “filename/label_depth_repeat” (default “test”)
- save_action{‘a’, ‘w’}, optional
action taken during first file write: ‘a’ to append, ‘w’ to overwrite (default ‘a’)
- time_limitint or None, optional
total allocated in-program time in seconds; if exceeded, the benchmark is suspended
- suspend_pathstr or None, optional
path to the suspend file if time_limit is not None
- 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
- grid_point_from_index(index: int) np.ndarray[np.float64]
Retrieve the corresponding coordinate point from a global index of the system state.
- Parameters:
- indexint
global index of the system state
- Returns:
- ndarray[float64]
a 1-D real array containing a grid point in Cartesian coordinates
- 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
- save(file_name: str, config_name: str, action: str = 'a')
Write the final state, observables and results summary to a HDf5 file.
- Parameters:
- file_namestr
file path to saved data
- config_namestr
simulation identifier
- action{‘a’, ‘w’}, optional
‘a’ to append or ‘w’ to overwrite, by default ‘a’
Notes
Data is saved into a
*.h5file with the following structure.├── config_name ├── final_state ├── observablesThe minimization result is saved in the ‘minimize_result’ attribute of ‘config_name’ as a formatted string.
Multiple configurations with a unique config_name can be stored in the same .h5 file. HDF5 files are supported in python by the h5py package. With it, a saved configuration can be accessed as follows:
import h5py config_name = "my_simulation" f = h5py.File(file_name + ".h5", "r") final_state = np.array(f[config_name]['final_state']).view(np.complex128) eigenvalues = np.array(f[config_name]['eigenvalues']).view(np.complex128) observables = np.array(f[config_name]['observables']).view(np.float64) print(f["my_simulation"].attrs["minimize_result"])
Warning
The
"final_state"and"observables"datasets are saved using Fortran subroutines which make use of parallel HDF5.The complex values of the final_state array are saved as a compound datatype consisting of contiguous double precision reals. This is equivalent to the np.complex128 NumPy datatype. To access this data without a loss of precision in python, the user must set the view of the NumPy array to np.complex128, rather than casting it to np.complex128 using the dtype keyword.
Similarly, the observables array, which is saved as an array of double-precision reals, should have its view set to np.float64.
- set_depth(depth: int)
Set the simulated ansatz depth.
- Parameters:
- depthint
number of ansatz iterations
- set_independent_t(independent: bool)
Specify simulation with or without independent unitary parameters (walk times) over each coordinate dimension.
- Parameters:
- independentbool
simulate a unique walk time in each coordinate dimension if
True, all walk times share the same value ifFalse
- 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_log(filename: str, label: str, action: str = 'a')
Creates a CSV in which to save simulation results after a call to
execute().- Parameters:
- filenamestr
path to the log file
- labelstr
simulation identifier
- action{‘a’, ‘w’}, optional
‘a’ to append or ‘w’ overwrite, by default ‘a’
- 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 the
set_observables()whose exponent contains the observable vector.- observables_dict: FunctionDict, 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_parallel_jacobian(nodes_per_subcomm: int, processes_per_node: int, maxcomm: int, method: str | Callable = 'forward', h: float | None = None)
Specify optimisation of the variational parameters using parallel computation of the jacobian.
This creates MPI subcommunicators containing duplicates of the
Ansatzinstance which return partial derivative information to the root MPI process during optimisation.- Parameters:
- nodes_per_subcommint
MPI nodes per subcommunicator
- processes_per_nodeint
MPI processors associated with each node
- maxcommint
maximum number of created MPI subcommunicators (and
Ansatzinstance duplicates) if nodes_per_subcomm > 1, or the maximum number of MPI subcommunicators per node if nodes_per_subcomm = 1- method :{‘forward’, ‘central’} or callable, optional
‘forward’ or ‘central’ to used the forward difference or central difference method for numerical approximation of the partial derivatives, or a QuOp Jacobian Function, by default ‘forward’
- hfloat, optional
step-size used by the forward or central difference methods, by default
np.sqrt(np.finfo(float).eps)
- set_parameter_map(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:
- 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_params(param_function: Callable, param_dict: dict | None = None)
Define the Parameter Function for the phase-shift and mixing unitaries.
- Parameters:
- param_functionCallable
- param_dictFunctionDict
FunctionDict for
param_function
- set_qualities(function: Callable, operator_dict: dict | None = None)
Define the observables and phase-shift unitary operator
- Parameters:
- functionCallable
- operator_dictFunctionDict, optional
FunctionDict for
function
- set_sampling(sample_block_size: int, function: Callable | None = None, max_sample_iterations: int = 100, sampling_dict: dict | None = None)
Compute the objective function using simulated sampling.
Samples are taken in blocks of sample_block_size. These are passed as a list of lists to
function(a Sampling Function), which returns a value for expectation value/objective function and a boolean that indicates wether the sampled result should be passed to the classical optimiser.If
functionisNone, the objective function is computed as the mean ofsample_block_sizeshots.- Parameters:
- sample_block_sizeint
number of shots taken between successive computation of the expectation value/objective function
- functioncallable, optional
- max_sample_iterationsint, optional
maximum number of sample blocks per computation of the expectation value/objective function, overrides the boolean returned by
function, by default 100- sampling_dictFunctionDict, optional
FunctionDict for the Sampling 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
- unset_sampling()
Revert to simulation using exact computation of the objective function.
observable
Predefined Observable Functions.
See also: quop_mpi.Ansatz.set_observables().
- quop_mpi.observable.array(partition_table: list[int], MPI_COMM: Intracomm, array: list[float] | np.ndarray[float]) np.ndarray[np.float64]
Define observables with a NumPy ndarray.
An Observables Function. The
arrayargument must be passed toquop_mpi.Ansatz.set_observables()in a FunctionDict .- Parameters:
- partition_tablelist[int]
1-D array describing the global partitioning scheme,
quop_mpi.Ansatzattribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatzattribute- arrayUnion[list[float], ndarray[float]]
a 1-D real array containing system size observable values
- Returns:
- ndarray[float64]
local_iobservable values with global index offsetlocal_i_offset(seequop_mpi.Ansatz())
- quop_mpi.observable.csv(partition_table: list[int], MPI_COMM: Intracomm, *args, **kwargs) np.ndarray[np.float64]
Load observables from a
*.csvusing pandas.An Observables Function. The
filenameargument must be passed toquop_mpi.Ansatz.set_observables()in a FunctionDict. Additional keyword arguments in theFunctionDictare passed to the pandas.read_csv method.- Parameters:
- partition_tablelist[int]
1-D array describing the global partitioning scheme,
quop_mpi.Ansatzattribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatzattribute- filenamestr
path to a
*csvfile
- Returns:
- ndarray[float64]
local_iobservable values with global index offsetlocal_i_offset(seequop_mpi.Ansatz())
- quop_mpi.observable.hdf5(partition_table: list[int], MPI_COMM: Intracomm, filename: str, dataset_name: str, **kwargs) np.ndarray[np.float64]
Load observables from a
*.h5file using HDF5 for Python.An Observables Function. The
filenameanddataset_namearguments must be passed toquop_mpi.Ansatz.set_observables()in a FunctionDict. Additional positional and keyword arguments in theFunctionDictare passed to the h5py.File method.- Parameters:
- partition_tablelist[int]
1-D array describing the global partitioning scheme,
quop_mpi.Ansatzattribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatzattribute- filenamestr
path to a
*.h5file- dataset_namestr
path to the dataset in
filenamecontaining an ndarray[float64] of system size observables.
- Returns:
- ndarray[float64]
local_iobservable values with global index offsetlocal_i_offset(seequop_mpi.Ansatz())
- quop_mpi.observable.serial(partition_table: list[int], MPI_COMM: Intracomm, function: Callable, *args, **kwargs) np.ndarray[np.float64]
Generate observables using a serial python function.
- An Observables Function. The
functionargument must be passed to quop_mpi.Ansatz.set_observables()in a FunctionDict. Additional- positional and keyword arguments in the
FunctionDictare passed to function.
- Parameters:
- partition_tablelist[int]
- 1-D array describing the global partitioning scheme,
quop_mpi.Ansatzattribute
- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatzattribute- functionCallable
- Python function returning a 1-D real array of system size
observable values
- Returns:
- ndarray[float64]
local_iobservable values with global index offsetlocal_i_offset(seequop_mpi.Ansatz())
- An Observables Function. The
- quop_mpi.observable.rand.uniform(system_size: int, partition_table: list[int], seed: int, MPI_COMM: Intracomm, low: float = 0, high: float = 1) np.ndarray[np.float64]
Generate random observables from a uniform distribution.
An Observables Function. The
lowandhigharguments can be passed toquop_mpi.Ansatz.set_observables()in a FunctionDict.- Parameters:
- system_sizeint
the size of the simulated system, class:quop_mpi.Ansatz attribute
- partition_tablelist[int]
1-D array describing the global partitioning scheme,
quop_mpi.Ansatzattribute- seedint
sets the seed of the random number generator,
quop_mpi.Ansatzattribute- MPI_COMMIntracomm
MPI intracommunicator,
quop_mpi.Ansatzattribute- lowfloat, optional
lower bound of the generated observable values (inclusive), by default
0- highfloat, optional
upper bound of the genereated observable values (exclusive), by default
1
- Returns:
- np.ndarray[float64]
local_iobservable values with global index offsetlocal_i_offset(seequop_mpi.Ansatz())
param
Predefined Parameter Functions.
See quop_mpi.Unitary().
- quop_mpi.param.rand.uniform(n_params: int, seed: int, low: float = 0, high: float = 6.283185307179586) np.ndarray[np.float64]
Generate initial variational parameters from a uniform distribution.
The default Parameter Function of the
quop_mpi.Unitaryclass. User specifiedlowandhighvalues can be specified by passing a corresponding:term:FunctionDict to on initialisation of aunitaryinstance (seequop_mpi.Unitary()).- Parameters:
- n_paramsint
total number of unitary and operator variational parameters,
quop_mpi.Unitaryattribute- seedint
seeds random number generation,
quop_mpi.Unitaryattribute- lowfloat, optional
lower bound of the generated variational parameters (inclusive), by default
0- highfloat, optional
upper bound of the generated variational parameters (exclusive), by default
2*pi
- Returns:
- ndarray[float64]
a 1-D array of
n_paramsvariational parameters
state
Predefined Initial State Functions .
See set_initial_state().
- quop_mpi.state.array(local_i: int, local_i_offset: int, MPI_COMM: Intracomm, state: np.ndarray[np.complex128], normalize: bool = True) np.ndarray[np.complex128]
Define the initial state using a Numpy array.
An Initial State Function. The
normalizeargument can be specified by passing a FunctionDict toset_initial_state().- Parameters:
- local_iint
size of the local system state partitions,
quop_mpi.Ansatzattribute- local_i_offsetint
global index offset of the local system state partitions,
quop_mpi.Ansatzattribute- MPI_COMMIntracomm
MPI communicator of the QVA simulation,
quop_mpi.Ansatzattribute- statendarray[complex128]
A 1-D array of system size initial state values
- normalizebool, optional
wether to normalize
state, by default True
- Returns:
- ndarray[complex128]
1-D complex array of
local_iinitial state values with global index offsetlocal_i_offset(seequop_mpi.Ansatz)
- quop_mpi.state.basis(local_i: int, local_i_offset: int, basis_states: list[int] = None) np.ndarray[np.complex128]
Generate an equal superposition over a subset of basis states.
An Initial State Function. The
basis_statesargument can be specified by passing a FunctionDict toquop_mpi.Ansatz.set_initial_state().- Parameters:
- local_iint
size of the local system state partitions,
quop_mpi.Ansatzattribute- local_i_offsetint
global index offset of the local system state partitions,
quop_mpi.Ansatzattribute- basis_stateslist[int], optional
global indexes specifying an equal superposition over a subset of states, by default [0]
- Returns:
- ndarray[complex128]
1-D complex array of
local_iinitial state values with global index offsetlocal_i_offset(seequop_mpi.Ansatz)
- quop_mpi.state.equal(system_size: int, local_i: int) np.ndarray[np.complex128]
Generate an equal superposition over all system states.
The default Initial State Function of the
quop_mpi.Ansatzclass.- Parameters:
- system_sizeint
size of the simulated QVA,
quop_mpi.Ansatzattribute- local_iint
size of the local system state partitions,
quop_mpi.Ansatzattribute
- Returns:
- ndarray[complex128]
1-D complex array of
local_iinitial state values with global index offsetlocal_i_offset(seequop_mpi.Ansatz)
- quop_mpi.state.position_grid(alloc_local: int, local_i: int, local_i_offset: int, MPI_COMM: Intracomm, Ns: list[int], deltas: list[float], mins: list[float], function: Callable) np.ndarray[np.complex128]
Generate an initial state discrete Cartesian coordinates.
An Observables Function. Arguments
Ns,deltas,minsandfunctionmust be passed toquop_mpi.Ansatz.set_observables()in a FunctionDict.The
functionargument must take anlen(Ns)-dimensional coordinate and return the complex amplitude of the initial state at that coordinate.If
functionisNone,position_gridgenerates a squeezed Gaussian state with its mean situated at a randomly generated coordinate that has a distance of at leastlength * 0.125from the boundaries of the grid (wherelengthis the length in each coordinate).- Parameters:
- alloc_localint
size of the array containing the local partition of the system,
quop_mpi.Ansatzattribute- local_iint
number of initial state values in local partition of the system state,
quop_mpi.Ansatzattribute- local_i_offsetint
global index offset of the local system state partition,
quop_mpi.Ansatzattribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatzattribute- Nslist[int]
number of grid points in each dimension of the Cartesian grid
- deltaslist[float]
step size in each coordinate
- minslist[float]
minimum value in each coordinate
- functionCallable
a Python function returning the value of the initial state at each grid point
- Returns:
- ndarray[complex128]
1-D complex array of
local_iinitial state values with global index offsetlocal_i_offset(seequop_mpi.Ansatz)
- quop_mpi.state.serial(partition_table: list[int], MPI_COMM: Intracomm, function: Callable, *args, **kwargs) np.ndarray[np.complex128]
Generate the initial state using a serial Python function.
An Initial State Function. The
functionargument must be specified by passing a FunctionDict toset_initial_state(). Additional positional and keyword arguments in theFunctionDictare passed tofunction.- Parameters:
- partition_tablelist[int]
1-D array describing the global partitioning scheme,
quop_mpi.Ansatzattribute- MPI_COMMIntracomm
MPI communicator of the QVA simulation,
quop_mpi.Ansatzattribute- functionCallable
a Python function returning a 1-D complex array of system size initial state values
- Returns:
- ndarray[complex128]
1-D complex array of
local_iinitial state values with global index offsetlocal_i_offset(seequop_mpi.Ansatz)
meta
- class quop_mpi.meta.swarm(nodes_per_subcomm: int, processes_per_node: int, maxcomm: int, MPI_COMM: COMM_WORLD, alg: type, *args, **kwargs)
Create and operate on a swarm of identical
Ansatzinstances.Each
Ansatzinstance is associated with an MPI subcommunicator such that they can carry out QVA simulation independently.The
Ansatzinstance is initialised by theswarminstance as,Ansatz(*args, MPI_COMM, **kwargs)
- Parameters:
- nodes_per_subcommint
number of compute nodes associated with each
Ansatzsubcommunicator, ifnodes_per_subcomm == 1createmaxcommsubcommunicators per available compute node.- processes_per_nodeint
number of MPI processes per compute node, must be the same for all nodes
- maxcommint
target number of
Ansatzsubcommunicators- MPI_COMMIntracomm
MPI communicator from which to create the
Ansatzsubcommunicators- algAnsatz
an
Ansatz,quop_mpi.Ansatzor a predefined algorithm (seequop_mpi.algorithm)
- benchmark(*args, **kwargs)
Test QVA performance as a function of Ansatz Depth.
- Parameters:
- args: list[Ans] or list[list[Any]]
positional arguments for
quop_mpi.ansatz.benchmark(), or a list of positional arguments specifying unique input forquop_mpi.ansatz.benchmark()for eachAnsatzinstance.- kwargs: dict
keyword arguments for
quop_mpi.ansatz.benchmark(), or keywords pointing to a list of positional arguments specifying unique input forquop_mpi.ansatz.benchmark()for eachAnsatzinstance.
See also
- benchmark_swarm(ansatz_depths: Iterable[int], repeats: int, basename: str, param_persist: bool = True, verbose: bool = True, save_action: str = 'a', time_limit: float | None = None, logging: bool = True, suspend_path: str | None = None)
Test QVA performance with increasing ansatz depth with repeats at each depth computed in parallel over the
swarm.- Parameters:
- ansatz_depthsIterable[int]
simulated ansatz depths
- repeatsint
number of repeats at each ansatz depth
- basenamestr
path to directory in which to write simulation results and logs, by default
None- param_persistbool, optional
if
Truethe optimised variational parameter values which achieved the lowest objective function value for all repeats atansatz_depthwill be used as starting parameters for the firstansatz_depth * total_paramsatansatz_depth += 1, by defaultTrue- verbosebool, optional
if
True, print current the ansatz depth, repeat number and optimisation results, by defaultTrue- save_action{‘a’, ‘w’}
‘a’ to append, ‘w’ to (over)write, by default “a”
- time_limitfloat, optional
time limit in seconds, program will suspend if the time remaining is less than the time taken by the last simulation, by default
None- loggingbool, optional
write simulation results to log files, by default
True- suspend_pathstr, optional
path to directory in which to write suspend data, by default
None
- Returns:
- list[dict]
optimisation results ordered by ansatz depth
- execute_swarm(param_lists: list[np.ndarray[np.float64]], basename: str, log_path: str = None, h5_path: str = None, labels: str | list[str] = None, save_action: str = 'a', time_limit: float = None, verbose: bool = True, suspend_path: str = None)
Parallel simulation of QVAs over a set of initial variational parameters.
- Parameters:
- param_listslist[np.ndarray[np.float64]]
list of 1-D real arrays containing initial variational parameters
- basenamestr
folder in which to store simulation results and suspend data unless otherwise specified, by default
None- log_pathstr, optional
folder in which to write simulation log files, by default
None- h5_pathstr, optional
folder in which to write simulation results, by default
None- labelsstr or list[str], optional
labels(s) for each simulation, by default
None- save_action{“a”, “w”}
“a” to append “w” to (over)write, by default
"a"- time_limitfloat, optional
suspend if the time remaining is less than the time taken by the last QVA simulation, by default
None- verbosebool, optional
print the simulation results and simulation progress, by default
True- suspend_pathstr, optional
folder in which to store suspend data, by default
None
- Returns:
- dict
a dictionary of optimisation results with keys
str(params_list[i])
- get_optimal_result() dict
Retrieve the result with the lowest objective function value out of the last set of simulations executed by the
swarm.- Returns:
- dict
simulation result
- save(*args, **kwargs)
Save simulation results.
- Parameters:
- args:
positional arguments for
quop_mpi.ansatz.save(), or a list of positional arguments specifying unique input forquop_mpi.ansatz.save()for eachAnsatzinstance.- kwargs:
keyword arguments for
quop_mpi.ansatz.save(), or keywords pointing to a list of positional arguments specifying unique input forquop_mpi.ansatz.save()for eachAnsatzinstance.
See also
- set_log(*args, **kwargs)
Log simulation information.
- Parameters:
- args: list[Any] or list[list[Any]]
positional arguments for
quop_mpi.ansatz.set_log(), or a list of positional arguments specifying unique input forquop_mpi.ansatz.set_log()for eachAnsatzinstance.- kwargs: dict
keyword arguments for
quop_mpi.ansatz.set_log(), or keywords pointing to a list of positional arguments specifying unique input forquop_mpi.ansatz.set_log()for eachAnsatzinstance.
See also
- set_unitaries(unitaries: list[Unitary] | list[list[Unitary]])
Set the unitaries of an
Ansatzswarm.- Parameters:
- unitaries :list[Unitary] or list[list[Unitary]]
a list of
unitaryinstances (broadcast to all swarm instances) or a list ofunitaryinstances for eachAnsatzinstance in theswarm
- Raises:
- RuntimeError
if
unitaries`is a list of lists that is not equal to the :literal:`swarmsize
propagator
Predefined unitary classes for simulation of the action of QVA
phase-shift and mixing
unitaries with compatible Operator Functions.
circulant
- class quop_mpi.propagator.circulant.unitary(*args, **kwargs)
operators
Predefined Operator Functions for
quop_mpi.propagator.circulant.unitary.
An Operator Function for 'circulant' unitary instances return a
local_i sized partition of the operator eigenvalues with global index offset
local_i_offset.
- quop_mpi.propagator.circulant.operator.complete(system_size: int) np.ndarray[np.float64]
Generate a parallel partition of the eigenvalues of a complete circulant graph with edge weightings
1.An Operator Function associated with
quop_mpi.propagator.circulant.unitary.- Parameters:
- system_sizeint
the size of the simulated QVA
- local_iint
size of the local system state partitions,
quop_mpi.Ansatzattribute- local_i_offsetint
global index offset of the local system state partitions,
quop_mpi.Ansatzattribute
- Returns:
- ndarray[complex128]
1-D complex array of
local_ieigenvalues with global index offsetlocal_i_offset
- quop_mpi.propagator.circulant.operator.graph(system_size: int, i: int = 1) np.ndarray[np.float64]
Generate the eigenvalues of the i-th symmetric circulant graph with edge weightings
1.An Operator Function associated with
quop_mpi.propagator.circulant.unitary.- Parameters:
- system_sizeint
the size of the simulated QVA
- local_iint
size of the local system state partitions,
quop_mpi.Ansatzattribute- local_i_offsetint
global index offset of the local system state partitions,
quop_mpi.Ansatzattribute- iint, optional
index of the graph (ordered by vertex degree),
1corresponds to a cycle graph andsystem_size // 2 + 1to a complete graph, by default1
- Returns:
- ndarray[complex128]
1-D complex array of
local_ieigenvalues with global index offsetlocal_i_offset
diagonal
- class quop_mpi.propagator.diagonal.unitary(*args, **kwargs)
Compute the action of a mixing unitary with a phase_shift operator or a sequence of mixing-unitaries with phase_shift operators (see the
unitary_n_paramsattribute below).Inheritance Diagram:
![digraph "sphinx-ext-graphviz" {
rankdir="LR";
node [fontsize="10"];
Unitary[label="quop_mpi.Unitary", shape="rectangle"];
unitary[label="quop_mpi.propagator.phase_shift.unitary", shape="rectangle"];
Unitary -> unitary;
}](_images/graphviz-f2be5656394a0471ede9fe3d96bf8000bc627002.png)
See
quop_mpi.Unitary.- Attributes:
- unitary_type
'phase_shift'- planner
false- unitary_n_params
Set on initialisation to
1or more. Ifunitary_n_parameters > 1, the Operator Function must return alist[csr_matrix]of lengthunitary_n_parameterscontainingcsr_matrixpartitions of oflocal_irows.
- propagate(gammas)
Simulation of the action of a :term`unitary`.
When implemented,
propagatecontains a call to a method (typically a contained in a complied Python extension module) that takes the class attributesinitial_state,final_stateandMPI_COMM, together with attributes describing the parallel partitioning scheme and variational parametersx, as input. The action of the unitary is computed in MPI parallel, with the computed result written tofinal_state.Warning
Not implemented by the base
Unitaryclass.- Parameters:
- xndarray[float64]
a 1-D real array of
n_paramsvariational parameters
Examples
def propagate(self, x): external_propagator( x, self.partition_table, self.initial_state, self.final_state, self.MPI_COMM )
operators
Predefined Operator Functions and related utility
for quop_mpi.propagator.diagonal.unitary.
An Operator Function for 'diagonal' unitary instances returns an
ndarray[float64] of size local_i, or a list[ndarray[float64]] with
local_i sized elements, which correspond to partition(s) of diagonal
operator(s) with global index offset local_i_offset.
If the Operator function returns list[ndarray[float64]], the unitary
instance must be initialised with unitary_n_parameters equal to the length
of returned list. The resulting unitary is then equivalent to a sequence of
phase-shift unitaries with independently
parameterised unitary parameters.
- quop_mpi.propagator.diagonal.operator.array(partition_table: list[int], MPI_COMM: Intracomm, array: np.ndarray[np.float64]) np.ndarray[np.float64]
Define the diagonal of the phase-shift unitary using a Numpy array.
An Operator Function for the
quop_mpi.propagate.diagonal.unitaryclass.Note
For memory efficiency,
arraycan be present as anndarray[float64]atMPI_COMM.rank == 0only andNoneat all other ranks inMPI_COMM.- Parameters:
- partition_tablelist[int]
describes the parallel partitioning scheme,
quop_mpi.Ansatzattribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatzattribute- arraynp.ndarray[np.float64]
a 1-D real array of size system size
- Returns:
- ndarray[float64]
a 1-D real array containing
local_ielements of the operator diagonal with global index offsetlocal_i_offset
- quop_mpi.propagator.diagonal.operator.cartesian(system_size: int, local_i: int, local_i_offset: int, Ns: list[int], deltas: list[float], mins: list[float], function: Callable, *args, **kwargs) np.ndarray[np.float64]
TODO:UPDATE Generate the diagonal of a phase-shift unitary operator using a Python function defined in discrete Cartesian coordinates.
An Observables Function. Depending on wether QVA simulation is defined using the
Ansatzclass directly or with a predefinedAnsatzsubclass from thealgorithmsubmodule, the following arguments must be defined in a corresponding FunctionDict on initialisation of theunitaryinstance:quop_mpi.Ansatz:Ns,deltas,minsandfunctionalgorithms in
quop_mpi.algorithm.combinatorial:Ns,deltas,minsandfunctionquop_mpi.algorithm.multivariable.qmoa:deltas,minsandfunctionquop_mpi.algorithm.multivariable.qowe:function
Additional positional and keyword arguments in the
FunctionDictare passed tofunction.The
functionargument must conform to the signature,def function(x: ndarray[float64], *args, *kwargs) -> float
where
xis a 1-D array containing alen(Ns)-dimensional grid point.- Parameters:
- system_sizeint
size of the simulated QVA
- local_iint
size of the local system state partition,
quop_mpi.Unitaryattribute- local_i_offsetint
global index offset of the local system state partition,
quop_mpi.Unitaryattribute- Nslist[int]
the number of qubits assigned to each dimension of the cartesian grid such that there is
2 ** Ns[d]grid points per dimensiond- deltaslist[float]
step size in each Cartesian coordinate
- minslist[float]
lower bound of each Cartesian coordinate
- functionCallable
a Python function that takes a list of
len(Ns)real coordinate values and returns afloat
- Returns:
- ndarray[float64]
a 1-D real array containing
local_ielements of the operator diagonal with global index offsetlocal_i_offset
See also
setup_cartesiancompute
deltasandminscartesian_scaledalternative to
cartesian, scalesfunctionbetween0and an upper bound.
- quop_mpi.propagator.diagonal.operator.cartesian_scaled(system_size: int, local_i: int, local_i_offset: int, MPI_COMM: Intracomm, Ns: list[int], deltas: list[float], mins: list[float], function: Callable, coeff: float, *args, **kwargs) np.ndarray[np.float64]
Generate the diagonal of a phase-shift unitary operator using a Python function defined in discrete Cartesian coordinates with the function scaled between
0andcoeff.An Observables Function. Depending on wether QVA simulation is defined using the
Ansatzclass directly or with a predefinedAnsatzsubclass from thealgorithmsubmodule, the following arguments must be defined in a corresponding FunctionDict on initialisation of theunitaryinstance:quop_mpi.Ansatz:Ns,deltas,mins,functionandcoeffalgorithms in
quop_mpi.algorithm.combinatorial:Ns,deltas,mins,functionandcoeffquop_mpi.algorithm.multivariable.qmoa:deltas,mins,functionandcoeffquop_mpi.algorithm.multivariable.qowe:functionandcoeff
Additional positional and keyword arguments in the
FunctionDictare passed tofunction.The
functionargument must conform to the signature,def function(x: ndarray[float64], *args, *kwargs) -> float
where
xis a 1-D array containing alen(Ns)-dimensional grid point.- Parameters:
- system_sizeint
size of the simulated QVA
- local_iint
size of the local system state partition,
quop_mpi.Unitaryattribute- local_i_offsetint
global index offset of the local system state partition,
quop_mpi.Unitaryattribute- Nslist[int]
the number of qubits assigned to each dimension of the cartesian grid such that there is
2 ** Ns[d]grid points per dimensiond- deltaslist[float]
step size in each Cartesian coordinate
- minslist[float]
lower bound of each Cartesian coordinate
- functionCallable
a Python function that takes a list of
len(Ns)real coordinate values and returns afloat- coefffloat
a positive real number, the upper bound of the scaling range
- Returns:
- ndarray[float64]
a 1-D real array containing
local_ielements of the operator diagonal with global index offsetlocal_i_offset
See also
setup_cartesiancompute
deltasandminscartesian_scaledalternative to
cartesian_scaled, does not scalefunction
- quop_mpi.propagator.diagonal.operator.csv(partition_table: list[int], MPI_COMM: Intracomm, filename: Callable, *args, **kwargs) np.ndarray[np.float64]
Load the diagonal of a phase-shift unitary using pandas.
An Operator Function for the
quop_mpi.propagate.diagonal.unitaryclass. Thefilenameargument must be defined in a corresponding FunctionDict on initialisation of theunitaryinstance. Additional keyword arguments in theFunctionDictare passed to the pandas.read_csv method.- Parameters:
- partition_tablelist[int]
describes the parallel partitioning scheme,
quop_mpi.Ansatzattribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatzattribute- filenameCallable
path to a
*.csvfile
- Returns:
- ndarray[float64]
a 1-D real array containing
local_ielements of the operator diagonal with global index offsetlocal_i_offset
- quop_mpi.propagator.diagonal.operator.hdf5(partition_table: int, MPI_COMM: Intracomm, filename: str, dataset_name: str) np.ndarray[np.float64]
Load the diagonal of a phase-shift unitary using HDF5 for Python.
An Operator Function for the
quop_mpi.propagate.diagonal.unitaryclass. Thefilenameanddataset_namearguments must be defined in a corresponding FunctionDict on initialisation of theunitaryinstance. Additional positional and keyword arguments in theFunctionDictare passed to the h5py.File method.- Parameters:
- partition_tableint
describes the parallel partitioning scheme,
quop_mpi.Ansatzattribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatzattribute- filenamestr
path to a
*.h5 file- dataset_namestr
path to the dataset containing a
ndarray[float64]of size system size
- Returns:
- np.ndarray[np.float64]
a 1-D real array containing
local_ielements of the operator diagonal with global index offsetlocal_i_offset
- quop_mpi.propagator.diagonal.operator.serial(partition_table: list[int], MPI_COMM: Intracomm, variational_parameters: np.ndarray[np.float64], function: Callable, *args, **kwargs) np.ndarray[np.float64] | list[np.ndarray[np.float64]]
Generate the diagonal of the operator for one or more sequential phase-shift unitaries using a serial Python function.
An Operator Function for the
quop_mpi.propagator.diagonal.unitaryclass. Thefunctionargument must be defined in a corresponding FunctionDict on initialisation of theunitaryinstance. Additional positional and keyword arguments contained in the FunctionDict are passed tofunction.The
functionargument must conform to the signature,def function(*args, *kwargs) -> (ndarray[float64] | list[ndarray[float64]])
where the output is a 1-D real array of type
ndarray[float64]and length system size, orlistcontaining one or more 1-D real arrays of typendarray[float64]and lengthsystem_size.- Parameters:
- partition_tablelist[int]
describes the parallel partitioning scheme,
quop_mpi.Ansatzattribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatzattribute- variational_parametersndarray[float64]
operator parameters, passed to
functionifunitary.operator_n_params > 0,quop_mpi.Unitaryattribute- functionCallable
returns one or more
ndarray[float64]of size system size corresponding to the diagonal of the operator of one or more phase-shift unitaries
- Returns:
- ndarray[float64] or list[ndarray[float64]]
a 1-d real array or list of 1-D real arrays containing a
local_ielements of the operator diagonal with global index offsetlocal_i_offset
- quop_mpi.propagator.diagonal.operator.setup_cartesian(Ns: list[int], bounds: list[list[float]]) list[list[float]]
Compute the step-size and minimum coordinate values in each dimension of a Cartesian grid.
- Parameters:
- Nslist[int]
the number of qubits assigned to each dimension of the Cartesian grid such that there is
2 ** Ns[d]grid points per dimensiond- boundslist[list[float]]
the lower and upper bounds of each dimension where
len(Ns) == len(bounds)
- Returns:
- list[list[float]]
the step-size,
deltas, and the minimum,mins, in each Cartesian coordinate
See also
sparse
- class quop_mpi.propagator.sparse.unitary(*args, **kwargs)
Compute the action of a mixing unitary with a sparse operator or a sequence of mixing-unitaries with sparse operators (see the
unitary_n_paramsattribute below).Inheritance Diagram:
![digraph "sphinx-ext-graphviz" {
rankdir="LR";
node [fontsize="10"];
Unitary[label="quop_mpi.Unitary", shape="rectangle"];
unitary[label="quop_mpi.propagator.sparse.unitary", shape="rectangle"];
Unitary -> unitary;
}](_images/graphviz-7b00c6df2ff9e202effea730ff4e3b917991da58.png)
See
quop_mpi.Unitary.- Attributes:
- unitary_type
'sparse'- planner
false- unitary_n_params
Set on initialisation to
1or more. Ifunitary_n_parameters > 1, the Operator Function must return alist[csr_matrix]of lengthunitary_n_parameterscontainingcsr_matrixpartitions of oflocal_irows.
- propagate(ts)
Simulation of the action of a :term`unitary`.
When implemented,
propagatecontains a call to a method (typically a contained in a complied Python extension module) that takes the class attributesinitial_state,final_stateandMPI_COMM, together with attributes describing the parallel partitioning scheme and variational parametersx, as input. The action of the unitary is computed in MPI parallel, with the computed result written tofinal_state.Warning
Not implemented by the base
Unitaryclass.- Parameters:
- xndarray[float64]
a 1-D real array of
n_paramsvariational parameters
Examples
def propagate(self, x): external_propagator( x, self.partition_table, self.initial_state, self.final_state, self.MPI_COMM )
operators
Predefined Operator Functions for
quop_mpi.propagator.sparse.unitary.
Operator Functions for unitary instances of type 'sparse' return CSR
partitions of one or more matrices. More than one CSR partition defines a
sequence of mixing unitaries with independent
unitary parameters.
Partitioned CSR Matrix Format
- lb
lower index of the system state and observables partition,
quop_mpi.Unitaryattribute- ub
upper index of the system state and observables partition,
quop_mpi.Unitaryattribute- W_col_index
a 1-D integer array containing non-zero column indexes for rows
lbtoub, grouped by ascending row index- W_values
a 1-D real array containing non-zero values for rows
lbtoub, grouped by ascending row index in the same order asW_col_index- W_row_start
an 1-D integer array of length
ub - lb + 1, a cumulative sum of the number of non-zero elements in each row such thatW_row_start[row_index + 1] - W_row_start[row_index]is equal to the number of non-zero elements in the row with indexrow_indexandW_rows_start[row] - local_i_offsetgives the local starting index for the non-zero column indexes and values inW_col_indexandW_valuesfor the row with indexrow_index
These are returned by the Operator Function as
list[list[W_row_start], list[W_col_indexes], list[W_values]].
- quop_mpi.propagator.sparse.operator.hypercube(system_size: int, lb: int, ub: int) list[list[np.ndarray[np.int64]], list[np.ndarray[np.int64], list[np.ndarray[np.float64]]]]
Generate a hypercube (QAOA) sparse mixing unitary operator.
An Operator Function for
quop_mpi.propagator.sparse.unitary.- Parameters:
- system_sizeint
size of the simulated QVA,
quop_mpi.Unitaryattribute- lbint
lower index of the system state partition,
quop_mpi.Unitaryattribute- ubint
upper index of the system state partition,
quop_mpi.Unitaryattribute
- Returns:
- list[list[np.ndarray[np.int64]], list[np.ndarray[np.int64], list[np.ndarray[np.float64]]]]
a CSR partition of the hypercube (QAOA) mixing operator
- Raises:
- RuntimeError
if
system_size % 2 != 0
- quop_mpi.propagator.sparse.operator.serial(partition_table: list[int], MPI_COMM: Intracomm, variational_parameters: np.ndarray[np.float64], function: Callable, *args, **kwargs) list[list[np.ndarray[np.int64]], list[np.ndarray[np.int64], list[np.ndarray[np.float64]]]]
Generate an operator for a sparse mixing unitary using a serial Python function.
An Operator Function for
quop_mpi.propagator.sparse.unitary. Thefunctionargument must be defined via a corresponding FunctionDict on initialisation of theunitaryinstance. Additional positional and keyword arguments in theFunctionDictare passed thefunction. The signature for afunctiongenerating an operator with one or more operator parameters is,def function(variational_parameters, *args, **kwargs) -> list[csr_matrix]
where
variational_parametersmay be excluded ifunitary.operator_n_params = 0.- Parameters:
- partition_tablelist[int]
describes the parallel partitioning of the observables and system state,
quop_mpi.Unitaryattribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Unitaryattribute- variational_parametersnp.ndarray[np.float64]
a 1-D real array of operator parameters, passed to
functioniflen(variational_parameters) > 0,quop_mpi.Unitaryattribute- functionCallable
function returning a list of scipy CSR matrices
- Returns:
- list[list[np.ndarray[np.int64]], list[np.ndarray[np.int64],
- list[np.ndarray[np.float64]]]]
a CSR matrix partition
- Raises:
- TypeError
if
functiondoes not return alistof scipy CSR matrices
composite
- class quop_mpi.propagator.composite.unitary(Ns, *args, **kwargs)
- propagate(t)
Simulation of the action of a :term`unitary`.
When implemented,
propagatecontains a call to a method (typically a contained in a complied Python extension module) that takes the class attributesinitial_state,final_stateandMPI_COMM, together with attributes describing the parallel partitioning scheme and variational parametersx, as input. The action of the unitary is computed in MPI parallel, with the computed result written tofinal_state.Warning
Not implemented by the base
Unitaryclass.- Parameters:
- xndarray[float64]
a 1-D real array of
n_paramsvariational parameters
Examples
def propagate(self, x): external_propagator( x, self.partition_table, self.initial_state, self.final_state, self.MPI_COMM )
operators
- quop_mpi.propagator.composite.operator.ith(Ns: list[int], Cs: list[int] = None) np.ndarray[np.float64]
Generate the eigenvalues of a QMOA mixing unitary operator.
An Operator Function for
quop_mpi.propagator.composite.unitary. TheCskeyword argument may be defined via a corresponding FunctionDict on initialisation of the receivingunitaryinstance.- Parameters:
- Nslist[int]
the number of grid points in each dimension of the Cartesian grid,
quop_mpi.propagator.composite.unitaryattribute- Cslist[int], optional
specifies the i-th index of the circulant operators associated with each dimension of the Cartesian grid, complete graphs by default
- Returns:
- ndarray[complex128]
a 2-D complex array containing
local_ieigenvalues of the QMOA mixing unitary with global index offsetlocal_i_offset
See also
quop_mpi.propagate.circulant.operator.graph()Generate the eigenvalues of the i-th symmetric circulant graph with edge weights
1.
momentum
- class quop_mpi.propagator.momentum.unitary(Ns: list[int], minsq: list[float], minsk: list[float], deltasq: list[float], deltask: list[float], *args, **kwargs)
Implements the QOWE mixing unitary.
Warning
unitaryinstances of type'momentumrequire that thesizeof the MPI communicator assocaited withquop_mpi.Ansatzclass be a factor of the first grid dimension (Ns[0] % size == 0).Inhertance Diagram:
![digraph "sphinx-ext-graphviz" {
rankdir="LR"; node [fontsize="10"];
Unitary[label="quop_mpi.Unitary", shape="rectangle"];
unitary[label="quop_mpi.propagator.momentum.unitary",
shape="rectangle"];
Unitary -> unitary;
}](_images/graphviz-4199047a2f9e9ff693e56fb78eeaeaf0e366f623.png)
See
quop_mpi.Unitary.- Parameters:
- Nslist[int]
the number of grid points in each dimension of the Cartesian grid in position and momentum space
- minsqlist[float]
the minimum of each Cartesian coordinate in position space
- minsklist[float]
the minimum of each Cartesian coordinate in momentum space
- deltasqlist[float]
the step-size in each Cartesian coordinate in position space
- deltasklist[float]
the step-size in each Cartesian coordinate in momentum space
- *args and **kwargs:
passed to the initialisation method of
quop_mpi.Unitary
- Attributes:
- unitary_type
'momentum'- planner
True- unitary_n_params
len(Ns)
- propagate(x)
Simulation of the action of a :term`unitary`.
When implemented,
propagatecontains a call to a method (typically a contained in a complied Python extension module) that takes the class attributesinitial_state,final_stateandMPI_COMM, together with attributes describing the parallel partitioning scheme and variational parametersx, as input. The action of the unitary is computed in MPI parallel, with the computed result written tofinal_state.Warning
Not implemented by the base
Unitaryclass.- Parameters:
- xndarray[float64]
a 1-D real array of
n_paramsvariational parameters
Examples
def propagate(self, x): external_propagator( x, self.partition_table, self.initial_state, self.final_state, self.MPI_COMM )
operators
- quop_mpi.propagator.momentum.operator.magnitude_squared(Ns: list[int], minsk: list[float], deltask: list[float]) np.ndarray[np.complex128]
Generate the QMOA mixing unitary operator.
An Operator Function for
quop_mpi.propagator.momentum.unitary.- Parameters:
- Nslist[int]
the number of grid points in each dimension of the Cartesian grid in position and momentum space,
quop_mpi.propagator.momentum.unitaryattribute- minsklist[float]
the minimum of each Cartesian coordinate in momentum space,
quop_mpi.propagator.momentum.unitaryattribute- deltasklist[float]
the step-size in each Cartesian coordinate in momentum space,
quop_mpi.propagator.momentum.unitaryattribute
- Returns:
- np.ndarray[np.complex128]
a 1-D complex array of
local_ielements of the QOWE diagonal momentum-space operator with global index offsetlocal_i_offset
toolkit
Convieniance functions for use in user-defined Initial State and Observables functions.
- quop_mpi.toolkit.I(n_qubits: int) csr_matrix
Generate a sparse identity matrix of size
2 ** n_qubits.- Parameters:
- n_qubits: int
generate the identity operator for
n_qubits
- Returns:
- csr_matrix
the identity operator for
n_qubits
- quop_mpi.toolkit.X(index: int, n_qubits: int) csr_matrix
Generate the Pauli X operator acting on qubit
indexin a system ofn_qubits.- Parameters:
- indexint
index of the qubit to which the X operator is applied
- n_qubitsint
total number of qubits in the system
- Returns:
- csr_matrix
the Pauli X operator acting on qubit
indexin a system ofn_qubits
- quop_mpi.toolkit.Y(index: int, n_qubits: int) csr_matrix
Generate the Pauli Y operator acting on qubit
indexin a system ofn_qubits.- Parameters:
- indexint
index of the qubit to which the Y operator is applied
- n_qubitsint
total number of qubits in the system
- Returns:
- csr_matrix
the Pauli Y operator acting on qubit
indexin a system ofn_qubits
- quop_mpi.toolkit.Z(index: int, n_qubits: int)
Generate the Pauli Z operator acting on qubit
indexin a system ofn_qubits.- Parameters:
- indexint
index of the qubit to which the Z operator is applied
- n_qubitsint
total number of qubits in the system
- Returns:
- csr_matrix
the Pauli Z operator acting on qubit
indexin a system ofn_qubits
- quop_mpi.toolkit.kron(terms: list['sparse']) csr_matrix
Compute the tensor (Kronecker) product of a sequence of sparse matrices.
- Parameters:
- termslist[sparse]
a list of scipy sparse matrices
- Returns:
- csr_matrix
the tensor product of
terms, computed from left to right
- quop_mpi.toolkit.kron_power(term: sparse, n: int) csr_matrix
Compute the tensor (Kronecker) product of
ninstances of a sparse matrix.- Parameters:
- termsparse
a scipy sparse matrix
- nint
length of the tensor product sequence
- Returns:
- csr_matrix
tensor product of
noccurences ofterm
- quop_mpi.toolkit.string(state: str) np.ndarray[np.complex128]
Generate an initial state from a bit-string representation.
- Parameters:
- statestr
a bit string state.
- Returns:
- ndarray[complex128]
the parsed quantum state