Example #1
0
    def test_transform_rhs_funcs_order_F(self):
        """Test rhs function conversion"""

        inner_spec = {"type": "array", "shape": (4,)}
        outer_spec = {"type": "array", "shape": (2, 2)}
        converter = StateTypeConverter(inner_spec, outer_spec)

        X = Array([[0.0, 1.0], [1.0, 0.0]])

        # do matrix multiplication (a truly '2d' operation)
        def rhs(t, y):
            return t * (y @ y)

        # pylint: disable=unused-argument
        def generator(t):
            return X

        new_rhs = converter.rhs_outer_to_inner(rhs)

        test_t = np.pi
        y_2d = Array([[1, 2], [3, 4]])
        y_1d = y_2d.flatten(order="F")

        expected_output = rhs(test_t, y_2d).flatten(order="F")
        output = new_rhs(test_t, y_1d)

        self.assertAllClose(output, expected_output)

        new_generator = converter.generator_outer_to_inner(generator)

        # verify generator vectorization
        expected_output = np.kron(Array(np.eye(2)), X)
        output = new_generator(test_t)

        self.assertAllClose(output, expected_output)
Example #2
0
    def test_y0_reshape(self):
        """Test automatic detection of vectorized LMDE."""

        y0 = Array(np.eye(2))

        output = lmde_y0_reshape(4, y0)
        expected = y0.flatten(order="F")

        self.assertAllClose(output, expected)
Example #3
0
    def from_outer_instance_inner_type_spec(cls, outer_y, inner_type_spec=None, order="F"):
        """Instantiate from concrete instance of the outer type,
        and an inner type-spec. The inner type spec can be either
        be fully specified, or be more general (i.e. to
        facilitate the situation in which a solver needs a 1d array).

        Accepted general data types:
            - {'type': 'array'}
            - {'type': 'array', 'ndim': 1}

        Args:
            outer_y (array): concrete outer data type
            inner_type_spec (dict): inner, potentially general, type spec
            order (str): order argument to be used in array reshaping.

        Returns:
            StateTypeConverter: type converter as specified by args

        Raises:
            Exception: if inner_type_spec is not properly specified or is
            not a handled type
        """

        # if no inner_type_spec given just instantiate both inner
        # and outer to the outer_y
        if inner_type_spec is None:
            return cls.from_instances(outer_y, order=order)

        inner_type = inner_type_spec.get("type")
        if inner_type is None:
            raise Exception("inner_type_spec needs a 'type' key.")

        if inner_type == "array":
            outer_y_as_array = Array(outer_y)

            # if a specific shape is given attempt to instantiate from a
            # reshaped outer_y
            shape = inner_type_spec.get("shape")
            if shape is not None:
                return cls.from_instances(
                    outer_y_as_array.reshape(shape, order=order), outer_y, order=order
                )

            # handle the case that ndim == 1 is given
            ndim = inner_type_spec.get("ndim")
            if ndim == 1:
                return cls.from_instances(
                    outer_y_as_array.flatten(order=order), outer_y, order=order
                )

            # if neither shape nor ndim is given, assume it can be an array
            # of any shape
            return cls.from_instances(outer_y_as_array, outer_y, order=order)

        raise Exception("inner_type_spec not a handled type.")
Example #4
0
    def test_basic_lindblad_lmult(self):
        """Test lmult method of Lindblad generator OperatorModel."""
        A = Array([[1.0, 2.0], [3.0, 4.0]])

        t = 1.123
        ham = (2 * np.pi * self.w * self.Z.data / 2 + 2 * np.pi * self.r *
               np.cos(2 * np.pi * self.w * t) * self.X.data / 2)
        sm = Array([[0.0, 0.0], [1.0, 0.0]])

        expected = self._evaluate_lindblad_rhs(A, ham, [sm])
        value = self.basic_lindblad.lmult(t, A.flatten(order="F"))
        self.assertAllClose(expected, value.reshape(2, 2, order="F"))
Example #5
0
def lmde_y0_reshape(generator_dim: int, y0: Array) -> Array:
    """Either: G(t)y0 is already well defined, or we assume that y0 is the input state of
    the more general form of lmde f(t, y) with f linear in y, and we assume the generator
    has been vectorized in column stacking convention.

    Args:
        generator_dim: dimension of the generator
        y0: input state

    Return:
        y0: Appropriately reshaped input state.

    Raises:
        QiskitError: If shape of y0 does not conform to any interpretation of the generator dim.
    """

    if y0.shape[0] != generator_dim:
        if y0.shape[0] * y0.shape[1] == generator_dim:
            y0 = y0.flatten(order="F")
        else:
            raise QiskitError(
                "y0.shape is incompatible with specified generator.")

    return y0
Example #6
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"))