def __init__(self, diag: Iterable, lmat: Iterable): """ Parameters ---------- diag : Iterable Diagonal vector. lmat : Iterable Low rank matrix. Raises ------ ValueError If length of ``diag`` not match with number of rows of ``lmat``. ValueError If there are non-positive numbers in ``diag``. """ diag = utils.to_numpy(diag, ndim=(1, )) lmat = utils.to_numpy(lmat, ndim=(2, )) if diag.size != lmat.shape[0]: raise ValueError("`diag` and `lmat` size not match.") if any(diag <= 0.0): raise ValueError("`diag` must be all positive.") self.diag = diag self.lmat = lmat self.dsize = self.diag.size self.lrank = min(self.lmat.shape) self.sdiag = np.sqrt(self.diag) self.ilmat = ILMat(self.lmat / self.sdiag[:, np.newaxis])
def invdot(self, x: Iterable) -> ndarray: """ Inverse dot product with vector or matrix Parameters ---------- x : Iterable Vector or matrix Returns ------- ndarray """ x = utils.to_numpy(x, ndim=(1, 2)) return x + (self._u * self._w) @ (self._u.T @ x)
def __init__(self, lmat: Iterable): """ Parameters ---------- lmat : Iterable Raises ------ ValueError When ``lmat`` is not a matrix. """ self.lmat = utils.to_numpy(lmat, ndim=(2, )) self.dsize = self.lmat.shape[0] self.lrank = min(self.lmat.shape) self._u, s, _ = np.linalg.svd(self.lmat, full_matrices=False) self._v = s**2 self._w = -self._v / (1 + self._v)
def invdot(self, x: Iterable) -> ndarray: """ Inverse dot product with vector or matrix Parameters ---------- x : Iterable Vector or matrix Returns ------- ndarray """ x = utils.to_numpy(x, ndim=(1, 2)) x = (x.T / self.sdiag).T x = self.ilmat.invdot(x) x = (x.T / self.sdiag).T return x
def test_to_numpy(array): nparray = utils.to_numpy(array) assert isinstance(nparray, np.ndarray)
def test_to_numpy_ndim(array): with pytest.raises(ValueError): utils.to_numpy(array, ndim=(1, ))