Source code for pycif.plugins.controlvects.standard.build_full_b

import numpy as np

from ....utils.iterators import iter_tracers


[docs] def build_b_block(controlvect, tracer): """Build the B matrix block corresponding to 'tracer' Args: controlvect (ControlVect): the controlvector plugin tracer (tracer plugin): the tracer to compute the corresping B block Returns: 2D array: B matrix block """ b_horiz = np.eye(tracer.dim) # Deals with non-diagonal horizontal correlations if hasattr(tracer, "hcorrelations") and tracer.hresol == "hpixels": corr = tracer.hcorrelations sqrt_evalues = corr.sqrt_evalues evectors = corr.evectors btmp = evectors.dot(np.diag(sqrt_evalues ** 2)).dot(evectors.T) for i in range(tracer.ndates * tracer.vresoldim): slc = slice(i * tracer.hresoldim, (i+1) * tracer.hresoldim) b_horiz[slc, slc] = btmp b_temp = np.eye(tracer.dim) # Deals with non-diagonal temporal correlations if hasattr(tracer, "tcorrelations"): corr = tracer.tcorrelations sqrt_evalues = corr.sqrt_evalues evectors = corr.evectors btmp = evectors.dot(np.diag(sqrt_evalues ** 2)).dot(evectors.T) for i in range(tracer.hresoldim * tracer.vresoldim): rdim = range(i, tracer.dim, tracer.hresoldim * tracer.vresoldim) slc = np.ix_(rdim, rdim) b_temp[slc] = btmp start = tracer.xpointer stop = tracer.xpointer + tracer.dim b_block = ( controlvect.std[start:stop, np.newaxis] * controlvect.std[start:stop] * b_temp.dot(b_horiz) ) return b_block
[docs] def build_b(controlvect, component=None, parameter=None): """Compute the full B matrix Args: controlvect (ControlVect): the controlvector plugin component (str, optional): only compute B block for a given tracer ('component', 'tracer'). Must be used with the 'tracer' argument. Defaults to None. parameter (str, optional): only compute B block for a given tracer ('component', 'tracer'). Must be used with the 'component' argument. Defaults to None.Defaults to None. Returns: 2D array: B matrix """ # Checking if 'component' and 'parameter' arguments are all None or if none is 'None' if ((component is None and parameter is not None) or (component is not None and parameter is None)): raise ValueError( "'component' and 'tracer' arguments must used together, " "one can not be 'None' while the other is not" ) datavect = controlvect.datavect # Building only one block if component is not None: # At this point 'parameter' can not be 'None' try: # Directly getting tracer plugin comp = getattr(datavect.components, component) tracer = getattr(comp, parameter) except AttributeError as e: raise ValueError( f"tracer '{component}/{parameter}' not found") from e if not tracer.iscontrol: raise ValueError( f"tracer '{component}/{parameter}' is not in the control vector") return build_b_block(controlvect, tracer) # Building the full B matrix b_full = np.eye(controlvect.dim) for _, tracer in iter_tracers(datavect): if not tracer.iscontrol: continue start = tracer.xpointer stop = tracer.xpointer + tracer.dim b_full[start:stop, start:stop] = build_b_block(controlvect, tracer) return b_full