Beispiel #1
0
    def test_tensor_transpose(self):
        # Test basic functionality
        paulis = np.array(util.paulis)
        I, X, Y, Z = paulis
        arr = util.tensor(I, X, Y, Z)
        arr_dims = [[2] * 4] * 2
        order = np.arange(4)

        for _ in range(20):
            order = rng.permutation(order)
            r = util.tensor_transpose(arr, order, arr_dims)
            self.assertArrayAlmostEqual(r, util.tensor(*paulis[order]))

        # Check exceptions
        with self.assertRaises(ValueError):
            # wrong arr_dims (too few dims)
            r = util.tensor_transpose(arr, order, [[2] * 3] * 2)

        with self.assertRaises(ValueError):
            # wrong arr_dims (too few dims)
            r = util.tensor_transpose(arr, order, [[2] * 4] * 1)

        with self.assertRaises(ValueError):
            # wrong arr_dims (dims too large)
            r = util.tensor_transpose(arr, order, [[3] * 4] * 2)

        with self.assertRaises(ValueError):
            # wrong order (too few axes)
            r = util.tensor_transpose(arr, (0, 1, 2), arr_dims)

        with self.assertRaises(ValueError):
            # wrong order (index 4 too large)
            r = util.tensor_transpose(arr, (1, 2, 3, 4), arr_dims)

        with self.assertRaises(ValueError):
            # wrong order (not unique axes)
            r = util.tensor_transpose(arr, (1, 1, 1, 1), arr_dims)

        with self.assertRaises(TypeError):
            # wrong order (floats instead of ints)
            r = util.tensor_transpose(arr, (0., 1., 2., 3.), arr_dims)

        # random tests
        for rank, n_args, n_broadcast in zip(rng.randint(1, 4, 10),
                                             rng.randint(3, 6, 10),
                                             rng.randint(1, 11, 10)):
            arrs = rng.standard_normal((n_args, n_broadcast, *[2] * rank))
            order = rng.permutation(n_args)
            arr_dims = [[2] * n_args] * rank

            r = util.tensor_transpose(util.tensor(*arrs, rank=rank),
                                      order=order,
                                      arr_dims=arr_dims,
                                      rank=rank)
            self.assertArrayAlmostEqual(r, util.tensor(*arrs[order],
                                                       rank=rank))
Beispiel #2
0
    def test_different_n_opers(self):
        """Test behavior when concatenating with different n_opers."""
        for d, n_dt in zip(rng.randint(2, 5, 20),
                           rng.randint(1, 11, 20)):
            opers = testutil.rand_herm_traceless(d, 10)
            letters = np.array(sample(list(string.ascii_letters), 10))
            n_idx = sample(range(10), rng.randint(2, 5))
            c_idx = sample(range(10), rng.randint(2, 5))
            n_opers = opers[n_idx]
            c_opers = opers[c_idx]
            n_coeffs = np.ones((n_opers.shape[0], n_dt))
            n_coeffs *= np.abs(rng.standard_normal((n_opers.shape[0], 1)))
            c_coeffs = rng.standard_normal((c_opers.shape[0], n_dt))
            dt = np.abs(rng.standard_normal(n_dt))
            n_ids = np.array([''.join(l) for l in letters[n_idx]])
            c_ids = np.array([''.join(l) for l in letters[c_idx]])

            pulse_1 = ff.PulseSequence(list(zip(c_opers, c_coeffs, c_ids)),
                                       list(zip(n_opers, n_coeffs, n_ids)),
                                       dt)
            permutation = rng.permutation(range(n_opers.shape[0]))
            pulse_2 = ff.PulseSequence(list(zip(c_opers, c_coeffs, c_ids)),
                                       list(zip(n_opers[permutation],
                                                n_coeffs[permutation],
                                                n_ids[permutation])),
                                       dt)
            more_n_idx = sample(range(10), rng.randint(2, 5))
            more_n_opers = opers[more_n_idx]
            more_n_coeffs = np.ones((more_n_opers.shape[0], n_dt))
            more_n_coeffs *= np.abs(rng.standard_normal(
                (more_n_opers.shape[0], 1)))
            more_n_ids = np.array([''.join(l) for l in letters[more_n_idx]])
            pulse_3 = ff.PulseSequence(list(zip(c_opers, c_coeffs, c_ids)),
                                       list(zip(more_n_opers, more_n_coeffs,
                                                more_n_ids)),
                                       dt)

            nontrivial_n_coeffs = np.abs(rng.standard_normal(
                (n_opers.shape[0], n_dt)))
            pulse_4 = ff.PulseSequence(list(zip(c_opers, c_coeffs, c_ids)),
                                       list(zip(more_n_opers,
                                                nontrivial_n_coeffs,
                                                more_n_ids)),
                                       dt)

            omega = np.geomspace(.1, 10, 50)

            # Test caching
            with self.assertRaises(ValueError):
                ff.concatenate([pulse_1, pulse_3],
                               calc_filter_function=True)

            with self.assertRaises(ValueError):
                ff.concatenate([pulse_1, pulse_3],
                               calc_pulse_correlation_FF=True)

            pulse_1.cache_filter_function(omega)
            pulse_2.cache_filter_function(omega)
            pulse_3.cache_filter_function(omega)
            pulse_11 = ff.concatenate([pulse_1, pulse_1])
            pulse_12 = ff.concatenate([pulse_1, pulse_2])
            pulse_13_1 = ff.concatenate([pulse_1, pulse_3])
            pulse_13_2 = ff.concatenate([pulse_1, pulse_3],
                                        calc_filter_function=True)

            # concatenate pulses with different n_opers and nontrivial sens.
            subset = (set.issubset(set(pulse_1.n_oper_identifiers),
                                   set(pulse_4.n_oper_identifiers)) or
                      set.issubset(set(pulse_4.n_oper_identifiers),
                                   set(pulse_1.n_oper_identifiers)))

            if not subset and (len(pulse_1.dt) > 1 or len(pulse_4.dt) > 1):
                with self.assertRaises(ValueError):
                    pulse_1 @ pulse_4

            self.assertEqual(pulse_11, pulse_12)
            # Filter functions should be the same even though pulse_2 has
            # different n_oper ordering
            self.assertArrayAlmostEqual(pulse_11._control_matrix,
                                        pulse_12._control_matrix, atol=1e-12)
            self.assertArrayAlmostEqual(pulse_11._filter_function,
                                        pulse_12._filter_function, atol=1e-12)

            should_be_cached = False
            for i in n_idx:
                if i in more_n_idx:
                    should_be_cached = True
            self.assertEqual(should_be_cached,
                             pulse_13_1.is_cached('filter_function'))

            # Test forcibly caching
            self.assertTrue(pulse_13_2.is_cached('filter_function'))
