-
Notifications
You must be signed in to change notification settings - Fork 165
Description
Many validation functions consult global_validationEpsilon, a zero or positive real scalar, to determine whether or not user input satisfies (approximately) mathematical preconditions. Such functions are documented to throw an error if the input deviates beyond epsilon from the intended domain.
Other functions also check that function output approximately satisfies postconditions. For example, calcExpecPauliStr() asserts that its output quantity is approximately real; that its imaginary component is within distance epsilon to zero. Many of those functions actually scale global_validationEpsilon by a currently fixed constant REDUCTION_EPSILON_FACTOR:
QuEST/quest/src/core/validation.cpp
Lines 4234 to 4247 in 2655690
| void validate_expecPauliStrValueIsReal(qcomp value, bool isDensMatr, const char* caller) { | |
| if (isNumericalValidationDisabled()) | |
| return; | |
| /// @todo include imag(value) in error message when non-integers are supported | |
| string msg = (isDensMatr)? | |
| report::CALC_DENSMATR_EXPECTED_PAULI_STR_VALUE_WAS_NOT_APPROX_REAL: | |
| report::CALC_STATEVEC_EXPECTED_PAULI_STR_VALUE_WAS_NOT_APPROX_REAL; | |
| qreal eps = REDUCTION_EPSILON_FACTOR * global_validationEpsilon; | |
| assertThat(util_isApproxReal(value, eps), msg, caller); | |
| } |
where currently:
QuEST/quest/src/core/validation.cpp
Lines 1194 to 1200 in 2655690
| // this file validates that the outputs of reductions (like | |
| // calcFidelity) are within numerical bounds (e.g. approx | |
| // real). Because these reductions combine exponentially | |
| // many decimals, they are much less precise than API inputs, | |
| // so should be validated with a more tolerant epsilon. We | |
| // here hackily specify the factor by which to expand eps. | |
| qreal REDUCTION_EPSILON_FACTOR = 100; |
This is because the functions result from a reduction of many scalars and so contain heightened numerical error, compounding numerical ill-conditions. As such, a comparison against global_validationEpsilon is too strict. In a sense, such 'numerically damaged' outputs should tolerate greater error than 'clean' user inputs.
The user of constant REDUCTION_EPSILON_FACTOR is a hacky stopgap. Ideally, we should separate global_validationEpsilon into input and output epsilons, and allow the user the independently vary them (both at runtime using the debug functions, and through pre-runtime defaults via environment variables).