All bitstrings in lexicographical order as a 2d np.ndarray.

    This should be the same as ``np.array(list(itertools.product([0,1], repeat=n_bits)))``
    but faster.
511169
def all_bitstrings(n_bits):
    
    n_bitstrings = 2 ** n_bits
    out = np.zeros(shape=(n_bitstrings, n_bits), dtype=np.int8)

    tf = np.array([False, True])
    for i in range(n_bits):
        # Lexicographical ordering gives a pattern of 1's
        # where runs of 1s of length 2**j are tiled 2**i times

        # i indexes from the *left*
        # j indexes from the *right*
        j = n_bits - i - 1

        out[np.tile(np.repeat(tf, 2 ** j), 2 ** i), i] = 1
    return out
948686
def sample_bitstrings(self, n_samples):
        
        if self.rs is None:
            raise ValueError("You have tried to perform a stochastic operation without setting the "
                             "random state of the simulator. Might I suggest using a PyQVM object?")

        # note on reshape: it puts bitstrings in lexicographical order.
        # would you look at that .. _all_bitstrings returns things in lexicographical order!
        # reminder: qubit 0 is on the left in einsum simulator.
        probabilities = np.abs(self.wf.reshape(-1)) ** 2
        possible_bitstrings = all_bitstrings(self.n_qubits)
        inds = self.rs.choice(2 ** self.n_qubits, n_samples, p=probabilities)
        return possible_bitstrings[inds, :]
175500
def C_dict2array(C):
    """"""
    return np.hstack([np.asarray(C[k]).ravel() for k in C_keys])
631661
def fill_array(dstarr, order, r, g, b, a):
    
    # TODO: can we make this more efficient?
    dtype = dstarr.dtype
    maxv = np.iinfo(dtype).max
    bgval = dict(A=int(maxv * a), R=int(maxv * r), G=int(maxv * g),
                 B=int(maxv * b))
    bgtup = tuple([bgval[order[i]] for i in range(len(order))])
    if dtype is np.uint8 and len(bgtup) == 4:
        # optimiztion
        bgtup = np.array(bgtup, dtype=dtype).view(np.uint32)[0]
        dstarr = dstarr.view(np.uint32)

    dstarr[..., :] = bgtup
451941
def _indexes(arr):
    
    myarr = np.array(arr)
    if myarr.ndim == 1:
        return list(range(len(myarr)))
    elif myarr.ndim == 2:
        return tuple(itertools.product(list(range(arr.shape[0])),
                                       list(range(arr.shape[1]))))
    else:
        raise NotImplementedError('Only supporting arrays of dimension 1 and 2 as yet.')
433560
def to_bitarray(data, width=8):
    '''  '''
    if isinstance(data, list) or isinstance(data, bytearray):
        data = combine_hex(data)
    return [True if digit == '1' else False for digit in bin(data)[2:].zfill(width)]
1336737
def _bfill(arr, n=None, axis=-1):
    ''''''
    import bottleneck as bn

    arr = np.flip(arr, axis=axis)

    # fill
    arr = bn.push(arr, axis=axis, n=n)

    # reverse back to original
    return np.flip(arr, axis=axis)
808813
def concatenate_1d(arrays):
    
    if len(arrays) == 0:
        return np.array([])
    if len(arrays) == 1:
        return np.asanyarray(arrays[0])
    if any(map(np.ma.is_masked, arrays)):
        return np.ma.concatenate(arrays)
    return np.concatenate(arrays)
787683
def ndim(self):
        """"""
        if self.is_raster():
            return {
                FeatureType.DATA: 4,
                FeatureType.MASK: 4,
                FeatureType.SCALAR: 2,
                FeatureType.LABEL: 2,
                FeatureType.DATA_TIMELESS: 3,
                FeatureType.MASK_TIMELESS: 3,
                FeatureType.SCALAR_TIMELESS: 1,
                FeatureType.LABEL_TIMELESS: 1
            }[self]
        return None
244550
def sorted_bits(self) -> List[Tuple[str, int]]:
        """"""
        return sorted(self.bit.items(), key=lambda x: x[1])
1187049
def numpy_bins(self) -> np.ndarray:
        
        if self._numpy_bins is None:
            self._numpy_bins = to_numpy_bins(self.bins)
        return self._numpy_bins
201370
def format_nd_slice(item, ndim):
    
    if not isinstance(item, tuple):
        item = (item,)
    return item[:ndim] + (None,) * (ndim - len(item))
458638
def as_int_array(self):
        
        return self.view(
            type=ndarray,
            dtype=unsigned_int_dtype_with_size_in_bytes(self.itemsize),
        )
1050554
def _coerce_to_ndarray(self):
        

        # TODO(jreback) make this better
        data = self._data.astype(object)
        data[self._mask] = self._na_value
        return data
1339999
def recarray2dict(recarray):
    """"""
    # TODO: subarrays
    result = {}
    for descr, value in zip(recarray.dtype.descr, recarray):
        name, dtype = descr[:2]
        if dtype[1] == 'S':
            value = bytes2str(stripnull(value))
        elif value.ndim < 2:
            value = value.tolist()
        result[name] = value
    return result
156142
def getIndicesFromBigIndex(self, bigIndex):
        
        indices = numpy.array([0 for i in range(self.ndims)])
        for i in range(self.ndims):
            indices[i] = bigIndex // self.dimProd[i] % self.dims[i]
        return indices
1273573
def to_multidimensional(tpm):
    
    # Cast to np.array.
    tpm = np.array(tpm)
    # Get the number of nodes.
    N = tpm.shape[-1]
    # Reshape. We use Fortran ordering here so that the rows use the
    # little-endian convention (least-significant bits correspond to low-index
    # nodes). Note that this does not change the actual memory layout (C- or
    # Fortran-contiguous), so there is no performance loss.
    return tpm.reshape([2] * N + [N], order="F").astype(float)