spook package¶
spook module¶
- class spook.base.SpookBase(B, A, mode='raw', G=None, lsparse=None, lsmooth=None, Bsmoother='laplacian', Asmoother='laplacian', normalize=True)[source]¶
Bases:
objectBase class for Spook solvers
- property AGscale¶
Product s_A * s_G, where s_A and s_G are the normalization factors of A and G.
- property AGtAG¶
Tensor product of AtA and GtG Some children classes need this tensor itself, some need its upper triangular part only, so I make it a non-cache property A child class can cache it/its upper triangular part if necessary
- property Na¶
Dimension of single-shot A
- property NaTuple¶
Shape of single-shot A. Most frequently, it is (Nw,) But in the case of delay binning, it is (Nw, Nt)
- property Ng¶
(Dimension of X) / Na
- getXopt(lsparse=None, lsmooth=None, orig_scale=True)[source]¶
Solve for the optimal X, :param lsparse: The regularization hyperparameters :type lsparse: float|None, lsmooth: float|tuple|None :param orig_scale: whether to scale it back to the original scale :type orig_scale: bool
- residueL2(X=None)[source]¶
Calculate the rmse of the linear model given variable X, in the original (unscaled) problem rmse = |(A otimes G)X - B|_2 :param X: Optimization (unscaled) variable. If None, use the last solved X :type X: np.ndarray
- set_btb(btb: float)[source]¶
Set the constant term in the quadratic form For 1D problem, btb is the sum of b^2 across all shots For 2D problem, btb is the sum of b^2 across all shots and all KE bins
- smoothness(X=None, dim='w')[source]¶
Evaluate the smoothness of variable X, along the dimension dim. The smoothness is defined as sqrt(X.T @ LL @ X), where LL is the smoothness operator
by default LL is the square of finite difference Laplacian operator. No lsmooth* is applied.
- Parameters:
X (the solution to evaluate)
dim ('w' or 'b' or 't') – ‘w’: along the photon frequency axis ‘b’: along the interested property axis ‘t’: along the delay axis (if applicable)
- smoothness_drop_boundaries = True¶
- solve(lsparse=None, lsmooth=None)[source]¶
ONLY for the base class For every derived class, PLEASE REDEFINE!
- verbose = False¶
- class spook.quad_program.SpookL1(B, A, mode='raw', G=None, lsparse=1, lsmooth=(0.1, 0.1), osqp_settings={}, **kwargs)[source]¶
Bases:
SpookQPBaseL1 sparsity w/o non-negativity. This is lasso, which requires auxilary variables
- class spook.quad_program.SpookPos(B, A, mode='raw', G=None, lsparse=1, lsmooth=(0.1, 0.1), osqp_settings={}, **kwargs)[source]¶
Bases:
SpookQPBaseNonnegativity constraint Definitely a Quadratic Program
- class spook.quad_program.SpookPosL1(B, A, mode='raw', G=None, lsparse=1, lsmooth=(0.1, 0.1), osqp_settings={}, **kwargs)[source]¶
Bases:
SpookPosPositivity + L1 sparsity L1 sparsity is just a linear term
- class spook.quad_program.SpookPosL2(B, A, mode='raw', G=None, lsparse=1, lsmooth=(0.1, 0.1), osqp_settings={}, **kwargs)[source]¶
Bases:
SpookPosNon-negativity + L2^2 sparsity, i.e. Ridge w/ Non-negativity constraints L1 sparsity is just a linear term
- class spook.quad_program.SpookQPBase(B, A, mode='raw', G=None, lsparse=1, lsmooth=(0.1, 0.1), osqp_settings={}, **kwargs)[source]¶
Bases:
SpookBase- calc_total_smoother_triu()[source]¶
CALCULATE Total Smoothness regularization operator lsma * (La.T @ La otimes Ib) + lsmb * (Ia otimes Bsmoother)
This method always recalculates
- Returns:
The upper triangular part of tensor product matrix, so DON’T use if the solver is vectorized over dimension b
- verbose = False¶
- class spook.lin_solve.SpookLinSolve(B, A, mode='raw', G=None, lsparse=1, lsmooth=(0.1, 0.1), **kwargs)[source]¶
Bases:
SpookBaseSpooktroscopy that involves only linear eq solving This means: no positivity constraint L2 squared sparsity
- solve(lsparse=None, lsmooth=None)[source]¶
Solve the linear system, since there is only a Tikhonov regularization but no constraint.
- verbose = False¶
spook.utils module¶
- spook.utils.calcL2fromContracted(Xo, AtA, Bcontracted, trBtB, GtG=None)[source]¶
Calculates the residual L2 norm from the contracted tensors. :param Xo: :type Xo: ndarray, value of the optimization variable :param AtA: :type AtA: ndarray, AtA matrix :param Bcontracted: :type Bcontracted: ndarray, AtB matrix if G is None, otherwise Bcontracted = AtB @ G :param trBtB: :type trBtB: float, constant in the mean square error :param GtG: :type GtG: ndarray, (optional) GtG matrix. If None, it means G=identity
- spook.utils.dict_innerprod(dictA, dictB, Aroi=None)[source]¶
Inner product of two tensors represented as dictionaries, with the contracted dimension being the keys.
spook.xval module¶
- class spook.xval.XValidation(solver_class, datasets, **kwargs)[source]¶
Bases:
objectClass for cross-validation of a solver.
- calc_residual(hyperparams, dset='val', avg=True)[source]¶
Validate the hyperparameters on the chosen set. :param hyperparams: The hyperparameters to validate.
Each tuple must be in the form of (lsparse, lsmooth) 2D array will be interpreted as a list of (lsparse, *lsmooth)
- Parameters:
dset (str) – which dataset to validate on. Must be either ‘train’ or ‘val’
avg (bool) – If True, return the average of the residuals. Otherwise, return the residuals for each train/val split
- Returns:
The L2 norm (no square) of the residuals. If avg is True, return the root-mean-squared of the L2 norm over the k splits
- Return type:
float | np.ndarray
- property k¶
spook.vmi_special module¶
spook.contraction_utils module¶
Note
Function adaptive_contraction in this module serves in the raw mode of the spook solver. It is not parallelized, so it is slow for large datasets. For TMO users, a good alternative is the outer-product accumulation application in the tmo-preproc repo.
- spook.contraction_utils.adaptive_contraction(A, B, a_slice=None, b_slice=None, keep_dims=False)[source]¶
Contract two tensors A, B along axis0, generalizing numpy.tensordot in terms of memory limit. :param A: two tensors stores as arrays/lists/dictionaries.
Arrays and lists can be mixed-and-matched, but if one of A,B is a dictionary, the other has to be too, with the same set of keys.
- Parameters:
B – two tensors stores as arrays/lists/dictionaries. Arrays and lists can be mixed-and-matched, but if one of A,B is a dictionary, the other has to be too, with the same set of keys.
a_slice – optional slicing objects that can be applied to each singleshot data in A, B, respectively
b_slice – optional slicing objects that can be applied to each singleshot data in A, B, respectively
keep_dims – controlling flag regarding whether the dimensions of the final tensor is kept. If False, the final tensor will be reshaped into a matrice as if A, B were two matrices with axis0 being the shot id while axis1 being the rest.
- spook.contraction_utils.shots_asarray(shots_iterable, shots_select=None, singleshot_slice=None)[source]¶
Iterate through an iterable object shots_iterable, apply optional singleshot_slice to each singleshot array, then stack up the sliced arrays into an array, whose axis0 is shot id.
- Use shots_select to specify which shots to stack into the matrix:
If the iterable is a dictionary, shots_select is a list of keys If the iterable is a list of np.ndarray, shots_select is a list of indices or a slice
This is a lower-level function that only accepts formated singleshot_slice object, if not None