Source code for pycif.plugins.modes.adjtl_test.execute
import copy
from logging import info
import numpy as np
from .testing_adj import testing_AD_whole
from .testing_TL import testing_TL_linearity, testing_TL_Taylor
from .testing_adj_sym import testing_AD_symmetry
[docs]
def execute(self, **kwargs):
"""Dispatch and run the requested adjoint / tangent-linear test.
Builds the perturbation increment ``dx`` (or ``chi`` in the reduced space)
according to ``incrmode`` and ``testspace``, then delegates to the
appropriate test function based on ``testtype``:
* ``'adj'`` — full adjoint test via :func:`testing_AD_whole`.
* ``'tllinearity'`` — linearity test via :func:`testing_TL_linearity`.
* ``'tltaylor'`` — Taylor expansion test via :func:`testing_TL_Taylor`.
* ``'adj_sym'`` — symmetry test via :func:`testing_AD_symmetry`.
Args:
self (Plugin): mode plugin carrying all configuration attributes.
**kwargs: forwarded verbatim to the individual test functions.
Returns:
float or None: for ``testtype='adj'``, the adjoint-test ratio
expressed in multiples of machine epsilon; ``None`` for other test
types.
"""
# Working directory
workdir = self.workdir
# Control vector
controlvect = self.controlvect
# Observation operator
obsoper = self.obsoperator
# Obsvervation vector
obsvect = self.obsvect
# Simulation window
datei = self.datei
datef = self.datef
# Check that the observation vector is not empty
if len(obsvect.yobs) == 0:
raise Exception(
"WARNING: trying to run a test of the adjoint with no "
"observation points! Please check your monitor file"
)
# Check that the control vector is not empty
if controlvect.dim == 0:
raise Exception(
"WARNING! There is no element in your control vector. "
"Please check your data vector."
)
# Increments in x
increments = self.increments
incrmode = self.incrmode
testspace = self.testspace
testtype = self.testtype
if incrmode == "rand":
np.random.seed(self.random_seed)
if testspace == "control":
if incrmode == "cst":
controlvect.dx = \
increments * controlvect.std
elif incrmode == "rand":
controlvect.dx = (
np.random.normal(0, increments, controlvect.dim)
* controlvect.std
)
elif testspace == "chi":
if incrmode == "cst":
controlvect.chi[:] = increments
elif incrmode == "rand":
controlvect.chi = np.random.normal(0, increments,
controlvect.chi_dim)
controlvect.dx = (
controlvect.sqrtbprod(controlvect.chi, **kwargs) - controlvect.xb
)
if testspace not in ["control", "chi"] or incrmode not in ["cst", "rand"]:
raise ValueError(
f"Unsupported increment mode '{incrmode}' or test space '{testspace}'. "
+ "Please check the definition of the running mode in your Yaml file"
)
controlvect.x = copy.deepcopy(controlvect.xb)
controlvect.dx_save = copy.deepcopy(controlvect.dx)
# Some verbose
info("Computing the test of the adjoint")
# Get the machine accuracy
accuracy = np.finfo(np.float64).eps
if testtype == 'tllinearity':
testing_TL_linearity(self, accuracy)
elif testtype == 'tltaylor':
testing_TL_Taylor(self, accuracy)
elif testtype == 'adj_sym':
testing_AD_symmetry(self, accuracy, increments, testspace)
if testtype == 'adj':
return testing_AD_whole(self, accuracy, testspace)