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:
- 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_function
is 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_i
observables- 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_i
values, the initial system state- final_statendarray[complex128]
1-D array of
local_i
elements, 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, param_persist: bool = False, verbose: bool = True, filename: str | None = None, label: str = 'test', save_action: str = 'a', time_limit: int | None = None, suspend_path: str | None = None)
A method by which to study how a QVA performs as the number of ansatz iterations increases.
- Parameters:
- ansatz_depthsiterable[int]
integers specifying a sequence of ansatz depths
- repeatsint
number of repeats at each ansatz depth
- param_persistbool, optional
if
True
the optimised variational parameter values which achieved the lowest objective function value for all repeats atansatz_depth
will be used as starting parameters for the firstansatz_depth * total_params
atansatz_depth += 1
- verbosebool, optional
if
True
, print current the ansatz depth, repeat number and optimisation results by defaultTrue
- filenamestr or None, optional
name of
*.h5
file in which tosave()
the optimised system state and observables- labelstr, optional
if
filename
is notNone
,*.h5
data will be saved as “filename/label_depth_repeat”, by default"test"
- save_action{‘a’, ‘w’}, optional
action taken during first file write: ‘a’ to append, ‘w’ to overwrite, by default ‘a’
- time_limitint or None, optional
total allocated in-program time in seconds, if the time of the previous simulation exceeds the time remaining, the benchmark is suspended
- suspend_pathstr or None, optional
path to the suspend file if
time_limit
is notNone
- evaluate(variational_parameters: list[float] | np.ndarray[float]) float
Lazily computes the objective function value.
The
Ansatz
instance stores the last variational parameters passed toevaluate
and 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_parameters
isNone
, initial parameter values are generated using the Parameter Function of the correspondingunitary
instances.- 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
unitary
passed to theset_unitaries()
method.Note
If
ansatz_depth
isNone
the 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
Ansatz
MPI 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
Ansatz
subcommunicator,None
otherwise
- get_probabilities() np.ndarray[np.float64] | None
Gather probabilities computed from the final state at rank 0 of the
Ansatz
MPI 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
Ansatz
subcommunicator,None
otherwise
- 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
*.h5
file with the following structure.├── config_name ├── final_state ├── observables
The 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_free_params(function: Callable, free_params_dict: dict | None = None)
Optimise over a subset of the free variational parameters.
- Parameters:
- functioncallable
- free_params_dictdict, optional
FunctionDict for the Free Parameters Function
Examples
A Free Params Function that restricts optimisation to the last ansatz iteration:
def last_ansatz_iteration(total_params, ansatz_depth): return list( range((ansatz_depth - 1) * total_params, ansatz_depth * total_params) )
- 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_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
Ansatz
instance 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
Ansatz
instance 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_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
function
isNone
, the objective function is computed as the mean ofsample_block_size
shots.- 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
unitary
is derived from theUnitary
class and implements simulation of a specfic unitary through definition of the following methods:A list of
unitary
instances passed toquop_mpi.Ansatz.set_unitaries()
defines the ansatz unitary of a QVA. After initialisation,unitary
instances are managed by thequop_mpi.Ansatz
class and calls tounitary
methods are not made explicitly.See
quop_mpi.propagator
for predefinedunitary
subclasses.Associated QuOp Functions:
The following attributes are common to all
unitary
instances.- 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-plannerunitaries
andunitaries
that 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
unitary
type (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_params
is 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_i
otherwise). 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_plan
performs the same internal operations asplan()
using thelocal_i
andalloc_local
attributes ofex_unitary
. Does not return[local_i, alloc_local]
.Warning
Not implemented by the base
Unitary
class.- Parameters:
- ex_unitaryunitary
a
unitary
instance with computedlocal_i
andalloc_local
attributes
- 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
Unitary
class.
- plan(system_size: int, MPI_COMM: mpi4py.MPI.Intracomm)
Plan the partitioning scheme used by an
quop_mpi.Ansatz
instance and performs any other tasks required bypropagate()
.An implemented
plan
returns (local_i
,alloc_local
). Data structures and allocation required by the propagation method called inpropagate()
are assigned to attributes of theUnitary
instance.The
alloc_local
return value specifies the size of the local system state arraysinitial_state
andfinal_state
. In most casesalloc_local == local_i
, howeveralloc_local > local_i
may be required by particular external propagation methods (e.g. the parallel FFTW).Warning
Not implemented by the base
Unitary
class.- Parameters:
- system_sizeint
size of the simulated quantum system.
- MPI_COMMIntracomm
MPI communicator over which the
Ansatz
observables, 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_state
andfinal_state
arrays
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,
propagate
contains a call to a method (typically a contained in a complied Python extension module) that takes the class attributesinitial_state
,final_state
andMPI_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
Unitary
class.- Parameters:
- xndarray[float64]
a 1-D real array of
n_params
variational 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, param_persist: bool = False, verbose: bool = True, filename: str | None = None, label: str = 'test', save_action: str = 'a', time_limit: int | None = None, suspend_path: str | None = None)
A method by which to study how a QVA performs as the number of ansatz iterations increases.
- Parameters:
- ansatz_depthsiterable[int]
integers specifying a sequence of ansatz depths
- repeatsint
number of repeats at each ansatz depth
- param_persistbool, optional
if
True
the optimised variational parameter values which achieved the lowest objective function value for all repeats atansatz_depth
will be used as starting parameters for the firstansatz_depth * total_params
atansatz_depth += 1
- verbosebool, optional
if
True
, print current the ansatz depth, repeat number and optimisation results by defaultTrue
- filenamestr or None, optional
name of
*.h5
file in which tosave()
the optimised system state and observables- labelstr, optional
if
filename
is notNone
,*.h5
data will be saved as “filename/label_depth_repeat”, by default"test"
- save_action{‘a’, ‘w’}, optional
action taken during first file write: ‘a’ to append, ‘w’ to overwrite, by default ‘a’
- time_limitint or None, optional
total allocated in-program time in seconds, if the time of the previous simulation exceeds the time remaining, the benchmark is suspended
- suspend_pathstr or None, optional
path to the suspend file if
time_limit
is notNone
- evaluate(variational_parameters: list[float] | np.ndarray[float]) float
Lazily computes the objective function value.
The
Ansatz
instance stores the last variational parameters passed toevaluate
and 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_parameters
isNone
, initial parameter values are generated using the Parameter Function of the correspondingunitary
instances.- 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
unitary
passed to theset_unitaries()
method.Note
If
ansatz_depth
isNone
the 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
Ansatz
MPI 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
Ansatz
subcommunicator,None
otherwise
- get_probabilities() np.ndarray[np.float64] | None
Gather probabilities computed from the final state at rank 0 of the
Ansatz
MPI 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
Ansatz
subcommunicator,None
otherwise
- 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
*.h5
file with the following structure.├── config_name ├── final_state ├── observables
The 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_free_params(function: Callable, free_params_dict: dict | None = None)
Optimise over a subset of the free variational parameters.
- Parameters:
- functioncallable
- free_params_dictdict, optional
FunctionDict for the Free Parameters Function
Examples
A Free Params Function that restricts optimisation to the last ansatz iteration:
def last_ansatz_iteration(total_params, ansatz_depth): return list( range((ansatz_depth - 1) * total_params, ansatz_depth * total_params) )
- 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_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
Ansatz
instance 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
Ansatz
instance 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_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
function
isNone
, the objective function is computed as the mean ofsample_block_size
shots.- 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, param_persist: bool = False, verbose: bool = True, filename: str | None = None, label: str = 'test', save_action: str = 'a', time_limit: int | None = None, suspend_path: str | None = None)
A method by which to study how a QVA performs as the number of ansatz iterations increases.
- Parameters:
- ansatz_depthsiterable[int]
integers specifying a sequence of ansatz depths
- repeatsint
number of repeats at each ansatz depth
- param_persistbool, optional
if
True
the optimised variational parameter values which achieved the lowest objective function value for all repeats atansatz_depth
will be used as starting parameters for the firstansatz_depth * total_params
atansatz_depth += 1
- verbosebool, optional
if
True
, print current the ansatz depth, repeat number and optimisation results by defaultTrue
- filenamestr or None, optional
name of
*.h5
file in which tosave()
the optimised system state and observables- labelstr, optional
if
filename
is notNone
,*.h5
data will be saved as “filename/label_depth_repeat”, by default"test"
- save_action{‘a’, ‘w’}, optional
action taken during first file write: ‘a’ to append, ‘w’ to overwrite, by default ‘a’
- time_limitint or None, optional
total allocated in-program time in seconds, if the time of the previous simulation exceeds the time remaining, the benchmark is suspended
- suspend_pathstr or None, optional
path to the suspend file if
time_limit
is notNone
- evaluate(variational_parameters: list[float] | np.ndarray[float]) float
Lazily computes the objective function value.
The
Ansatz
instance stores the last variational parameters passed toevaluate
and 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_parameters
isNone
, initial parameter values are generated using the Parameter Function of the correspondingunitary
instances.- 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
unitary
passed to theset_unitaries()
method.Note
If
ansatz_depth
isNone
the 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
Ansatz
MPI 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
Ansatz
subcommunicator,None
otherwise
- get_probabilities() np.ndarray[np.float64] | None
Gather probabilities computed from the final state at rank 0 of the
Ansatz
MPI 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
Ansatz
subcommunicator,None
otherwise
- 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
*.h5
file with the following structure.├── config_name ├── final_state ├── observables
The 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_free_params(function: Callable, free_params_dict: dict | None = None)
Optimise over a subset of the free variational parameters.
- Parameters:
- functioncallable
- free_params_dictdict, optional
FunctionDict for the Free Parameters Function
Examples
A Free Params Function that restricts optimisation to the last ansatz iteration:
def last_ansatz_iteration(total_params, ansatz_depth): return list( range((ansatz_depth - 1) * total_params, ansatz_depth * total_params) )
- 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_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
Ansatz
instance 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
Ansatz
instance 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_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
function
isNone
, the objective function is computed as the mean ofsample_block_size
shots.- 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, param_persist: bool = False, verbose: bool = True, filename: str | None = None, label: str = 'test', save_action: str = 'a', time_limit: int | None = None, suspend_path: str | None = None)
A method by which to study how a QVA performs as the number of ansatz iterations increases.
- Parameters:
- ansatz_depthsiterable[int]
integers specifying a sequence of ansatz depths
- repeatsint
number of repeats at each ansatz depth
- param_persistbool, optional
if
True
the optimised variational parameter values which achieved the lowest objective function value for all repeats atansatz_depth
will be used as starting parameters for the firstansatz_depth * total_params
atansatz_depth += 1
- verbosebool, optional
if
True
, print current the ansatz depth, repeat number and optimisation results by defaultTrue
- filenamestr or None, optional
name of
*.h5
file in which tosave()
the optimised system state and observables- labelstr, optional
if
filename
is notNone
,*.h5
data will be saved as “filename/label_depth_repeat”, by default"test"
- save_action{‘a’, ‘w’}, optional
action taken during first file write: ‘a’ to append, ‘w’ to overwrite, by default ‘a’
- time_limitint or None, optional
total allocated in-program time in seconds, if the time of the previous simulation exceeds the time remaining, the benchmark is suspended
- suspend_pathstr or None, optional
path to the suspend file if
time_limit
is notNone
- evaluate(variational_parameters: list[float] | np.ndarray[float]) float
Lazily computes the objective function value.
The
Ansatz
instance stores the last variational parameters passed toevaluate
and 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_parameters
isNone
, initial parameter values are generated using the Parameter Function of the correspondingunitary
instances.- 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
unitary
passed to theset_unitaries()
method.Note
If
ansatz_depth
isNone
the 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
Ansatz
MPI 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
Ansatz
subcommunicator,None
otherwise
- get_probabilities() np.ndarray[np.float64] | None
Gather probabilities computed from the final state at rank 0 of the
Ansatz
MPI 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
Ansatz
subcommunicator,None
otherwise
- 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
*.h5
file with the following structure.├── config_name ├── final_state ├── observables
The 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_free_params(function: Callable, free_params_dict: dict | None = None)
Optimise over a subset of the free variational parameters.
- Parameters:
- functioncallable
- free_params_dictdict, optional
FunctionDict for the Free Parameters Function
Examples
A Free Params Function that restricts optimisation to the last ansatz iteration:
def last_ansatz_iteration(total_params, ansatz_depth): return list( range((ansatz_depth - 1) * total_params, ansatz_depth * total_params) )
- 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] == 1
cycle graph,Cs[j] > system_size // 2
complete graph
See also
quop_mpi.propagator.composite.ith()
- 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
Ansatz
instance 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
Ansatz
instance 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_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
function
isNone
, the objective function is computed as the mean ofsample_block_size
shots.- 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, param_persist: bool = False, verbose: bool = True, filename: str | None = None, label: str = 'test', save_action: str = 'a', time_limit: int | None = None, suspend_path: str | None = None)
A method by which to study how a QVA performs as the number of ansatz iterations increases.
- Parameters:
- ansatz_depthsiterable[int]
integers specifying a sequence of ansatz depths
- repeatsint
number of repeats at each ansatz depth
- param_persistbool, optional
if
True
the optimised variational parameter values which achieved the lowest objective function value for all repeats atansatz_depth
will be used as starting parameters for the firstansatz_depth * total_params
atansatz_depth += 1
- verbosebool, optional
if
True
, print current the ansatz depth, repeat number and optimisation results by defaultTrue
- filenamestr or None, optional
name of
*.h5
file in which tosave()
the optimised system state and observables- labelstr, optional
if
filename
is notNone
,*.h5
data will be saved as “filename/label_depth_repeat”, by default"test"
- save_action{‘a’, ‘w’}, optional
action taken during first file write: ‘a’ to append, ‘w’ to overwrite, by default ‘a’
- time_limitint or None, optional
total allocated in-program time in seconds, if the time of the previous simulation exceeds the time remaining, the benchmark is suspended
- suspend_pathstr or None, optional
path to the suspend file if
time_limit
is notNone
- evaluate(variational_parameters: list[float] | np.ndarray[float]) float
Lazily computes the objective function value.
The
Ansatz
instance stores the last variational parameters passed toevaluate
and 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_parameters
isNone
, initial parameter values are generated using the Parameter Function of the correspondingunitary
instances.- 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
unitary
passed to theset_unitaries()
method.Note
If
ansatz_depth
isNone
the 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
Ansatz
MPI 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
Ansatz
subcommunicator,None
otherwise
- get_probabilities() np.ndarray[np.float64] | None
Gather probabilities computed from the final state at rank 0 of the
Ansatz
MPI 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
Ansatz
subcommunicator,None
otherwise
- 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
*.h5
file with the following structure.├── config_name ├── final_state ├── observables
The 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_free_params(function: Callable, free_params_dict: dict | None = None)
Optimise over a subset of the free variational parameters.
- Parameters:
- functioncallable
- free_params_dictdict, optional
FunctionDict for the Free Parameters Function
Examples
A Free Params Function that restricts optimisation to the last ansatz iteration:
def last_ansatz_iteration(total_params, ansatz_depth): return list( range((ansatz_depth - 1) * total_params, ansatz_depth * total_params) )
- 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_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
Ansatz
instance 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
Ansatz
instance 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_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
function
isNone
, the objective function is computed as the mean ofsample_block_size
shots.- 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
array
argument 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.Ansatz
attribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatz
attribute- arrayUnion[list[float], ndarray[float]]
a 1-D real array containing system size observable values
- Returns:
- ndarray[float64]
local_i
observable 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
*.csv
using pandas.An Observables Function. The
filename
argument must be passed toquop_mpi.Ansatz.set_observables()
in a FunctionDict. Additional keyword arguments in theFunctionDict
are passed to the pandas.read_csv method.- Parameters:
- partition_tablelist[int]
1-D array describing the global partitioning scheme,
quop_mpi.Ansatz
attribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatz
attribute- filenamestr
path to a
*csv
file
- Returns:
- ndarray[float64]
local_i
observable 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
*.h5
file using HDF5 for Python.An Observables Function. The
filename
anddataset_name
arguments must be passed toquop_mpi.Ansatz.set_observables()
in a FunctionDict. Additional positional and keyword arguments in theFunctionDict
are passed to the h5py.File method.- Parameters:
- partition_tablelist[int]
1-D array describing the global partitioning scheme,
quop_mpi.Ansatz
attribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatz
attribute- filenamestr
path to a
*.h5
file- dataset_namestr
path to the dataset in
filename
containing an ndarray[float64] of system size observables.
- Returns:
- ndarray[float64]
local_i
observable 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
function
argument must be passed to quop_mpi.Ansatz.set_observables()
in a FunctionDict. Additional- positional and keyword arguments in the
FunctionDict
are passed to function
.
- Parameters:
- partition_tablelist[int]
- 1-D array describing the global partitioning scheme,
quop_mpi.Ansatz
attribute
- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatz
attribute- functionCallable
- Python function returning a 1-D real array of system size
observable values
- Returns:
- ndarray[float64]
local_i
observable 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
low
andhigh
arguments 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.Ansatz
attribute- seedint
sets the seed of the random number generator,
quop_mpi.Ansatz
attribute- MPI_COMMIntracomm
MPI intracommunicator,
quop_mpi.Ansatz
attribute- 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_i
observable 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.Unitary
class. User specifiedlow
andhigh
values can be specified by passing a corresponding:term:FunctionDict to on initialisation of aunitary
instance (seequop_mpi.Unitary()
).- Parameters:
- n_paramsint
total number of unitary and operator variational parameters,
quop_mpi.Unitary
attribute- seedint
seeds random number generation,
quop_mpi.Unitary
attribute- 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_params
variational 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
normalize
argument can be specified by passing a FunctionDict toset_initial_state()
.- Parameters:
- local_iint
size of the local system state partitions,
quop_mpi.Ansatz
attribute- local_i_offsetint
global index offset of the local system state partitions,
quop_mpi.Ansatz
attribute- MPI_COMMIntracomm
MPI communicator of the QVA simulation,
quop_mpi.Ansatz
attribute- 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_i
initial 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_states
argument 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.Ansatz
attribute- local_i_offsetint
global index offset of the local system state partitions,
quop_mpi.Ansatz
attribute- 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_i
initial 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.Ansatz
class.- Parameters:
- system_sizeint
size of the simulated QVA,
quop_mpi.Ansatz
attribute- local_iint
size of the local system state partitions,
quop_mpi.Ansatz
attribute
- Returns:
- ndarray[complex128]
1-D complex array of
local_i
initial 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
,mins
andfunction
must be passed toquop_mpi.Ansatz.set_observables()
in a FunctionDict.The
function
argument must take anlen(Ns)
-dimensional coordinate and return the complex amplitude of the initial state at that coordinate.If
function
isNone
,position_grid
generates a squeezed Gaussian state with its mean situated at a randomly generated coordinate that has a distance of at leastlength * 0.125
from the boundaries of the grid (wherelength
is the length in each coordinate).- Parameters:
- alloc_localint
size of the array containing the local partition of the system,
quop_mpi.Ansatz
attribute- local_iint
number of initial state values in local partition of the system state,
quop_mpi.Ansatz
attribute- local_i_offsetint
global index offset of the local system state partition,
quop_mpi.Ansatz
attribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatz
attribute- 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_i
initial 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
function
argument must be specified by passing a FunctionDict toset_initial_state()
. Additional positional and keyword arguments in theFunctionDict
are passed tofunction
.- Parameters:
- partition_tablelist[int]
1-D array describing the global partitioning scheme,
quop_mpi.Ansatz
attribute- MPI_COMMIntracomm
MPI communicator of the QVA simulation,
quop_mpi.Ansatz
attribute- 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_i
initial 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
Ansatz
instances.Each
Ansatz
instance is associated with an MPI subcommunicator such that they can carry out QVA simulation independently.The
Ansatz
instance is initialised by theswarm
instance as,Ansatz(*args, MPI_COMM, **kwargs)
- Parameters:
- nodes_per_subcommint
number of compute nodes associated with each
Ansatz
subcommunicator, ifnodes_per_subcomm == 1
createmaxcomm
subcommunicators 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
Ansatz
subcommunicators- MPI_COMMIntracomm
MPI communicator from which to create the
Ansatz
subcommunicators- algAnsatz
an
Ansatz
,quop_mpi.Ansatz
or 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 eachAnsatz
instance.- 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 eachAnsatz
instance.
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
True
the optimised variational parameter values which achieved the lowest objective function value for all repeats atansatz_depth
will be used as starting parameters for the firstansatz_depth * total_params
atansatz_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 eachAnsatz
instance.- 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 eachAnsatz
instance.
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 eachAnsatz
instance.- 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 eachAnsatz
instance.
See also
- set_unitaries(unitaries: list[Unitary] | list[list[Unitary]])
Set the unitaries of an
Ansatz
swarm.- Parameters:
- unitaries :list[Unitary] or list[list[Unitary]]
a list of
unitary
instances (broadcast to all swarm instances) or a list ofunitary
instances for eachAnsatz
instance in theswarm
- Raises:
- RuntimeError
if
unitaries`is a list of lists that is not equal to the :literal:`swarm
size
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.Ansatz
attribute- local_i_offsetint
global index offset of the local system state partitions,
quop_mpi.Ansatz
attribute
- Returns:
- ndarray[complex128]
1-D complex array of
local_i
eigenvalues 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.Ansatz
attribute- local_i_offsetint
global index offset of the local system state partitions,
quop_mpi.Ansatz
attribute- iint, optional
index of the graph (ordered by vertex degree),
1
corresponds to a cycle graph andsystem_size // 2 + 1
to a complete graph, by default1
- Returns:
- ndarray[complex128]
1-D complex array of
local_i
eigenvalues 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_params
attribute below).Inheritance Diagram:
See
quop_mpi.Unitary
.- Attributes:
- unitary_type
'phase_shift'
- planner
false
- unitary_n_params
Set on initialisation to
1
or more. Ifunitary_n_parameters > 1
, the Operator Function must return alist[csr_matrix]
of lengthunitary_n_parameters
containingcsr_matrix
partitions of oflocal_i
rows.
- propagate(gammas)
Simulation of the action of a :term`unitary`.
When implemented,
propagate
contains a call to a method (typically a contained in a complied Python extension module) that takes the class attributesinitial_state
,final_state
andMPI_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
Unitary
class.- Parameters:
- xndarray[float64]
a 1-D real array of
n_params
variational 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.unitary
class.Note
For memory efficiency,
array
can be present as anndarray[float64]
atMPI_COMM.rank == 0
only andNone
at all other ranks inMPI_COMM
.- Parameters:
- partition_tablelist[int]
describes the parallel partitioning scheme,
quop_mpi.Ansatz
attribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatz
attribute- arraynp.ndarray[np.float64]
a 1-D real array of size system size
- Returns:
- ndarray[float64]
a 1-D real array containing
local_i
elements 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
Ansatz
class directly or with a predefinedAnsatz
subclass from thealgorithm
submodule, the following arguments must be defined in a corresponding FunctionDict on initialisation of theunitary
instance:quop_mpi.Ansatz
:Ns
,deltas
,mins
andfunction
algorithms in
quop_mpi.algorithm.combinatorial
:Ns
,deltas
,mins
andfunction
quop_mpi.algorithm.multivariable.qmoa
:deltas
,mins
andfunction
quop_mpi.algorithm.multivariable.qowe
:function
Additional positional and keyword arguments in the
FunctionDict
are passed tofunction
.The
function
argument must conform to the signature,def function(x: ndarray[float64], *args, *kwargs) -> float
where
x
is 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.Unitary
attribute- local_i_offsetint
global index offset of the local system state partition,
quop_mpi.Unitary
attribute- 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_i
elements of the operator diagonal with global index offsetlocal_i_offset
See also
setup_cartesian
compute
deltas
andmins
cartesian_scaled
alternative to
cartesian
, scalesfunction
between0
and 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
0
andcoeff
.An Observables Function. Depending on wether QVA simulation is defined using the
Ansatz
class directly or with a predefinedAnsatz
subclass from thealgorithm
submodule, the following arguments must be defined in a corresponding FunctionDict on initialisation of theunitary
instance:quop_mpi.Ansatz
:Ns
,deltas
,mins
,function
andcoeff
algorithms in
quop_mpi.algorithm.combinatorial
:Ns
,deltas
,mins
,function
andcoeff
quop_mpi.algorithm.multivariable.qmoa
:deltas
,mins
,function
andcoeff
quop_mpi.algorithm.multivariable.qowe
:function
andcoeff
Additional positional and keyword arguments in the
FunctionDict
are passed tofunction
.The
function
argument must conform to the signature,def function(x: ndarray[float64], *args, *kwargs) -> float
where
x
is 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.Unitary
attribute- local_i_offsetint
global index offset of the local system state partition,
quop_mpi.Unitary
attribute- 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_i
elements of the operator diagonal with global index offsetlocal_i_offset
See also
setup_cartesian
compute
deltas
andmins
cartesian_scaled
alternative 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.unitary
class. Thefilename
argument must be defined in a corresponding FunctionDict on initialisation of theunitary
instance. Additional keyword arguments in theFunctionDict
are passed to the pandas.read_csv method.- Parameters:
- partition_tablelist[int]
describes the parallel partitioning scheme,
quop_mpi.Ansatz
attribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatz
attribute- filenameCallable
path to a
*.csv
file
- Returns:
- ndarray[float64]
a 1-D real array containing
local_i
elements 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.unitary
class. Thefilename
anddataset_name
arguments must be defined in a corresponding FunctionDict on initialisation of theunitary
instance. Additional positional and keyword arguments in theFunctionDict
are passed to the h5py.File method.- Parameters:
- partition_tableint
describes the parallel partitioning scheme,
quop_mpi.Ansatz
attribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatz
attribute- 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_i
elements 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.unitary
class. Thefunction
argument must be defined in a corresponding FunctionDict on initialisation of theunitary
instance. Additional positional and keyword arguments contained in the FunctionDict are passed tofunction
.The
function
argument 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, orlist
containing one or more 1-D real arrays of typendarray[float64]
and lengthsystem_size
.- Parameters:
- partition_tablelist[int]
describes the parallel partitioning scheme,
quop_mpi.Ansatz
attribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Ansatz
attribute- variational_parametersndarray[float64]
operator parameters, passed to
function
ifunitary.operator_n_params > 0
,quop_mpi.Unitary
attribute- 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_i
elements 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_params
attribute below).Inheritance Diagram:
See
quop_mpi.Unitary
.- Attributes:
- unitary_type
'sparse'
- planner
false
- unitary_n_params
Set on initialisation to
1
or more. Ifunitary_n_parameters > 1
, the Operator Function must return alist[csr_matrix]
of lengthunitary_n_parameters
containingcsr_matrix
partitions of oflocal_i
rows.
- propagate(ts)
Simulation of the action of a :term`unitary`.
When implemented,
propagate
contains a call to a method (typically a contained in a complied Python extension module) that takes the class attributesinitial_state
,final_state
andMPI_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
Unitary
class.- Parameters:
- xndarray[float64]
a 1-D real array of
n_params
variational 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.Unitary
attribute- ub
upper index of the system state and observables partition,
quop_mpi.Unitary
attribute- W_col_index
a 1-D integer array containing non-zero column indexes for rows
lb
toub
, grouped by ascending row index- W_values
a 1-D real array containing non-zero values for rows
lb
toub
, 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_index
andW_rows_start[row] - local_i_offset
gives the local starting index for the non-zero column indexes and values inW_col_index
andW_values
for 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.Unitary
attribute- lbint
lower index of the system state partition,
quop_mpi.Unitary
attribute- ubint
upper index of the system state partition,
quop_mpi.Unitary
attribute
- 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
. Thefunction
argument must be defined via a corresponding FunctionDict on initialisation of theunitary
instance. Additional positional and keyword arguments in theFunctionDict
are passed thefunction
. The signature for afunction
generating an operator with one or more operator parameters is,def function(variational_parameters, *args, **kwargs) -> list[csr_matrix]
where
variational_parameters
may be excluded ifunitary.operator_n_params = 0
.- Parameters:
- partition_tablelist[int]
describes the parallel partitioning of the observables and system state,
quop_mpi.Unitary
attribute- MPI_COMMIntracomm
MPI communicator,
quop_mpi.Unitary
attribute- variational_parametersnp.ndarray[np.float64]
a 1-D real array of operator parameters, passed to
function
iflen(variational_parameters) > 0
,quop_mpi.Unitary
attribute- 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
function
does not return alist
of 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,
propagate
contains a call to a method (typically a contained in a complied Python extension module) that takes the class attributesinitial_state
,final_state
andMPI_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
Unitary
class.- Parameters:
- xndarray[float64]
a 1-D real array of
n_params
variational 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
. TheCs
keyword argument may be defined via a corresponding FunctionDict on initialisation of the receivingunitary
instance.- Parameters:
- Nslist[int]
the number of grid points in each dimension of the Cartesian grid,
quop_mpi.propagator.composite.unitary
attribute- 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_i
eigenvalues 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
unitary
instances of type'momentum
require that thesize
of the MPI communicator assocaited withquop_mpi.Ansatz
class be a factor of the first grid dimension (Ns[0] % size == 0
).Inhertance Diagram:
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,
propagate
contains a call to a method (typically a contained in a complied Python extension module) that takes the class attributesinitial_state
,final_state
andMPI_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
Unitary
class.- Parameters:
- xndarray[float64]
a 1-D real array of
n_params
variational 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.unitary
attribute- minsklist[float]
the minimum of each Cartesian coordinate in momentum space,
quop_mpi.propagator.momentum.unitary
attribute- deltasklist[float]
the step-size in each Cartesian coordinate in momentum space,
quop_mpi.propagator.momentum.unitary
attribute
- Returns:
- np.ndarray[np.complex128]
a 1-D complex array of
local_i
elements 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
index
in 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
index
in a system ofn_qubits
- quop_mpi.toolkit.Y(index: int, n_qubits: int) csr_matrix
Generate the Pauli Y operator acting on qubit
index
in 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
index
in a system ofn_qubits
- quop_mpi.toolkit.Z(index: int, n_qubits: int)
Generate the Pauli Z operator acting on qubit
index
in 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
index
in 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
n
instances of a sparse matrix.- Parameters:
- termsparse
a scipy sparse matrix
- nint
length of the tensor product sequence
- Returns:
- csr_matrix
tensor product of
n
occurences 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