def test_cgls_skinny(self): tol = 1e5 A = self.A x0 = da.ones(A.shape[1], chunks=(A.chunks[1], )) b = atoms2.dot(A, x0) tol_cgls = tol * da.linalg.norm(b) / da.linalg.norm(x0) x, res, iters = cg.cgls(A, b, 0., tol=tol_cgls) r = atoms2.dot(A, x) - b assert da.linalg.norm(r).compute() < tol * (1 + x.size**0.5)
def test_cgls_fat(self): tol = 1e5 A = self.B x0 = da.ones(A.shape[1], chunks=(A.chunks[1], )) b = atoms2.dot(A, x0) tol_cgls = tol * da.linalg.norm(b) / da.linalg.norm(x0) x_ln, res, iters = cg.cgls(A, b, 0., tol=tol_cgls) r = atoms2.dot(A, x_ln) - b assert da.linalg.norm(r).compute() < tol * (1 + x0.size**0.5) assert (x0 - x_ln).dot(x_ln).compute() < tol * (1 + x0.size**0.5)
def cg_project(A, x, y, tol=1e-8, **options): r""" Project (x, y) onto graph G = {(y, x) | y = Ax} via CG In particular, form outputs as: :math:`x_{out} = (1 + A^TA)^{-1}(A^Ty + x)` :math:`y_{out} = Ax_{out}` """ fmt = 'array {} compatible' assert A.shape[0] == y.shape[0] and A.shape[1] == x.shape[0], fmt.format( 'dims') assert A.chunks[0] == y.chunks[0] and A.chunks[1] == x.chunks[ 0], fmt.format('chunks') token = options.pop( 'name', 'cg-project-' + dask.base.tokenize(A, x, y, tol, **options)) nm_b, nm_x, nm_y = map(lambda nm: nm + '-' + token, ('b', 'x', 'y')) # b = A'y + x b = atoms2.gemv(1, A, y, 1, x, transpose=True, name=nm_b) A_hat = linop.DLORegularizedGram(A, transpose=False) x_out, res, iters = cg.cg_graph(A_hat, b, tol=tol, name=nm_x, **options) y_out = atoms2.dot(A, x_out, name=nm_y) x_out, y_out = dask.persist(x_out, y_out) return x_out, y_out, res, iters
def cgls_project(A, x, y, tol=1e-8, **options): r""" Project (x, y) onto graph G = {(y, x) | y = Ax} via CGLS In particular, form outputs as: :math:`x_{out} = x + argmin_x 1/2 \|Ax' - (y - Ax)\| + 1/2 \|x'\|_2^2` :math:`y_{out} = Ax_{out}` """ fmt = 'array {} compatible' assert A.shape[0] == y.shape[0] and A.shape[1] == x.shape[0], fmt.format( 'dims') assert A.chunks[0] == y.chunks[0] and A.chunks[1] == x.chunks[ 0], fmt.format('chunks') token = options.pop( 'name', 'cgls-project-' + dask.base.tokenize(A, x, y, tol, **options)) nm_b, nm_x, nm_y = map(lambda nm: nm + '-' + token, ('b', 'x', 'y')) # b = y - Ax # x_cg = argmin \|Ax' - (b)\| + \|x'\|_2^2 b = atoms2.gemv(-1, A, x, 1, y, name=nm_b) x_cg, res, iters = cg.cgls(A, b, 1, tol=tol) x_out = da.add(x, x_cg, name=nm_x) y_out = atoms2.dot(A, x_out, name=nm_y) return x_out, y_out, res, iters
def cg_reduces_residuals(A): options = dict(graph_iters=1, maxiter=1000) tol = 1e-5 b = da.ones(A.shape[0], chunks=A.chunks[0]) x, _, _ = cg.cg_graph(A, b) nrm = da.linalg.norm(b - atoms2.dot(A, x)).compute() nrm_tol = tol * (1 + da.linalg.norm(b)).compute() return nrm < nrm_tol
def cgls(A, b, rho, **options): b_hat = atoms2.dot(A, b, transpose=True) A_hat = linop.DLORegularizedGram(A, regularization=rho, transpose=False) x, _, iters = cg_graph(A_hat, b_hat, **options) res = da.linalg.norm(atoms2.dot(A, x) - b).compute() return x, res, iters
def dot_matches_expected(matrixlike, vec, expected, transpose=False): tol = 1e-15 * (1 + expected.size**0.5) output = atoms2.dot(matrixlike, vec, transpose=transpose) norm = da.linalg.norm(output - expected).compute() assert norm < tol, '|Ax - Ax_expected| < tol: {:.2e} < {:.2e}'.format(norm, tol) return True