Skip to content

Commit 604b3d6

Browse files
committed
add tests for uncertainty covariance matrices
1 parent c11fdbd commit 604b3d6

1 file changed

Lines changed: 62 additions & 0 deletions

File tree

test/rmgpy/tools/uncertaintyTest.py

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -343,6 +343,68 @@ def test_local_analysis(self):
343343
assert np.isclose(sorted_thermo_variances, expected_correlated_thermo_variances).all()
344344
assert sorted_thermo_names == expected_correlated_thermo_labels
345345

346+
def test_covariance_matrices(self):
347+
"""
348+
Test that the covariance matrices are being constructed correctly, and that the correlated uncertainties are different from the uncorrelated ones
349+
"""
350+
351+
# have to add an extra reaction to see any kinetic correlations
352+
# copy reaction 4 and change the index so it is a new reaction, but with the same source (rate rule) as the original reaction
353+
extra_reaction = copy.deepcopy(self.uncertainty.reaction_list[4])
354+
self.uncertainty.reaction_list.append(extra_reaction)
355+
try: # this will still error out if there's a problem, but will reset the reaction list so it doesn't affect other tests
356+
self.uncertainty.extract_sources_from_model() # this will assign the same source to the new reaction as the original reaction
357+
358+
self.uncertainty.assign_parameter_uncertainties(correlated=False)
359+
uncorrelated_thermo_inputs = np.array(self.uncertainty.thermo_input_uncertainties)
360+
uncorrelated_kinetic_inputs = np.array(self.uncertainty.kinetic_input_uncertainties)
361+
362+
self.uncertainty.assign_intermediate_uncertainties(correlated=False)
363+
uncorrelated_thermo_covariance = self.uncertainty.get_thermo_covariance_matrix()
364+
uncorrelated_kinetic_covariance = self.uncertainty.get_kinetic_covariance_matrix()
365+
366+
self.uncertainty.assign_intermediate_uncertainties(correlated=True)
367+
correlated_thermo_covariance = self.uncertainty.get_thermo_covariance_matrix()
368+
correlated_kinetic_covariance = self.uncertainty.get_kinetic_covariance_matrix()
369+
Sigma_ww_thermo = self.uncertainty._get_intermediate_thermo_covariance_matrix()
370+
Sigma_ww_kinetics = self.uncertainty._get_intermediate_kinetics_covariance_matrix()
371+
finally:
372+
self.uncertainty.reaction_list.pop() # remove the extra reaction so it doesn't affect other tests
373+
374+
# check that the diagonal elements of the correlated and uncorrelated covariance matrices are the same and equal to the squares of the input uncertainties
375+
np.testing.assert_allclose(np.diag(uncorrelated_thermo_covariance), np.float_power(uncorrelated_thermo_inputs, 2.0), rtol=1e-4)
376+
np.testing.assert_allclose(np.diag(correlated_thermo_covariance), np.float_power(uncorrelated_thermo_inputs, 2.0), rtol=1e-4)
377+
np.testing.assert_allclose(np.diag(uncorrelated_kinetic_covariance), np.float_power(uncorrelated_kinetic_inputs, 2.0), rtol=1e-4)
378+
np.testing.assert_allclose(np.diag(correlated_kinetic_covariance), np.float_power(uncorrelated_kinetic_inputs, 2.0), rtol=1e-4)
379+
380+
# check that the off-diagonal elements of the uncorrelated covariance matrix are zero
381+
off_diagonal_kinetic_uncorrelated = uncorrelated_kinetic_covariance - np.diag(np.diag(uncorrelated_kinetic_covariance))
382+
assert np.allclose(off_diagonal_kinetic_uncorrelated, 0, atol=1e-8)
383+
off_diagonal_thermo_uncorrelated = uncorrelated_thermo_covariance - np.diag(np.diag(uncorrelated_thermo_covariance))
384+
assert np.allclose(off_diagonal_thermo_uncorrelated, 0, atol=1e-8)
385+
386+
# check that the off-diagonal elements of the correlated covariance matrix are not all zero
387+
off_diagonal_kinetic_correlated = correlated_kinetic_covariance - np.diag(np.diag(correlated_kinetic_covariance))
388+
assert not np.allclose(off_diagonal_kinetic_correlated, 0, atol=1e-8)
389+
off_diagonal_thermo_correlated = correlated_thermo_covariance - np.diag(np.diag(correlated_thermo_covariance))
390+
assert not np.allclose(off_diagonal_thermo_correlated, 0, atol=1e-8)
391+
392+
# check that the correlated covariance matrices are symmetric
393+
assert np.allclose(correlated_kinetic_covariance, correlated_kinetic_covariance.T, atol=1e-8)
394+
assert np.allclose(correlated_thermo_covariance, correlated_thermo_covariance.T, atol=1e-8)
395+
assert np.allclose(Sigma_ww_kinetics, Sigma_ww_kinetics.T, atol=1e-8)
396+
assert np.allclose(Sigma_ww_thermo, Sigma_ww_thermo.T, atol=1e-8)
397+
398+
# check that the matrix is positive semi-definite by confirming that all eigenvalues are non-negative
399+
kinetic_eigenvalues = np.linalg.eigvals(correlated_kinetic_covariance)
400+
assert np.all(kinetic_eigenvalues >= -1e-8) # allow for small numerical errors
401+
thermo_eigenvalues = np.linalg.eigvals(correlated_thermo_covariance)
402+
assert np.all(thermo_eigenvalues >= -1e-8) # allow for small numerical errors
403+
intermediate_kinetic_eigenvalues = np.linalg.eigvals(Sigma_ww_kinetics)
404+
assert np.all(intermediate_kinetic_eigenvalues >= -1e-8)
405+
intermediate_thermo_eigenvalues = np.linalg.eigvals(Sigma_ww_thermo)
406+
assert np.all(intermediate_thermo_eigenvalues >= -1e-8)
407+
346408
def test_specific_species_uncertainties(self):
347409
"""
348410
Test uncertainties for a few specific examples

0 commit comments

Comments
 (0)