Skip to content

Replace REDUCTION_EPSILON_FACTOR with user-configurable output validation epsilon #687

@TysonRayJones

Description

@TysonRayJones

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:

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:

// 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).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions