@@ -942,7 +942,7 @@ def calculate_cumulant_function(
942
942
frequency_shifts : Optional [ndarray ] = None ,
943
943
show_progressbar : bool = False ,
944
944
memory_parsimonious : bool = False ,
945
- cache_intermediates : bool = False
945
+ cache_intermediates : Optional [ bool ] = None
946
946
) -> ndarray :
947
947
r"""Calculate the cumulant function :math:`\mathcal{K}(\tau)`.
948
948
@@ -996,7 +996,7 @@ def calculate_cumulant_function(
996
996
Keep and return intermediate terms of the calculation of the
997
997
control matrix that can be reused in other computations (second
998
998
order or gradients). Otherwise the sum is performed in-place.
999
- The default is False.
999
+ Default is True if second_order=True, else False.
1000
1000
1001
1001
Returns
1002
1002
-------
@@ -1074,6 +1074,9 @@ def calculate_cumulant_function(
1074
1074
if which == 'correlations' and second_order :
1075
1075
raise ValueError ('Cannot compute correlation cumulant function for second order terms' )
1076
1076
1077
+ if cache_intermediates is None :
1078
+ cache_intermediates = second_order
1079
+
1077
1080
if decay_amplitudes is None :
1078
1081
decay_amplitudes = calculate_decay_amplitudes (pulse , spectrum , omega , n_oper_identifiers ,
1079
1082
which , show_progressbar , cache_intermediates ,
@@ -1517,27 +1520,31 @@ def calculate_second_order_filter_function(
1517
1520
result = np .zeros (shape , dtype = complex )
1518
1521
1519
1522
# intermediate results from calculation of control matrix
1520
- if not intermediates :
1521
- # Require absolut times for calculation of control matrix at step g
1523
+ if intermediates is None :
1524
+ intermediates = dict ()
1525
+
1526
+ # Work around possibly populated intermediates dict with missing keys
1527
+ n_opers_transformed = intermediates .get ('n_opers_transformed' ,
1528
+ _transform_hamiltonian (eigvecs , n_opers , n_coeffs ))
1529
+ try :
1530
+ basis_transformed_cache = intermediates ['basis_transformed' ]
1531
+ ctrlmat_step_cache = intermediates ['control_matrix_step' ]
1532
+ have_intermediates = True
1533
+ except KeyError :
1534
+ have_intermediates = False
1535
+ # No cache. Precompute some things and perform the costly computations
1536
+ # during each loop iteration below
1522
1537
t = np .concatenate (([0 ], np .asarray (dt ).cumsum ()))
1523
- # Cheap to precompute as these don't use a lot of memory
1524
1538
eigvecs_propagated = _propagate_eigenvectors (propagators [:- 1 ], eigvecs )
1525
- n_opers_transformed = _transform_hamiltonian (eigvecs , n_opers , n_coeffs )
1526
- # These are populated anew during every iteration, so there is no need
1527
- # to keep every time step
1528
1539
basis_transformed = np .empty (basis .shape , dtype = complex )
1529
1540
ctrlmat_step = np .zeros ((len (n_coeffs ), len (basis ), len (omega )), dtype = complex )
1530
- else :
1531
- n_opers_transformed = intermediates ['n_opers_transformed' ]
1532
- basis_transformed_cache = intermediates ['basis_transformed' ]
1533
- ctrlmat_step_cache = intermediates ['control_matrix_step' ]
1534
1541
1535
1542
step_expr = oe .contract_expression ('oijmn,akij,blmn->abklo' , int_buf .shape ,
1536
1543
* [(len (n_coeffs ), len (basis ), d , d )]* 2 ,
1537
1544
optimize = [(0 , 1 ), (0 , 1 )])
1538
1545
for g in util .progressbar_range (len (dt ), show_progressbar = show_progressbar ,
1539
1546
desc = 'Calculating second order FF' ):
1540
- if not intermediates :
1547
+ if not have_intermediates :
1541
1548
basis_transformed = _transform_by_unitary (eigvecs_propagated [g ], basis ,
1542
1549
out = basis_transformed )
1543
1550
# Need to compute G^(g) since no cache given. First initialize
0 commit comments