qnet_qsd package¶
Top-level package for QNET-QSD.
Summary¶
Exceptions:
QSDCodeGenError |
Exception raised for missing data in a QSDCodeGen instance |
Classes:
QSDCCodePrinter |
A printer for converting SymPy expressions to C++ code, while taking into account pre-defined variable names for symbols |
QSDCodeGen |
Class that allows to generate a QSD program for QNET expressions, and to run the program to (accumulative) collect expectation values for observables |
QSDOperator |
Encapsulation of a QSD (symbolic) Operator, containing all information required to instantiate that operator and to use it in C++ code expressions. |
Functions:
compilation_worker |
Worker to perform compilation, suitable e.g. |
expand_cmd |
Return a copy of the array cmd, where for each element of the cmd array, environment variables and ‘~’ are expanded |
find_kets |
Given a Ket instance, return the set of LocalKet instances contained in it. |
local_ops |
Given a symbolic expression, extract the set of “atomic” operators (instances of Operator ) occurring in that expression. |
qsd_run_worker |
Worker to perform run of a previously compiled program (see compilation_worker() ), suitable e.g. |
sanitize_name |
Return a sanitized name, where all letters that occur as keys in replacements are replaced by their corresponding values, and any letters that do not match allowed_letters are dropped |
Reference¶
-
class
qnet_qsd.
QSDCCodePrinter
(settings={})[source]¶ Bases:
sympy.printing.ccode.C89CodePrinter
A printer for converting SymPy expressions to C++ code, while taking into account pre-defined variable names for symbols
-
qnet_qsd.
local_ops
(expr)[source]¶ Given a symbolic expression, extract the set of “atomic” operators (instances of
Operator
) occurring in that expression. The set is “atomic” in the sense that the operators are not algebraic combinations of other operators.
-
qnet_qsd.
find_kets
(expr, cls=<class 'qnet.algebra.state_algebra.LocalKet'>)[source]¶ Given a
Ket
instance, return the set ofLocalKet
instances contained in it.
-
class
qnet_qsd.
QSDOperator
(qsd_type, name, instantiator)[source]¶ Bases:
object
Encapsulation of a QSD (symbolic) Operator, containing all information required to instantiate that operator and to use it in C++ code expressions.
All arguments set the corresponding properties.
Examples
>>> A0 = QSDOperator('AnnihilationOperator', 'A0', '(0)') >>> Ad0 = QSDOperator('Operator', 'Ad0', '= A0.hc()')
-
known_types
= ['AnnihilationOperator', 'FieldTransitionOperator', 'IdentityOperator', 'Operator']¶
-
qsd_type
¶ QSD object type, i.e., name of the C++ class. See
known_types
class attribute for allowed type names
-
name
¶ The name of the operator object. Must be a valid C++ variable name.
-
instantiator
¶ String that instantiates the operator object. This must either be the constructor arguments of the operator’s QSD class, or a C++ expression (starting with an equal sign) that initializes the object
-
instantiation
¶ Complete line of C++ code that instantiates the operator
Example
>>> A0 = QSDOperator('AnnihilationOperator', 'A0', '(0)') >>> print(A0.instantiation) AnnihilationOperator A0(0);
-
__iter__
()[source]¶ Split
QSDOperator
into a tuple.Example
>>> A0 = QSDOperator('AnnihilationOperator', 'A0', '(0)') >>> qsd_type, name, instantiator = A0
-
-
exception
qnet_qsd.
QSDCodeGenError
[source]¶ Bases:
Exception
Exception raised for missing data in a
QSDCodeGen
instance
-
class
qnet_qsd.
QSDCodeGen
(circuit, num_vals=None, time_symbol=None)[source]¶ Bases:
object
Class that allows to generate a QSD program for QNET expressions, and to run the program to (accumulative) collect expectation values for observables
Parameters: - circuit (
SLH
) – The circuit to be simulated via QSD. - num_vals (dict of
Symbol
to float)) – Numeric value for any symbol occurring in the circuit, or any operator/state that may be added later on. - time_symbol (None or
Symbol
) – symbol to denote the time dependence in the Hamiltonian (usually t). If None, the Hamiltonian is time-independent.
Attributes: - circuit (
SLH
) – see circuit parameter - time_symbol (None or
Symbol
) – see time_symbol parameter - syms (set of
Symbol
) – The set of symbols used either in the circuit, any of the observables, or the initial state, excluding time_symbol - num_vals (dict of
Symbol
to float)) – Map of symbols to numeric value. Must specify a value for any symbol in syms. - traj_data (
trajectorydata.TrajectoryData
) – The accumulated trajectory data. Every time therun()
, respectively therun_delayed()
method is called, the resulting trajectory data is incorporated. Thus, by repeatedly callingrun()
(followed byrun_delayed()
ifdelay=True
), an arbitrary number of trajectories may be accumulated in traj_data.
-
known_steppers
= ['Order4Step', 'AdaptiveStep', 'AdaptiveJump', 'AdaptiveOrthoJump']¶
-
observables
¶ Iterator over all defined observables (instances of
Operator
)
-
observable_names
¶ Iterator of all defined observable names (str)
-
compile_cmd
¶ Command to be used for compilation (after
compile()
method has been called). Environment variables and ‘~’ are not expanded
-
get_observable
(name)[source]¶ Return the observable for the given name (instance of
Operator
), according to the mapping defined byadd_observable()
-
add_observable
(op, name=None)[source]¶ Register an operator as an observable, together with a name that will be used in the header of the table of expectation values, and on which the name of the QSD output files will be based.
Parameters: - op (
Operator
) – Observable (does not need to be Hermitian) - name (str or
None
) – Name of of the operator, to be used in the header of the output table. IfNone
,str(op)
is used.
Raises: ValueError
– if name is invalid or too long, or no unique filename can be generated from name- op (
-
set_moving_basis
(move_dofs, delta=0.0001, width=2, move_eps=0.0001)[source]¶ Activate the use of the moving basis, see Section 6 of the QSD Paper.
Parameters: - move_dofs (int) – degrees of freedom for which to use a moving basis (the first ‘move_dofs’ freedoms are re-centered, and their cutoffs adjusted.)
- delta (float) – probability threshold for the cutoff adjustment
- width (int) – size of the “pad” for the cutoff
- move_eps (float) – numerical accuracy with which to make the shift.
Cf.
shiftAccuracy
in QSDState::recenter
method
Raises: ValueError
– if move_dofs is invalidQSDCodeGenError
– if requesting a moving basis for a degree of freedom for which any operator is defined that cannot be applied in the moving basis
-
set_trajectories
(psi_initial, stepper, dt, nt_plot_step, n_plot_steps, n_trajectories, traj_save=10)[source]¶ Set the parameters that control the trajectories from which a plot of expectation values for the registered observables will be generated.
Parameters: - psi_initial (
Ket
) – The initial state - stepper (str) – Name of the QSD stepper that should handle
propagation of a single time step. See
known_steppers
for allowed values - dt (float) – The duration for a single propagation step. Note that
the plot of expectation values will generally be on a coarser
grid, as controlled by the
set_plotting
routine - nt_plot_step (int) – Number of propagation steps per plot step. That is, expectation values of the observables will be written out every nt_plot_step propagation steps
- n_plot_steps (int) – Number of plot steps. The total number of
propagation steps for each trajectory will be
nt_plot_step * n_plot_steps
, and duration T of the entire trajectory will bedt * nt_plot_step * n_plot_steps
- n_trajectories (int) – The number of trajectories over which to average for getting the expectation values of the observables
- traj_save (int) – Number of trajectories to propagate before writing
the averaged expectation values of all observables to file.
This ensures that if the program is terminated before the
calculation of
n_trajectories
is complete, the lost data is at most that of the lasttraj_save
trajectories is lost. A value of 0 indicates that the values are to be written out only after completing all trajectories.
- psi_initial (
-
compile
(qsd_lib, qsd_headers, executable='qsd_run', path='.', compiler='g++', compile_options='-O2', delay=False, keep_cc=False, remote_apply=None)[source]¶ Compile into an executable
Parameters: - qsd_lib (str) – full path to the file
libqsd.a
containing the statically compiled QSD library. May reference environment variables the home directory (‘~’) - qsd_headers (str) – path to the folder containing the QSD header files. May reference environment variables the home directory (‘~’)
- executable (str) – name of executable to which the QSD program should be compiled. Must consist only of letters, numbers, dashes, and underscores only
- path (str) – The path to the folder where executable will be generated. May reference environment variables the home directory (‘~’)
- compiler (str) – compiler executable
- compile_options (str) – options to pass to the compiler
- delay (bool) – Deprecated, must be False
- keep_cc (bool) – If True, keep the C++ code from which the executable was compiled. It will have the same name as the executable, with an added ‘.cc’ file extension.
- remote_apply (callable or None) – If not None,
remote_apply(compilation_worker, kwargs)
must callcompilation_worker()
on any remote node. Typically, this might point to the apply method of anipyparallel
View instance. The remote_apply argument should only be given ifrun_delayed()
will be called with an argument map that will push the calculation of a trajectory to a remote node.
Raises: ValueError
– if executable name or qsd_lib are invalidsubprocess.CalledProcessError
– if compilation fails
- qsd_lib (str) – full path to the file
-
run
(seed=None, workdir=None, keep=False, delay=False)[source]¶ Run the QSD program. The
compile()
method must have been called before run. Ifcompile()
was called withdelay=True
, compile at this point and run the resulting program. Otherwise, just run the existing program from the earlier compilation. The resulting directory data is returned, and in addition the traj_data attribute is updated to include the new trajectories (in addition to any previous trajectories)The run method may be called repeatedly to accumulate trajectories.
Parameters: - seed (int) – Random number generator seed (unsigned integer), will be passed to the executable as the only argument.
- workdir (str or None) – The directory in which to (temporarily) create the output files. If None, a temporary directory will be used. Otherwise, the workdir must exist. Environment variables and ‘~’ will be expanded.
- keep (bool) – If True, keep QSD output files inside workdir.
- delay (bool) – If True, schedule the run to be performed at a later
point in time, when the
run_delayed()
routine is called.
Returns: Averaged data obtained from the newly simulated trajectories only. None if delay=True.
Return type: trajectorydata.TrajectoryData
Raises: QSDCodeGenError
– ifcompile()
was not calledOSError
– if creating/removing files/folders failssubprocess.CalledProcessError
– if delayed compilation fails or executable returns with non-zero exit codeValueError
– if seed is not unique
Note
The only way to run multiple trajectories in parallel is by giving
delay=True
. After preparing an arbitrary number of trajectories by repeated calls torun()
. Thenrun_delayed()
must be called with a map argument that supports parallel execution.
-
run_delayed
(map=<class 'map'>, n_procs_extend=1, _run_worker=None)[source]¶ Execute all scheduled runs (see delay option in
run()
method), possibly in parallel.Parameters: - map (callable) –
map(qsd_run_worker, list_of_kwargs)
must be equivalent to[qsd_run_worker(kwargs) for kwargs in list_of_kwargs]
. Defaults to the builtin map routine, which will process the scheduled runs serially. - n_procs_extend (int) – Number of local processes to use when averaging over trajectories.
Raises: TypeError
– If map does not return a list ofTrajectoryData
instances.Note
Parallel execution is achieved by passing an appropriate map routine. For example,
map=multiprocessing.Pool(5).map
would use a local thread pool of 5 workers. Another alternative would be the map method of anipyparallel
View. If (and only if) the View connects remote IPython engines,compile()
must have been called with an appropriate remote_apply argument that compiled the QSD program on all of the remote engines.- map (callable) –
- circuit (
-
qnet_qsd.
expand_cmd
(cmd)[source]¶ Return a copy of the array cmd, where for each element of the cmd array, environment variables and ‘~’ are expanded
-
qnet_qsd.
compilation_worker
(kwargs, _runner=None)[source]¶ Worker to perform compilation, suitable e.g. for being run on an IPython cluster. All arguments are in the kwargs dictionary.
Keys: - executable (str) – Name of the executable to be created. Nothing will be expanded.
- path (str) – Path where the executable should be created, as absolute path or relative to the current working directory. Environment variables and ‘~’ will be expanded.
- cc_code (str) – Multiline string that contains the entire C++ program to be compiled
- keep_cc (bool) – Keep C++ file after compilation? It will have the
same name as the executable, with an added
.cc
file extension. - cmd (list of str) – Command line arguments (see args in
subprocess.check_output). In each argument, environment
variables are expanded, and ‘~’ is
expanded to
$HOME
. It must meet the following requirements:- the compiler (first argument) must be in the
$PATH
- Invocation of the command must compile a C++ file with the name executable.cc in the current working directory to exectuable, also in the current working directoy. It must not take into account path. This is because the working directory for the subprocess handling the command invocation will be set to path. Thus, that is where the executable will be created.
- the compiler (first argument) must be in the
Returns: Absolute path of the compiled executable
Raises: subprocess.CalledProcessError
– if compilation failsOSError
– if creating/removing files/folder fails
-
qnet_qsd.
qsd_run_worker
(kwargs, _runner=None)[source]¶ Worker to perform run of a previously compiled program (see
compilation_worker()
), suitable e.g. for being run on an IPython cluster. All arguments are in the kwargs dictionary.Keys: - executable (str) – Name of the executable to be run. Nothing will be
expanded. This should generally be only the name of the
executable, but it can also be a path relative to
kwargs['path']
, or a (fully expanded) absolute path, in which casekwargs['path']
is ignored. - path (str) – Path where the executable can be found, as absolute path or relative to the current working directory. Environment variables and ‘~’ will be expanded.
- seed (int) – Seed (unsigned int) to be passed as argument to the executable
- operators (dict or OrderedDict of str to str)) – Mapping of operator name
to filename, see operators parameter of
from_qsd_data()
- workdir (str or None) – The working directory in which to execute the executable (relative to the current working directory). The output files defined in operators will be created in this folder. If None, a temporary directory will be used. If workdir does not exist yet, it will be created.
- keep (bool) – If True, keep the QSD output files. If False, remove the output files as well as any parent folders that may have been created alongside with workdir
Raises: FileNotFoundError
– if executable does not exist in pathReturns: Expectation values and variances of the observables, from the newly simulated trajectories only (instance of
TrajectoryData
)- executable (str) – Name of the executable to be run. Nothing will be
expanded. This should generally be only the name of the
executable, but it can also be a path relative to
-
qnet_qsd.
sanitize_name
(name, allowed_letters, replacements)[source]¶ Return a sanitized name, where all letters that occur as keys in replacements are replaced by their corresponding values, and any letters that do not match allowed_letters are dropped
Parameters: - name (str) – string to be sanitized
- allowed_letters (regex) – compiled regular expression that any allowed letter must match
- replacement (dict of str to str) – dictionary of mappings
Returns: sanitized name
Return type: Example:
>>> sanitize_filename = partial(sanitize_name, ... allowed_letters=re.compile(r'[.a-zA-Z0-9_-]'), ... replacements={'^':'_', '+':'_', '*':'_', ' ':'_'}) >>> sanitize_filename.__doc__ = "Sanitize name to be used as a filename" >>> sanitize_filename('\chi^{(1)}_1') 'chi_1_1'