This guide explains how to write C++QED scripts in Python. For a detailed documentation about all modules, classes and functions look into the cpypyqed Reference.
Cpypyqed is a thin python wrapper to the C++QED programming framework. The goal is to enable the user to write python scripts instead of C++ programs, while keeping the structure and syntax very similar.
All the actual work of running teh simulations is done by the C++ libraries under the hood, which means there is no performance penalty when using cpypyqed over plain C++QED.
C++QED makes heavy use of deeply templated classes and compile-time algorithms. Some of the class templates are pre-instantiated for cpypyqed, e.g. there is StateVector1, StateVector2, ... StateVector4 as instantiations for a quantumdata::StateVector up to rank 4. For other classes which are templated in a more complex way, this pre-instantiation is not possible.
Instead, cpypyqed makes use of the cmake build infrastructure of C++QED to build wrappers of these class templates on demand. The modules resulting out of these on-demand compilation are cached and available for use without compilation delay from then on.
Easiest installation is to clone the C++QED super repository which comes with everything. If Python and boost.python is detected, cpypyqed will be built:
$ git clone --recursive -b python git@ge-c705.uibk.ac.at:cppqed/complete.git C++QED
$ cd C++QED
$ make C++QED/build; cd C++QED/build
$ cmake -DCMAKE_BUILD_TYPE=<Release or Debug> <other cmake options> ..
$ make cpypyqed
$ make check_cpypyqed
The last command will run the cpypyqed related tests.
Of course it is also possible to clone the cpypyqed repository as a standalone project.
After building the module, either call make install or point your $PYTHONPATH to the cpypyqed build directory. As will be explained later, you can also have two cpypyqed build directories installed or in the $PYTHONPATH simultaneously: one compiled in release mode and one compiled in debug mode.
By default, on-demand compilation is performed in a temporary directory under ~/.cpypyqed and the resulting modules are stored in ~/.cpypyqed/cppqedmodules. The build directory ~/.cpypyqed can be changed by setting the environment variable $CPYPYQED_BUILDDIR. Still we will refer to the build directory as ~/.cpypyqed.
By default the configuration file read in by cpypyqed is ~/.cpypyqed/config.txt. An additional configure file can be read in by setting the environment variable $CPYPYQED_CONFIG. The configuration file has the following syntax:
[Setup]
# override the location where cpypyqed looks for C++QED libraries (e.g. CPPQEDcore build directory)
cppqed_dir=<path>
# override the location where cpypyqed looks for release C++QED libraries (e.g. CPPQEDcore build directory)
# this also overrides cppqed_dir
cppqed_dir_debug=<path>
# override the location where cpypyqed looks for debug C++QED libraries (e.g. CPPQEDcore build directory)
# this also overrides cppqed_dir
cppqed_dir_release=<path>
# Set the C++ compiler path
compiler=<path>
# Set additional cmake options
cmake_opts=-Dsome_option -Dsome_other_option
# If set to False, the temporary build directory is not deleted after the build
delete_temp=True
Because cmake allows different build configurations, there are two versions of cpypyqed:
- import cpypyqed or from cpypyqed import * for release mode
- import cpypyqed.debug or from cpypyqed.debug import * for debug mode
If one or both of these import statements succeed depend on which configurations are installed.
Note that importing cpypyqed will fall back to the debug version if the release version is not found, so this should work in both cases. Use cpypyqed.debug or call the script with –debug to force the debug version (note that –debug is removed from the comand line when importing cpypyqed.debug).
In C++QED, the parameter bundle is responsible to declare parameters, define their defaults and finally parse and update parameters from the command line. The parameter bundle is exposed in the cpypyqed interface by ParameterTable, update and all the relevant Pars-classes like mode.Pars, qbit.Pars, etc. Usage is pretty much along the lines of the C++QED parameter bundle with two exceptions: the update function has a different signature as documented, and parameters::ParameterTable::add is missing in cpypyqed for technical reasons. This means additional user-defined commandline parameters cannot be added in the usual way. However, there is a workaround using the aforementioned argparse. This is demonstrated in the script 1particle1mode.py:
import sys
import argparse
from cpypyqed import *
parser = argparse.ArgumentParser(add_help=False)
parser.add_argument('--1p1mconf', help="System configuration code for 1particle1mode",
type=int,default=1)
(args,remaining)=parser.parse_known_args(sys.argv)
conf = vars(args)['1p1mconf']
...
parameters.update(p,remaining,'--')
These Python scripts correspond to the examples presented in the User Guide for the C++ interface
Corresponds to this C++ script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 | #!/usr/bin/env python2
import sys
from cpypyqed import *
p=parameters.ParameterTable()
pe=evolution.Pars(p)
pm=mode.ParsPumpedLossy(p)
pe.evol=evolution.Method.MASTER
pm.cutoff=30
parameters.update(p,sys.argv,'--')
evolve(mode.init(pm),mode.make(pm,QMP.UIP),pe)
|
Corresponds to this C++ script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | #!/usr/bin/env python2
import sys
from cpypyqed import *
p=parameters.ParameterTable()
pe=evolution.Pars(p)
pq=qbit.ParsPumpedLossy(p)
pm=mode.ParsPumpedLossy(p)
pjc=jaynescummings.Pars(p)
qmp=updateWithPicture(p,sys.argv,'--')
evolve(qbit.init(pq)**mode.init(pm),
binary.make( jaynescummings.make( qbit.make(pq,qmp),
mode.make(pm,qmp),
pjc ) ),
pe)
|
Corresponds to this C++ script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 | #!/usr/bin/env python2
# coding: utf-8
import sys
from cpypyqed import *
p=parameters.ParameterTable()
pe=evolution.Pars(p)
pp=particle.Pars(p)
pmP=mode.ParsLossy(p,"P")
pmM=mode.ParsLossy(p,"M")
ppcP=particlecavity.ParsAlong(p,"P")
ppcM=particlecavity.ParsAlong(p,"M")
ppcP.modeCav=ModeFunctionType.PLUS
ppcM.modeCav=ModeFunctionType.MINUS
qmp=updateWithPicture(p,sys.argv,"--")
part=particle.make(pp ,qmp)
plus = mode.make(pmP,qmp)
minus= mode.make(pmM,qmp)
evolve(particle.wavePacket(pp)**mode.init(pmP)**mode.init(pmM),
makeComposite({(1,0):ParticleAlongCavity(plus ,part,ppcP),
(2,0):ParticleAlongCavity(minus,part,ppcM),
(1,2,0):ParticleTwoModes(plus,minus,part,ppcP,ppcM)}),
pe)
|
…