Beispiel #3
0
    def test_accuracy(self):
        paulis = np.array(util.paulis)
        I, X, Y, Z = paulis
        amps = rng.standard_normal(rng.randint(1, 11))
        pulse = ff.PulseSequence(
            [[util.tensor(X, Y, Z), amps]],
            [[util.tensor(X, I, I), np.ones_like(amps), 'XII'],
             [util.tensor(I, X, I), np.ones_like(amps), 'IXI'],
             [util.tensor(I, I, X), np.ones_like(amps), 'IIX']],
            np.ones_like(amps),
            ff.Basis.pauli(3)
        )
        omega = util.get_sample_frequencies(pulse, 50)
        pulse.cache_filter_function(omega)

        for _ in range(100):
            order = rng.permutation(range(3))
            reordered_pulse = ff.PulseSequence(
                [[util.tensor(*paulis[1:][order]), amps]],
                [[util.tensor(*paulis[[1, 0, 0]][order]), np.ones_like(amps),
                  (''.join(['XII'[o] for o in order]))],
                 [util.tensor(*paulis[[0, 1, 0]][order]), np.ones_like(amps),
                  (''.join(['IXI'[o] for o in order]))],
                 [util.tensor(*paulis[[0, 0, 1]][order]), np.ones_like(amps),
                  (''.join(['IIX'[o] for o in order]))]],
                np.ones_like(amps),
                ff.Basis.pauli(3)
            )
            reordered_pulse.cache_filter_function(omega)

            remapped_pulse = ff.remap(
                pulse, order,
                oper_identifier_mapping={
                    'A_0': 'A_0',
                    'XII': ''.join(['XII'[o] for o in order]),
                    'IXI': ''.join(['IXI'[o] for o in order]),
                    'IIX': ''.join(['IIX'[o] for o in order])
                }
            )

            self.assertEqual(reordered_pulse, remapped_pulse)
            self.assertArrayAlmostEqual(reordered_pulse.t, remapped_pulse.t)
            self.assertEqual(reordered_pulse.d, remapped_pulse.d)
            self.assertEqual(reordered_pulse.basis, remapped_pulse.basis)
            self.assertArrayAlmostEqual(reordered_pulse._omega,
                                        remapped_pulse.omega)
            self.assertArrayAlmostEqual(reordered_pulse._propagators,
                                        remapped_pulse._propagators,
                                        atol=1e-14)
            self.assertArrayAlmostEqual(reordered_pulse._total_propagator,
                                        remapped_pulse._total_propagator,
                                        atol=1e-14)
            self.assertArrayAlmostEqual(
                reordered_pulse._total_propagator_liouville,
                remapped_pulse._total_propagator_liouville,
                atol=1e-14
            )
            self.assertArrayAlmostEqual(reordered_pulse._total_phases,
                                        remapped_pulse._total_phases)
            self.assertArrayAlmostEqual(reordered_pulse._control_matrix,
                                        remapped_pulse._control_matrix,
                                        atol=1e-12)
            self.assertArrayAlmostEqual(reordered_pulse._filter_function,
                                        remapped_pulse._filter_function,
                                        atol=1e-12)

            # Test the eigenvalues and -vectors by the characteristic equation
            self.assertCorrectDiagonalization(remapped_pulse, atol=1e-14)