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))
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'))
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)