sf.TDMProgram¶
-
class
TDMProgram
(N, name=None)[source]¶ Bases:
strawberryfields.program.Program
Represents a photonic quantum circuit in the time domain encoding.
The
TDMProgram
class provides a context manager for easily defining a single time-bin of the time domain algorithm. As with the standardProgram
, Strawberry Fields operations are appended to the time domain program using the Python-embedded Blackbird syntax.Once created, time domain programs can be executed on Strawberry Fields’ Gaussian backend in an efficient manner, or submitted to be executed on compatible hardware.
- Parameters
N (int or Sequence[int]) – If an integer, the number of concurrent (or ‘alive’) modes in each time bin. Alternatively, a sequence of integers may be provided, corresponding to the number of concurrent modes in the possibly multiple bands in the circuit.
name (str) – the program name (optional)
Example
Below, we create a time domain program with 2 concurrent modes:
>>> import strawberryfields as sf >>> from strawberryfields import ops >>> prog = sf.TDMProgram(N=2)
Once created, we can construct the program using the
prog.context()
context manager.>>> with prog.context([1, 2], [3, 4]) as (p, q): ... ops.Sgate(0.7, 0) | q[1] ... ops.BSgate(p[0]) | (q[0], q[1]) ... ops.MeasureHomodyne(p[1]) | q[0]
Printing out this program:
>>> prog.print() Sgate(0.7, 0) | (q[1]) BSgate({p0}, 0) | (q[0], q[1]) MeasureHomodyne({p1}) | (q[0])
Note that
p0
andp1
are symbolic gate parameters; to access the numeric values, we must use theprog.parameters
attribute:>>> prog.parameters {'p0': [1, 2], 'p1': [3, 4]}
When we simulate a time-domain program, it is first unrolled by the engine; unrolling involves explicitly repeating the single time-bin sequence constructed above, and shifting the simulated registers. This ‘unrolling’ procedure is performed automatically by the engine, however, we can visualize the unrolled program by calling the
unroll()
method.>>> prog.unroll(shots=3).print() Sgate(0.7, 0) | (q[1]) BSgate(1, 0) | (q[0], q[1]) MeasureHomodyne(3) | (q[0]) Sgate(0.7, 0) | (q[0]) BSgate(2, 0) | (q[1], q[0]) MeasureHomodyne(4) | (q[1]) Sgate(0.7, 0) | (q[1]) BSgate(1, 0) | (q[0], q[1]) MeasureHomodyne(3) | (q[0]) Sgate(0.7, 0) | (q[0]) BSgate(2, 0) | (q[1], q[0]) MeasureHomodyne(4) | (q[1]) Sgate(0.7, 0) | (q[1]) BSgate(1, 0) | (q[0], q[1]) MeasureHomodyne(3) | (q[0]) Sgate(0.7, 0) | (q[0]) BSgate(2, 0) | (q[1], q[0]) MeasureHomodyne(4) | (q[1])
Note the ‘shifting’ of the measured registers — this optimization allows for time domain algorithms to be simulated in memory much more efficiently:
>>> eng = sf.Engine("gaussian") >>> results = eng.run(prog, shots=3)
The engine automatically takes this mode shifting into account; returned samples will always be transformed to match the modes specified during construction:
>>> print(results.samples_dict) {0: [array([1.26208025]), array([1.53910032]), array([-1.29648336]), array([0.75743215]), array([-0.17850101]), array([-1.44751996])]}
Note that, unlike the standard
Program
, the TDM context manager has both required and essential arguments:Positional arguments are used to pass sequences of gate arguments to apply per time-bin. Within the context, these are accessible via the
p
context variable;p[i]
corresponds to thei
-th positional arguments.All positional arguments corresponding to sequences of gate arguments must be the same length. This length determines how many time-bins are present in the TDM program.
If the
p
variable is not used, the gate argument is assumed to be constant across all time-bins.shift="default"
(str or int): Defines how the qumode register is shifted at the end of each time bin. If set to"default"
, the qumode register is shifted such that each measured qumode reappears as a fresh mode at the beginning of the subsequent time bin. This is equivalent to a measured qumode being removed from the representation (by measurement) and a new one being added (by a light source). If set to an integer value, the register will shift by a step size of this integer at the end of each time bin.
Related tutorials
Attributes
The device specification and the compiler that was used during compilation.
The number of concurrent modes in the program.
Indicate if any operation in the program uses feed-forwarding or not.
Indicate if any operation in the program uses post-selection or not.
Whether the circuit is either unrolled or space-unrolled.
The number of measured modes in the program returned as a list.
Return the current number of valid quantum modes.
Return the parameters of the
TDMProgram
as a dictionary with the parameter name as keys, and the parameter lists as values.Return a tuple of all the currently valid quantum modes.
The number of spatial modes in the program.
The target specification the program has been compiled against.
The number of timebins in the program.
-
compile_info
¶ The device specification and the compiler that was used during compilation.
If the program has not been compiled, this will return
None
.- Returns
device specification and the short name of the Compiler that was used if compiled, otherwise None
- Return type
tuple or None
-
concurr_modes
¶ The number of concurrent modes in the program.
-
has_feed_forward
¶ Indicate if any operation in the program uses feed-forwarding or not.
- Returns
whether feed-forwarding is used anywhere in the circuit
- Return type
bool
-
has_post_selection
¶ Indicate if any operation in the program uses post-selection or not.
- Returns
whether post-selection is used anywhere in the circuit
- Return type
bool
-
is_unrolled
¶ Whether the circuit is either unrolled or space-unrolled.
-
measured_modes
¶ The number of measured modes in the program returned as a list.
-
num_subsystems
¶ Return the current number of valid quantum modes.
- Returns
number of currently valid register subsystems
- Return type
int
-
parameters
¶ Return the parameters of the
TDMProgram
as a dictionary with the parameter name as keys, and the parameter lists as values.
-
register
¶ Return a tuple of all the currently valid quantum modes.
- Returns
valid subsystem references
- Return type
tuple[RegRef]
-
spatial_modes
¶ The number of spatial modes in the program.
-
target
¶ The target specification the program has been compiled against.
If the program has not been compiled, this will return
None
.- Returns
the short name of the target Compiler template if compiled, otherwise None
- Return type
str or None
-
timebins
¶ The number of timebins in the program.
Methods
append
(op, reg)Append a command to the program.
apply_op
(cmd, modes, t)Apply a particular operation on register q at timestep t.
assert_modes
(device)Check that the number of modes in the program is valid.
bind_params
(binding)Binds the free parameters of the program to the given values.
can_follow
(prev)Check whether this program can follow the given program.
compile
(*[, device, compiler])Compile the program given a Strawberry Fields photonic compiler, or hardware device specification.
context
(*args[, shift])Syntactic sugar for defining a Program using the
with
statement.draw_circuit
([tex_dir, write_to_file])Draw the circuit using the Qcircuit \(\LaTeX\) package.
equivalence
(prog, **kwargs)Checks if two programs are equivalent.
Calculates and returns the value for where to crop the gate parameters.
Calculates and returns the loop delays.
lock
()Finalize the program.
optimize
()Simplify and optimize the program.
params
(*args)Create and access free circuit parameters.
print
([print_fn])Print the program contents using Blackbird syntax.
roll
()Represent the program in a compressed way without unrolling the for loops.
space_unroll
([shots])Construct the space-unrolled program and set it to
self.circuit
.unroll
([shots])Construct program with the register shift and store it in
self.circuit
.-
append
(op, reg)¶ Append a command to the program.
-
assert_modes
(device)[source]¶ Check that the number of modes in the program is valid.
Note
device.modes
must be a dictionary containing the maximum number of allowed measurements for the specified target.- Parameters
device (strawberryfields.DeviceSpec) – device specification object to use
-
bind_params
(binding)¶ Binds the free parameters of the program to the given values.
- Parameters
binding (dict[Union[str, FreeParameter], Any]) – mapping from parameter names (or the parameters themselves) to parameter values
- Raises
ParameterError – tried to bind an unknown parameter
-
can_follow
(prev)¶ Check whether this program can follow the given program.
This requires that the final RegRef state of the first program matches the initial RegRef state of the second program, i.e., they have the same number number of RegRefs, all with identical indices and activity states.
- Parameters
prev (Program) – preceding program fragment
- Returns
True if the Program can follow prev
- Return type
bool
-
compile
(*, device=None, compiler=None, **kwargs)¶ Compile the program given a Strawberry Fields photonic compiler, or hardware device specification.
The compilation process can involve up to three stages:
Validation: Validates properties of the program, including number of modes and allowed operations, making sure all the Operations used are accepted by the compiler.
Decomposition: Once the program has been validated, decomposition are performed, transforming certain gates into sequences of simpler gates.
General compilation: Finally, the compiler might specify bespoke compilation logic for transforming the quantum circuit into an equivalent circuit which can be executed by the target device.
Example:
The
gbs
compile target will compile a circuit consisting of Gaussian operations and Fock measurements into canonical Gaussian boson sampling form.>>> prog2 = prog.compile(compiler="gbs")
For a hardware device a
Device
object, and optionally a specified compile strategy, must be supplied. If no compile strategy is supplied the default compiler from the device specification is used.>>> eng = sf.RemoteEngine("X8") >>> device = eng.device_spec >>> prog2 = prog.compile(device=device, compiler="Xcov")
- Parameters
- Keyword Arguments
optimize (bool) – If True, try to optimize the program by merging and canceling gates. The default is False.
warn_connected (bool) – If True, the user is warned if the quantum circuit is not weakly connected. The default is True.
shots (int) – Number of times the program measurement evaluation is repeated. Passed along to the compiled program’s
run_options
.
- Returns
compiled program
- Return type
-
context
(*args, shift='default')[source]¶ Syntactic sugar for defining a Program using the
with
statement.The Program object itself acts as the context manager.
-
draw_circuit
(tex_dir='./circuit_tex', write_to_file=True)¶ Draw the circuit using the Qcircuit \(\LaTeX\) package.
This will generate the LaTeX code required to draw the quantum circuit diagram corresponding to the Program.
The drawing of the following Xanadu supported operations are currently supported:
Gate type
Supported gates
Single mode gates
Dgate
,Xgate
,Zgate
,Sgate
,Rgate
,Pgate
,Vgate
,Kgate
,Fouriergate
Two mode gates
Note
Measurement operations
MeasureHomodyne
,MeasureHeterodyne
, andMeasureFock
are not currently supported.- Parameters
tex_dir (str) – relative directory for latex document output
write_to_file (bool) – if False, no output file is created
- Returns
filename of the written tex document and the written tex content
- Return type
list[str]
-
equivalence
(prog, **kwargs)¶ Checks if two programs are equivalent.
This function converts the program lists into directed acyclic graphs, and runs the NetworkX
is_isomorphic
graph function in order to determine if the two programs are equivalent.Note
This method is a convenience method, wrapping the
program_equivalence()
function in the program utils module.- Parameters
prog (strawberryfields.program.Program) – quantum program to check equivalence with
- Keyword Arguments
compare_params (bool) – Set to
False
to turn of comparing program parameters; equivalency will only take into account the operation order.atol (float) – the absolute tolerance parameter for checking quantum operation parameter equality
rtol (float) – the relative tolerance parameter for checking quantum operation parameter equality
- Returns
returns
True
if two quantum programs are equivalent- Return type
bool
-
get_crop_value
()[source]¶ Calculates and returns the value for where to crop the gate parameters.
This method returns the number of vacuum modes arriving at the detector before the first computational mode for any job run on a single spatial mode TDM program.
- Returns
crop parameter
- Return type
int
-
get_delays
()[source]¶ Calculates and returns the loop delays.
This method calculates the delays present in the circuit by using the modes in which beamsplitters are acting on: on TMDPrograms with a single spatial mode, loop crossings always correspond to beamsplitters; if no beamsplitters are presents this method returns an empty list.
- Returns
A list where the length represent the number of loops present in the circuit and every entry corresponds to the number of modes that will fit at the same time in each loop.
- Return type
List[int]
-
lock
()¶ Finalize the program.
When a Program is locked, no more Commands can be appended to it. The locking happens when the program is run, compiled, or a successor Program is constructed, in order to ensure that the RegRef state of the Program does not change anymore.
-
optimize
()¶ Simplify and optimize the program.
The simplifications are based on the algebraic properties of the gates, e.g., combining two consecutive gates of the same gate family.
Returns a copy of the program, sharing RegRefs with the original.
See
optimize_circuit()
.- Returns
optimized copy of the program
- Return type
-
params
(*args)¶ Create and access free circuit parameters.
Returns the named free parameters. If a parameter does not exist yet, it is created and returned.
- Parameters
*args (tuple[str]) – name(s) of the free parameters to access
- Returns
requested parameter(s)
- Return type
FreeParameter, list[FreeParameter]
-
print
(print_fn=<built-in function print>)¶ Print the program contents using Blackbird syntax.
Example:
# create a 3 mode quantum program prog = sf.Program(3) with prog.context as q: ops.Sgate(0.54) | q[0] ops.Sgate(0.54) | q[1] ops.Sgate(0.54) | q[2] ops.BSgate(0.43, 0.1) | (q[0], q[2]) ops.BSgate(0.43, 0.1) | (q[1], q[2]) ops.MeasureFock() | q
>>> prog.print() Sgate(0.54, 0) | (q[0]) Sgate(0.54, 0) | (q[1]) Sgate(0.54, 0) | (q[2]) BSgate(0.43, 0.1) | (q[0], q[2]) BSgate(0.43, 0.1) | (q[1], q[2]) MeasureFock | (q[0], q[1], q[2])
- Parameters
print_fn (function) – optional custom function to use for string printing
-
space_unroll
(shots=1)[source]¶ Construct the space-unrolled program and set it to
self.circuit
.Calls the
_unroll_program
method which constructs the space-unrolled single-shot program, storing it in self.space_unrolled_circuit when run for the first time, and returns the space-unrolled program.- Parameters
shots (int) – the number of times the circuit should be repeated
-
unroll
(shots=1)[source]¶ Construct program with the register shift and store it in
self.circuit
.Calls the
_unroll_program
method which constructs the unrolled single-shot program, storing it in self.unrolled_circuit when run for the first time, and returns the unrolled program.- Parameters
shots (int) – the number of times the circuit should be repeated