Utilities

trueq.utils.deprecated(deprecated_in, removed_after, reason='')

Decorator used to mark functions as deprecated.

The following example shows renaming a function and marking the old name as deprecated.

import trueq as tq
v = tq.__version__

@tq.utils.deprecated(v, v, "Use foo() instead.")
def my_func(x):
    return x
Parameters
  • deprecated_in (str) – The True-Q™ version that the function was deprecated in.

  • removed_after (str) – The last True-Q™ version that will have this function.

  • reason (str) – A string to be appended to the warning message.

Return type

function

trueq.utils.rename_deprecation(old_name, new_fn, deprecated_in, removed_after)

Specialization of deprecation() to deprecations that are simply function or method renames.

import trueq as tq
v = tq.__version__

def foo(x):
    return x

bar = tq.utils.rename_deprecation("bar", foo, v, v)
Parameters
  • old_name (string) – The old name of the function.

  • new_fn (function) – The new function.

  • deprecated_in – The True-Q™ version that the function was deprecated in.

  • removed_after – The last True-Q™ version that will have this function.

Return type

function

trueq.utils.auto_twirl(twirl, labels_or_cycle)

Given a full twirling group or a twirling group shortcut, returns a valid full twirling group. As a special case, if twirl=None then None is returned.

Parameters
  • twirl (Iterable | str) – One of the twirling shortcuts “P”, “C”, “SU”, or “I”, or, a full twirling group specification such as (("C", 0, 1), ("SU", 2), ("P", 4)).

  • labels_or_cycle (Iterable | trueq.Cycle) – A depth-2 nested iterable of labels to be used as twirling labels in the case when twirl is a string (this value is unused otherwise), or a cycle, where gate labels are used.

Return type

tuple | None

trueq.utils.pretty_twirl(twirl, max_chars=30)

Converts the full twirl object into a pretty string representation.

Parameters
  • twirl (tuple) – The full twirl object, e.g. the output of auto_twirl().

  • max_chars (int) – The maximum length of the output string.

trueq.utils.shelve_cache(func=None, filename=None)

Returns a decorator that enables shelve-based memoization of function calls.

If no filename is specified, keeps only the local cache of function calls.

This adds several entries to the __dict__ of the wrapped function:

  • func.local_cache() - Local cache, with stringified args, and
    kwargs as keys.
  • func.info() - Dict of memoizer info, including a count of
    cache hits, misses and calls.
  • func.clear_cache() - Deletes the contents of the local cache and
    empties the file if specified.
  • func.set_filename(filename)() - This sets the filename of where to save
    the cache file.

Example:

import trueq.utils as tqu

@tqu.shelve_cache
def fib(n):
    "Memoized Fibonacci function"
    if n in [0, 1]:
        return 1
    else:
        return fib(n - 1) + fib(n - 2)

print(fib(100))  # 573147844013817084101

fib.info
573147844013817084101
{'hits': 98, 'misses': 101, 'calls': 199, 'filename': None, 'cachesize': 101}
Parameters

filename (str) – the name of the shelve file where the cache will be saved. shelve may create multiple files depending on underlying shelve methods (see shelve package for more info).

trueq.utils.optional_import(name, package=None, required_version=None, package_name=None)

Attempts to import the given module name and return it. If there is an ImportError, None is returned. Optionally, if it is imported but the detected version is less recent than the required version, a warning is raised and None is returned. If no version is detected, we return the module and raise a different warning.

import trueq.utils as tqu

a = tqu.optional_import("qiskit", required_version="0.8.1")
b = tqu.optional_import(".converters", "qiskit", required_version="0.8.1")
Parameters
  • name (str) – The name of the package to import.

  • package (str) – The package anchor if the name is specified in relative terms.

  • required_version (str) – The version we require to import.

  • package_name (str) – The name of the package as defined in its setup.py, if None then name or package is used.

Return type

module

trueq.utils.to_tuple_int(param, int_depth)

Converts a nested iterable of ints to a nested tuple of integers. The desired tuple-nesting depth is specified, and the output is guaranteed not to be ragged in this nesting depth. Integers below the final depth are treated as tuples of length one for convenience, hence the validity of the last two examples below.

import numpy as np
from trueq.utils import to_tuple_int

print(to_tuple_int(7, 0))                  # 7
print(to_tuple_int([0, 5, 3], 1))          # (0, 5, 3)
print(to_tuple_int([(0,), (5, 3)], 2))     # ((0,), (5, 3))
print(to_tuple_int([([0],), (5, [3])], 3)) # (((0,),), ((5,), (3,)))
print(to_tuple_int([0, 5, (3,)], 2))       # ((0,), (5,), (3,))
7
(0, 5, 3)
((0,), (5, 3))
(((0,),), ((5,), (3,)))
((0,), (5,), (3,))
Parameters
  • param (int | Iterable) – A nested iterable terminated in integer-likes.

  • int_depth (int) – The depth at which you want integers; int_depth=0 means output will be integer, int_depth=1 means output will be tuple of integers, etc.

