Пример #1
0
def vec_commutator(A: Array):
    r"""Linear algebraic vectorization of the linear map X -> [A, X]
    in column-stacking convention. In column-stacking convention we have

    .. math::
        vec(ABC) = C^T \otimes A vec(B),

    so for the commutator we have

    .. math::
        [A, \cdot] = A \cdot - \cdot A \mapsto id \otimes A - A^T \otimes id

    Note: this function is also "vectorized" in the programming sense.

    Args:
        A: Either a 2d array representing the matrix A described above,
           or a 3d array representing a list of matrices.

    Returns:
        Array: vectorized version of the map.
    """
    iden = Array(np.eye(A.shape[-1]))
    axes = list(range(A.ndim))
    axes[-1] = axes[-2]
    axes[-2] += 1
    return np.kron(iden, A) - np.kron(A.transpose(axes), iden)
Пример #2
0
    def test_operators_into_frame_basis_with_cutoff(self):
        """Test function for construction of operators with cutoff."""

        # cutoff test
        frame_op = -1j * np.pi * Array([1.0, -1.0])
        operators = Array([self.X.data, self.Y.data, self.Z.data])
        carrier_freqs = Array([1.0, 2.0, 3.0])
        cutoff_freq = 3.0

        frame = Frame(frame_op)

        cutoff_mat = Array([[[1, 1], [1, 1]], [[1, 0], [1, 1]], [[0, 0],
                                                                 [1, 0]]])

        ops_w_cutoff, ops_w_conj_cutoff = frame.operators_into_frame_basis_with_cutoff(
            operators, cutoff_freq=cutoff_freq, carrier_freqs=carrier_freqs)

        ops_w_cutoff_expect = cutoff_mat * operators
        ops_w_conj_cutoff_expect = cutoff_mat.transpose([0, 2, 1]) * operators

        self.assertAllClose(ops_w_cutoff, ops_w_cutoff_expect)
        self.assertAllClose(ops_w_conj_cutoff, ops_w_conj_cutoff_expect)

        # same test with lower cutoff
        cutoff_freq = 2.0

        cutoff_mat = Array([[[1, 0], [1, 1]], [[0, 0], [1, 0]], [[0, 0],
                                                                 [0, 0]]])

        ops_w_cutoff, ops_w_conj_cutoff = frame.operators_into_frame_basis_with_cutoff(
            operators, cutoff_freq=cutoff_freq, carrier_freqs=carrier_freqs)

        ops_w_cutoff_expect = cutoff_mat * operators
        ops_w_conj_cutoff_expect = cutoff_mat.transpose([0, 2, 1]) * operators

        self.assertAllClose(ops_w_cutoff, ops_w_cutoff_expect)
        self.assertAllClose(ops_w_conj_cutoff, ops_w_conj_cutoff_expect)
Пример #3
0
    def test_lindblad_lmult_pseudorandom(self):
        """Test lmult of Lindblad OperatorModel with structureless
        pseudorandom model parameters.
        """
        rng = np.random.default_rng(9848)
        dim = 10
        num_ham = 4
        num_diss = 3

        b = 1.0  # bound on size of random terms

        # generate random hamiltonian
        randoperators = rng.uniform(low=-b, high=b, size=(
            num_ham, dim,
            dim)) + 1j * rng.uniform(low=-b, high=b, size=(num_ham, dim, dim))
        rand_ham_ops = Array(randoperators +
                             randoperators.conj().transpose([0, 2, 1]))

        # generate random hamiltonian coefficients
        rand_ham_coeffs = rng.uniform(low=-b, high=b, size=(
            num_ham)) + 1j * rng.uniform(low=-b, high=b, size=(num_ham))
        rand_ham_carriers = Array(rng.uniform(low=-b, high=b, size=(num_ham)))
        rand_ham_phases = Array(rng.uniform(low=-b, high=b, size=(num_ham)))
        ham_sigs = VectorSignal(lambda t: rand_ham_coeffs, rand_ham_carriers,
                                rand_ham_phases)

        # generate random dissipators
        rand_diss = Array(
            rng.uniform(low=-b, high=b, size=(num_diss, dim, dim)) +
            1j * rng.uniform(low=-b, high=b, size=(num_diss, dim, dim)))

        # random dissipator coefficients
        rand_diss_coeffs = rng.uniform(low=-b, high=b, size=(
            num_diss)) + 1j * rng.uniform(low=-b, high=b, size=(num_diss))
        rand_diss_carriers = Array(rng.uniform(low=-b, high=b,
                                               size=(num_diss)))
        rand_diss_phases = Array(rng.uniform(low=-b, high=b, size=(num_diss)))
        diss_sigs = VectorSignal(lambda t: rand_diss_coeffs,
                                 rand_diss_carriers, rand_diss_phases)

        # random anti-hermitian frame operator
        rand_op = rng.uniform(low=-b, high=b, size=(
            dim, dim)) + 1j * rng.uniform(low=-b, high=b, size=(dim, dim))
        frame_op = Array(rand_op - rand_op.conj().transpose())

        lindblad_frame_op = np.kron(Array(np.eye(dim)), frame_op) - np.kron(
            frame_op.transpose(), Array(np.eye(dim)))

        # construct model
        hamiltonian = HamiltonianModel(operators=rand_ham_ops,
                                       signals=ham_sigs)
        lindblad_model = LindbladModel.from_hamiltonian(
            hamiltonian=hamiltonian,
            noise_operators=rand_diss,
            noise_signals=diss_sigs)
        lindblad_model.frame = lindblad_frame_op

        A = Array(
            rng.uniform(low=-b, high=b, size=(dim, dim)) +
            1j * rng.uniform(low=-b, high=b, size=(dim, dim)))

        t = rng.uniform(low=-b, high=b)
        value = lindblad_model.lmult(t, A.flatten(order="F"))

        ham_coeffs = np.real(rand_ham_coeffs *
                             np.exp(1j * 2 * np.pi * rand_ham_carriers * t +
                                    1j * rand_ham_phases))
        ham = np.tensordot(ham_coeffs, rand_ham_ops, axes=1)
        diss_coeffs = np.real(rand_diss_coeffs *
                              np.exp(1j * 2 * np.pi * rand_diss_carriers * t +
                                     1j * rand_diss_phases))

        expected = self._evaluate_lindblad_rhs(A, ham, rand_diss, diss_coeffs,
                                               frame_op, t)

        self.assertAllClose(expected, value.reshape(dim, dim, order="F"))