Source code for qdyn.prop_gate

"""Support routines for the qdyn_prop_gate utility"""
import re

import numpy as np

from .units import UnitFloat


def _isqrt(n):
    """Integer square root of n > 0

    >>> _isqrt(1024**2)
    1024
    >>> _isqrt(10)
    3
    """
    assert n >= 0
    x = n
    y = (x + 1) // 2
    while y < x:
        x = y
        y = (x + n // x) // 2
    return x


[docs]def get_prop_gate_of_t(gates_file, with_t=False): r"""Yield gates in `gates_file`, where `gates_file` is in the format written by the ``qdyn_prop_gate`` utility's ``--write-gate`` option. That is, each row in `gates_files` has $2 n^2 + 1$ columns. The first column is a time stamp, the remaining columns are the real and imaginary part for each entry in the $n \times n$ gate (vectorized in column-major format). If `with_t` is False (default), yield only the gates, otherwise yield both the gates and the time stamp for each gate Returns: * If ``with_t=False``, iterator over gates, where each gate is a complex $n \times n$ numpy matrix, or a Gate2Q instance for a $4 \times 4$ gate * If ``with_t=True``, iterator of tuples ``(gate, t)``, where ``t`` is a float or an instance of UnitFloat if the time unit can be derived from the header of `gates_file` """ with open(gates_file) as in_fh: time_unit = None for line in in_fh: if line.startswith('#'): try: time_unit = re.search(r't\s*\[(\w+)\]', line).group(1) except AttributeError: pass else: vals = np.array([float(v) for v in line.split()]) n = _isqrt((len(vals) - 1) // 2) assert 2 * n * n + 1 == len(vals) shape = (n, n) gate = np.reshape( vals[1::2], shape, order='F' ) + 1j * np.reshape(vals[2::2], shape, order='F') if with_t: if time_unit is not None: yield gate, UnitFloat(vals[0], time_unit) else: yield gate, vals[0] else: yield gate