Returns

A nested tuple of ints.

Return type

tuple | int

Raises

ValueError – If the input has ragged iterable depth (excepting the int-likes are honorary length-1 tuples rule) or an unexpected type is found.

trueq.utils.dicts_close(dict1, dict2)

Tests if the given dicts whose values are numeric are equal up to numerical precision. np.allclose is used with default tolerance parameters.

Parameters
  • dict1 (dict) – A dictionary, for example, {'00':0.25, '01':0.75}

  • dict2 (dict2) – A dictionary, for example, {'00':0.25, '01':0.75}

Return type

bool

trueq.utils.temp_folder(delete=True)

Context to create a temporary folder and switch the current working directory to that folder for the duration of the context. The folder and its contents are deleted by default when the context is exited.

import trueq.utils as tqu
import os

with tqu.temp_folder() as folder:
    with open("new_file.txt", "w") as f:
       f.write("Hello!")

print(f"The folder was called {os.path.basename(folder)} but now it's gone.")
The folder was called tmp78u58gwk but now it's gone.
Parameters

delete (bool) – Whether to delete the folder and its contents when the context exits. The current working directory is restored to its original location regardless.

trueq.utils.save(obj, filename, overwrite=False, include_cycles=True)

Saves a Pickle representation of an object to file. Tries to gzip the file contents by default. See trueq.utils.load() to instantiate a new object from the saved file.

import trueq as tq
import os

circuits = tq.make_srb([0, 1], [4, 50, 100], 30)

with tq.utils.temp_folder():
    # the extension ".tq" is optional but encouraged
    tq.utils.save(circuits, "my_circuits.tq")
    print(f"Saved file is {os.path.getsize('my_circuits.tq')} bytes.")
Saved file is 91394 bytes.
Parameters
  • obj – The object to Pickle.

  • filename (str) – The filename to save as.

  • overwrite (bool) – Any existing file will be overwritten if this is True, else saving will raise FileExistsError

  • include_cycles (bool) – Whether the cycle information in any present Circuits should be retained. If false, then all circuits will have their Cycles stripped in the saved version to save space. Results and other information will be saved so that analysis and plotting will work on a reinstantiated copy.

trueq.utils.load(filenames, verbose=False)

Creates a new instance of a True-Q™ object from a file that was saved to disk. Multiple files are concatenated into a single object if every file stores a EstimateCollection or if every file stores a CircuitCollection.

See trueq.utils.save() to save a True-Q™ object to disk.

import trueq as tq

circuits = tq.make_srb([0, 1], [4, 50, 100], 30)

with tq.utils.temp_folder():
    # the extension ".tq" is optional but encouraged
    tq.utils.save(circuits, "my_circuits.tq")

    loaded = tq.load("my_circuits.tq")
    assert circuits == loaded
Parameters
  • filenames (str or list) – Where to find the file(s).

  • verbose (bool) – Print the version of True-Q™ used to save the file(s) if True.

Returns

object

trueq.utils.labels_contain_cycle(labels, cycle)

Determines whether a tuple of qubit labels contains a given Cycle.

Parameters
  • labels (tuple) – A tuple of ints.

  • cycle (Cycle) – A clock cycle of Gates, mapping label tuples to gates.

Return type

bool

trueq.utils.twirls_equal(twirl1, twirl2)

Returns True iff the two given twirling groups are equal.

import trueq.utils as tqu

print(tqu.twirls_equal((("P", 0), ("SU", 1, 2)), (("SU", 2, 1), ("P", 0) )))
# True
print(tqu.twirls_equal((("P", 0), ("SU", 1, 2)), (("P", 0), ("C", 1, 2))))
# False
True
False
Parameters
  • twirl1 – The first twirling group.

  • twirl2 – The second twirling group.

Return type

bool

trueq.utils.cycle_labels(cycle)

Returns the sorted unique qubit labels contained in the given Cycle object.

Return type

list

trueq.utils.riffle_chain(*iterables)

Chains the given iterables together by riffling their contents. The riffling strategy tries to spread out the shortest given iterables as much as possible over the whole output when the given iterables have non-uniform lengths.

import trueq.utils as tqu

print(list(tqu.riffle_chain([1] * 4, [2] * 4, [3] * 4)))
# [1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
print(list(tqu.riffle_chain([1] * 6, [2] * 5, [3] * 2)))
# [1, 1, 1, 2, 2, 3, 1, 1, 1, 2, 2, 3, 2]
[1, 2, 3, 1, 2, 3, 1, 2, 3, 1, 2, 3]
[1, 1, 1, 2, 2, 3, 1, 1, 1, 2, 2, 3, 2]
Parameters

iterables – A sequence of iterable objects with a len attribute.

Return type

generator

trueq.utils.get_template(filename)

Returns a mako template from the templates in trueq.assets.

Parameters

filename (str) – The filename of the template file in trueq.assets.