Tomographer
v4.1
Tomographer C++ Framework Documentation
|
tomorun
program The tomorun
executable has several figures of merit built into the program: the trace distance, the purified distance, or the fidelity to any reference state, as well as the expectation value of an observable. If you wish to produce a histogram of a different figure of merit which can't be cast into one of these, you need to change the source code of the tomorun program.
Another option, which may be easier if you have a very special purpose which might not warrant inclusion into the generic tomorun
program, is to combine the required classes into a new special-purpose program. This is not difficult, and there is already an example ready—see Creating a custom tomorun-like program.
This information page describes how you should change the source code of tomorun
to include your figure of merit.
We'll illustrate these steps with a simple example: the two-norm distance (aka. the Hilbert-Schmidt distance) to any reference state, defined by \( d_\mathrm{HS}(\rho,\rho_{\mathrm{Ref}}) = \Vert \rho-\rho_{\mathrm{Ref}}\Vert_2 \), with \( \Vert A\Vert_2 = \mathrm{tr}\left(A^\dagger A\right) \).
First, you should write the code which calculates the figure of merit, complying to a ValueCalculator Interface type interface. Your new class should in particular have a method getValue(const MatrixType & T)
taking as argument an Eigen matrix type which will be a matrix square root (see T Parameterization) of the quantum state rho for which the function should calculate the figure of merit.
You should do this in a new header file, that's the easiest.
For our example, we can get inspired by the code for, e.g., Tomographer::DenseDM::TSpace::TrDistToRefCalculator defined in tspacefigofmerit.h. For example, let's create a file called "hs_dist.h"
inside the "cxx/tomorun/"
directory of the tomographer project:
The part about needownoperatornew.h and Tomographer::Tools::NeedOwnOperatorNew is to make sure that the object, when created, is aligned in memory. This is needed because the object has a Eigen member (rho_ref) which must be aligned in memory for vectorized operations (see Eigen's docs for alignment issues, there's a lot on that). In the Tomographer project, the Tomographer::Tools::NeedOwnOperatorNew virtual base makes sure that the necessary operator new()
is defined so that objects are aligned in memory when allocated.
The choice of figure of merit is specified as the argument to the command line option "--value-type"
. So you should in fact first decide of a short memo string describing your figure of merit (e.g. for our example "HS-dist"
would be an appropriate choice).
Now, open the file "tomorun_opts.h"
located inside the "cxx/tomorun/"
directory. The locations where you should adapt the code are marked by comments saying "INSERT
CUSTOM FIGURE OF MERIT HERE"
. Adapt the code as follows.
The class val_type_spec
is a type which is used to store the choice of figure of merit. It stores the choice as an enum value, but it is capable of converting to and from a string. So you should add a new enumeration value, as well as adapt the class methods, so that it understands your new figure of merit.
As with the other figures of merit, the user may also pass a string argument in the form "HS-dist:string_argument_goes_here"
which can specify for example a reference state. You don't have to do anything special for that, it's taken care of for you already.
Also change the command-line help text to include documentation for your new figure of merit.
In our example, we'd change the following enumeration inside the class val_type_spec
from:
to:
Then we would insert the following inside the method val_type_spec::set_value_string(), after the similar tests for the other figures of merit:
and similarly, we'd update the function operator<<(std::ostream & str, const val_type_spec & val)
to include a case for our figure of merit:
tomorun
how to instantiate your figure of merit calculatorThe final piece of code which needs to be added is the logic of how your class which calculates the figure of merit (in our example, inside "hs_dist.h"
) should be instantiated.
The relevant file to modify is the file named tomorun_dispatch.h
, located inside the "cxx/tomorun/"
directory.
First, include your "hs_dist.h"
file near the top: insert the line
near the top of the file, below the other include directives.
Then you'll have to code how specifically the program should instantiate your value calculator. Add a conditional in the function tomorun_dispatch()
which tests whether the user asked for your figure of merit, and instantiate your class appropriately. The general logic should look like this:
Starting in Tomographer version 2, the set up is slightly more complicated, because there are two different ways tomorun
can be compiled. It can either be compiled by using a Tomographer::MultiplexorValueCalculator, or with static checks and different static code for each figure of merit (as before). The former approach seems more efficient, and is now the default (this can be changed with CMake options when compiling tomorun). The logic is not that compicated, so you're best off by seeing what the code does for the built-in figures of merit and mimicking that.
You're probably best off copying from the built-in examples inside that same function, or the example for the Hilbert-Schmidt distance presented here. Here are some additional tips:
"opt->valtype.ref_obj_name"
is an std::string of anything the user specified at the command line or in the config file as second part to the "--value-type"
option (e.g., representing the name of the variable in the MATLAB data file containing the reference state density matrix)."matf"
object, which is a Tomographer::MAT::File instance.In our example for the Hilbert-Schmidt distance, the reference state is read from the MATLAB data file. It is to be taken by default to be "rho_MLE"
, which is the maximum likelihood estimate state, if "--value-type=HS-dist"
. A custom reference state can be given which is to be read from the MATLAB data file (if "--value-type=HS-dist:my_ref_state_dm"
, where "my_ref_state_dm"
is the name of the variable inside the MATLAB data file containing the density matrix of the reference state). Here's the code for the non-multiplexed version of the value-calculator: