@@ -50,6 +50,72 @@ def test_gradient_calculation_variable_noise_coefficients(self):
50
50
)
51
51
self .assertArrayAlmostEqual (ana_grad , fin_diff_grad , rtol = 1e-6 , atol = 1e-10 )
52
52
53
+ def test_n_coeffs_deriv_sorting (self ):
54
+ for _ in range (5 ):
55
+ pulse = testutil .rand_pulse_sequence (testutil .rng .integers (2 , 5 ),
56
+ testutil .rng .integers (2 , 11 ))
57
+ omega = ff .util .get_sample_frequencies (pulse , n_samples = 37 )
58
+
59
+ # Not the correct derivative, but irrelevant for comparison between analytics
60
+ n_coeffs_deriv = testutil .rng .normal (size = (len (pulse .n_opers ),
61
+ len (pulse .c_opers ),
62
+ len (pulse )))
63
+
64
+ # indices to sort sorted opers into a hypothetical unsorted original order.
65
+ n_oper_unsort_idx = np .random .permutation (np .arange (len (pulse .n_opers )))
66
+ c_oper_unsort_idx = np .random .permutation (np .arange (len (pulse .c_opers )))
67
+
68
+ # subset of c_opers and n_opers to compute the derivative for
69
+ n_choice = np .random .choice (np .arange (len (pulse .n_opers )),
70
+ testutil .rng .integers (1 , len (pulse .n_opers ) + 1 ),
71
+ replace = False )
72
+ c_choice = np .random .choice (np .arange (len (pulse .c_opers )),
73
+ testutil .rng .integers (1 , len (pulse .c_opers ) + 1 ),
74
+ replace = False )
75
+
76
+ grad = pulse .get_filter_function_derivative (
77
+ omega ,
78
+ n_coeffs_deriv = n_coeffs_deriv
79
+ )
80
+ grad_as_given = pulse .get_filter_function_derivative (
81
+ omega ,
82
+ n_oper_identifiers = pulse .n_oper_identifiers [n_oper_unsort_idx ],
83
+ control_identifiers = pulse .c_oper_identifiers [c_oper_unsort_idx ],
84
+ n_coeffs_deriv = n_coeffs_deriv [n_oper_unsort_idx [:, None ], c_oper_unsort_idx ]
85
+ )
86
+ grad_n_choice = pulse .get_filter_function_derivative (
87
+ omega ,
88
+ n_oper_identifiers = pulse .n_oper_identifiers [n_choice ],
89
+ n_coeffs_deriv = n_coeffs_deriv [n_choice ]
90
+ )
91
+ grad_c_choice = pulse .get_filter_function_derivative (
92
+ omega ,
93
+ control_identifiers = pulse .c_oper_identifiers [c_choice ],
94
+ n_coeffs_deriv = n_coeffs_deriv [:, c_choice ]
95
+ )
96
+ grad_nc_choice = pulse .get_filter_function_derivative (
97
+ omega ,
98
+ control_identifiers = pulse .c_oper_identifiers [c_choice ],
99
+ n_oper_identifiers = pulse .n_oper_identifiers [n_choice ],
100
+ n_coeffs_deriv = n_coeffs_deriv [n_choice [:, None ], c_choice ]
101
+ )
102
+ self .assertArrayAlmostEqual (
103
+ grad [np .ix_ (n_oper_unsort_idx , np .arange (len (pulse )), c_oper_unsort_idx )],
104
+ grad_as_given
105
+ )
106
+ self .assertArrayAlmostEqual (
107
+ grad [np .ix_ (n_choice , np .arange (len (pulse )))],
108
+ grad_n_choice
109
+ )
110
+ self .assertArrayAlmostEqual (
111
+ grad [np .ix_ (np .arange (len (pulse .n_opers )), np .arange (len (pulse )), c_choice )],
112
+ grad_c_choice
113
+ )
114
+ self .assertArrayAlmostEqual (
115
+ grad [np .ix_ (n_choice , np .arange (len (pulse )), c_choice )],
116
+ grad_nc_choice
117
+ )
118
+
53
119
def test_gradient_calculation_random_pulse (self ):
54
120
55
121
for d , n_dt in zip (testutil .rng .integers (2 , 5 , 5 ), testutil .rng .integers (2 , 8 , 5 )):
@@ -105,3 +171,9 @@ def test_raises(self):
105
171
omega = ff .util .get_sample_frequencies (pulse , n_samples = 13 )
106
172
with self .assertRaises (ValueError ):
107
173
ff .infidelity_derivative (pulse , 1 / omega , omega , control_identifiers = ['long string' ])
174
+
175
+ with self .assertRaises (ValueError ):
176
+ pulse .get_filter_function_derivative (
177
+ omega ,
178
+ n_coeffs_deriv = testutil .rng .normal (size = (2 , 5 , 10 ))
179
+ )
0 commit comments