def test_minres_deflation(self):
        # Create sparse symmetric problem.
        num_unknowns = 100
        A = self._create_sparse_herm_indef_matrix(num_unknowns)
        rhs = np.ones( (num_unknowns,1) )
        x0 = np.zeros( (num_unknowns,1) )

        # get projection
        from scipy.sparse.linalg import eigs
        num_vecs = 6
        D, W = eigs(A, k=num_vecs, v0=np.ones((num_unknowns,1)))

        # Uncomment next lines to perturb W
        #W = W + 1.e-10*np.random.rand(W.shape[0], W.shape[1])
        #from scipy.linalg import qr
        #W, R = qr(W, mode='economic')

        AW = nm._apply(A, W)
        P, x0new = nm.get_projection( W, AW, rhs, x0 )

        # Solve using MINRES.
        tol = 1.0e-9
        out = nm.minres( A, rhs, x0new, Mr=P, tol=tol, maxiter=num_unknowns-num_vecs, full_reortho=True, return_basis=True )

        # TODO: move to new unit test
        o = nm.get_p_ritz( W, AW, out['Vfull'], out['Hfull'] )
        ritz_vals, ritz_vecs = nm.get_p_ritz( W, AW, out['Vfull'], out['Hfull'] )

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - A * out['xk']
        self.assertAlmostEqual( np.linalg.norm(res)/np.linalg.norm(rhs), 0.0, delta=tol )
Exemplo n.º 2
0
    def test_get_projection(self):
        N = 100
        A = scipy.sparse.spdiags(range(1, N + 1), [0], N, N)
        b = np.ones((N, 1))
        x0 = np.ones((N, 1))

        # 'last' 2 eigenvectors
        W = np.zeros((N, 2))
        W[-2, 0] = 1.
        W[-1, 1] = 1
        AW = A * W

        P, x0new = nm.get_projection(W, AW, b, x0)

        # Check A*(P*I) against exact A*P
        AP = A * (P * np.eye(N))
        AP_exact = scipy.sparse.spdiags(
            list(range(1, N - 1)) + [0, 0], [0], N, N)
        self.assertAlmostEqual(np.linalg.norm(AP - AP_exact), 0.0, delta=1e-14)

        # Check x0new
        x0new_exact = np.ones((N, 1))
        x0new_exact[N - 2:N, 0] = [1. / (N - 1), 1. / N]
        self.assertAlmostEqual(np.linalg.norm(x0new - x0new_exact),
                               0.0,
                               delta=1e-14)
Exemplo n.º 3
0
    def test_get_ritz(self):
        N = 10
        A = scipy.sparse.spdiags(range(1, N + 1), [0], N, N)
        b = np.ones((N, 1))
        x0 = np.ones((N, 1))

        # 'last' 2 eigenvectors
        W = np.zeros((N, 2))
        W[-2, 0] = 1.
        W[-1, 1] = 1
        AW = A * W

        # Get the projection
        P, x0new = nm.get_projection(W, AW, b, x0)

        # Run MINRES (we are only interested in the Lanczos basis and tridiag matrix)
        out = nm.minres(A,
                        b,
                        x0new,
                        Mr=P,
                        tol=1e-14,
                        maxiter=11,
                        full_reortho=True,
                        return_basis=True)

        # Get Ritz pairs
        ritz_vals, ritz_vecs = nm.get_p_ritz(W, AW, out['Vfull'], out['Hfull'])

        # Check Ritz pair residuals
        #ritz_res_exact = A*ritz_vecs - np.dot(ritz_vecs,np.diag(ritz_vals))
        #for i in range(0,len(ritz_vals)):
        #norm_ritz_res_exact = np.linalg.norm(ritz_res_exact[:,i])
        #self.assertAlmostEqual( abs(norm_ritz_res[i] - norm_ritz_res_exact), 0.0, delta=1e-13 )

        # Check if Ritz values / vectors corresponding to W are still there ;)
        order = np.argsort(ritz_vals)
        # 'last' eigenvalue
        self.assertAlmostEqual(abs(ritz_vals[order[-1]] - N), 0.0, delta=1e-13)
        self.assertAlmostEqual(abs(ritz_vals[order[-2]] - (N - 1)),
                               0.0,
                               delta=1e-13)
        # now the eigenvectors
        self.assertAlmostEqual(abs(nm._ipstd(ritz_vecs[:, order[-1]], W[:,
                                                                        1])),
                               1.0,
                               delta=1e-13)
        self.assertAlmostEqual(abs(nm._ipstd(ritz_vecs[:, order[-2]], W[:,
                                                                        0])),
                               1.0,
                               delta=1e-13)
Exemplo n.º 4
0
    def test_minres_deflation(self):
        # Create sparse symmetric problem.
        num_unknowns = 100
        A = self._create_sparse_herm_indef_matrix(num_unknowns)
        rhs = np.ones((num_unknowns, 1))
        x0 = np.zeros((num_unknowns, 1))

        # get projection
        from scipy.sparse.linalg import eigs
        num_vecs = 6
        D, W = eigs(A, k=num_vecs, v0=np.ones((num_unknowns, 1)))

        # Uncomment next lines to perturb W
        #W = W + 1.e-10*np.random.rand(W.shape[0], W.shape[1])
        #from scipy.linalg import qr
        #W, R = qr(W, mode='economic')

        AW = nm._apply(A, W)
        P, x0new = nm.get_projection(W, AW, rhs, x0)

        # Solve using MINRES.
        tol = 1.0e-9
        out = nm.minres(A,
                        rhs,
                        x0new,
                        Mr=P,
                        tol=tol,
                        maxiter=num_unknowns - num_vecs,
                        full_reortho=True,
                        return_basis=True)

        # TODO: move to new unit test
        o = nm.get_p_ritz(W, AW, out['Vfull'], out['Hfull'])
        ritz_vals, ritz_vecs = nm.get_p_ritz(W, AW, out['Vfull'], out['Hfull'])

        # Make sure the method converged.
        self.assertEqual(out['info'], 0)
        # Check the residual.
        res = rhs - A * out['xk']
        self.assertAlmostEqual(np.linalg.norm(res) / np.linalg.norm(rhs),
                               0.0,
                               delta=tol)
    def test_get_ritz(self):
        N = 10
        A = scipy.sparse.spdiags( range(1,N+1), [0], N, N)
        b = np.ones( (N,1) )
        x0 = np.ones( (N,1) )

        # 'last' 2 eigenvectors
        W = np.zeros( (N,2) )
        W[-2,0]=1.
        W[-1,1]=1
        AW = A*W

        # Get the projection
        P, x0new = nm.get_projection(W, AW, b, x0)

        # Run MINRES (we are only interested in the Lanczos basis and tridiag matrix)
        out = nm.minres(A, b, x0new, Mr=P, tol=1e-14, maxiter=11,
                        full_reortho=True,
                        return_basis=True
                        )

        # Get Ritz pairs
        ritz_vals, ritz_vecs = nm.get_p_ritz(W, AW,
                                             out['Vfull'],
                                             out['Hfull']
                                             )

        # Check Ritz pair residuals
        #ritz_res_exact = A*ritz_vecs - np.dot(ritz_vecs,np.diag(ritz_vals))
        #for i in range(0,len(ritz_vals)):
            #norm_ritz_res_exact = np.linalg.norm(ritz_res_exact[:,i])
            #self.assertAlmostEqual( abs(norm_ritz_res[i] - norm_ritz_res_exact), 0.0, delta=1e-13 )

        # Check if Ritz values / vectors corresponding to W are still there ;)
        order = np.argsort(ritz_vals)
        # 'last' eigenvalue
        self.assertAlmostEqual( abs(ritz_vals[order[-1]] - N), 0.0, delta=1e-13 )
        self.assertAlmostEqual( abs(ritz_vals[order[-2]] - (N-1)), 0.0, delta=1e-13 )
        # now the eigenvectors
        self.assertAlmostEqual( abs(nm._ipstd(ritz_vecs[:,order[-1]],W[:,1])), 1.0, delta=1e-13 )
        self.assertAlmostEqual( abs(nm._ipstd(ritz_vecs[:,order[-2]],W[:,0])), 1.0, delta=1e-13 )
    def test_get_projection(self):
        N = 100
        A = scipy.sparse.spdiags( range(1,N+1), [0], N, N)
        b = np.ones( (N,1) )
        x0 = np.ones( (N,1) )

        # 'last' 2 eigenvectors
        W = np.zeros( (N,2) )
        W[-2,0]=1.
        W[-1,1]=1
        AW = A*W

        P, x0new = nm.get_projection(W, AW, b, x0)

        # Check A*(P*I) against exact A*P
        AP = A*(P*np.eye(N))
        AP_exact = scipy.sparse.spdiags(list(range(1,N-1))+[0,0], [0], N, N)
        self.assertAlmostEqual( np.linalg.norm(AP-AP_exact), 0.0, delta=1e-14 )

        # Check x0new
        x0new_exact = np.ones( (N,1) )
        x0new_exact[N-2:N,0] = [1./(N-1),1./N]
        self.assertAlmostEqual( np.linalg.norm(x0new-x0new_exact), 0.0, delta=1e-14 )
Exemplo n.º 7
0
def _solve_system(modeleval, filename, timestep, mu, args):
    # read the mesh
    print('Reading current psi...',)
    start = time.time()
    mesh, point_data, field_data = voropy.read(filename,
                                               timestep=timestep
                                               )
    total = time.time() - start
    print('done (%gs).' % total)

    num_coords = len( mesh.node_coords )
    # --------------------------------------------------------------------------
    # set psi at which to create the Jacobian
    print('Creating initial guess and right-hand side...',)
    start = time.time()
    current_psi = (point_data['psi'][:,0] + 1j * point_data['psi'][:,1]).reshape(-1,1)

    # Perturb a bit.
    eps = 1.0e-10
    perturbation = eps * (np.random.rand(num_coords) + 1j * np.random.rand(num_coords))
    current_psi += perturbation.reshape(current_psi.shape)

    if args.bordering:
        phi0 = np.zeros((num_coords+1,1), dtype=complex)
        # right hand side
        x = np.empty((num_coords+1,1), dtype=complex)
        x[0:num_coords] = current_psi
        x[num_coords] = 0.0
    else:
        # create right hand side and initial guess
        phi0 = np.zeros( (num_coords,1), dtype=complex )
        x = current_psi
    # right hand side
    #rhs = np.ones( (num_coords,1), dtype=complex )

    #rhs = np.empty( num_coords, dtype = complex )
    #radius = np.random.rand( num_coords )
    #arg    = np.random.rand( num_coords ) * 2.0 * cmath.pi
    #for k in range( num_coords ):
        #rhs[ k ] = cmath.rect(radius[k], arg[k])
    rhs = modeleval.compute_f(x=x, mu=mu, g=1.0)
    end = time.time()
    print('done. (%gs)' % (end - start))
    print('||rhs|| = %g' % np.sqrt(modeleval.inner_product(rhs, rhs)))
    # --------------------------------------------------------------------------
    # create the linear operator
    print('Getting Jacobian...',)
    start_time = time.clock()
    jacobian = modeleval.get_jacobian(x=x, mu=mu, g=1.0)
    end_time = time.clock()
    print('done. (%gs)' % (end_time - start_time))

    # create precondictioner object
    print('Getting preconditioner...',)
    start_time = time.clock()
    prec = modeleval.get_preconditioner_inverse(x=x, mu=mu, g=1.0)
    end_time = time.clock()
    print('done. (%gs)' % (end_time - start_time))

    # --------------------------------------------------------------------------
    # Get reference solution
    #print 'Get reference solution (dim = %d)...' % (2*num_coords),
    #start_time = time.clock()
    #ref_sol, info, relresvec, errorvec = nm.minres_wrap( jacobian, rhs,
                                          #x0 = phi0,
                                          #tol = 1.0e-14,
                                          #M = prec,
                                          #inner_product = modeleval.inner_product,
                                          #explicit_residual = True
                                        #)
    #end_time = time.clock()
    #if info == 0:
        #print 'success!',
    #else:
        #print 'no convergence.',
    #print ' (', end_time - start_time, 's,', len(relresvec)-1 ,' iters).'

    if args.use_deflation:
        W = 1j * x
        AW = jacobian * W
        P, x0new = nm.get_projection(W, AW, rhs, phi0,
                                     inner_product = modeleval.inner_product
                                     )
    else:
        #AW = np.zeros((len(current_psi),1), dtype=np.complex)
        P = None
        x0new = phi0

    if args.krylov_method == 'cg':
        lin_solve = nm.cg
    elif args.krylov_method == 'minres':
        lin_solve = nm.minres
    #elif args.krylov_method == 'minresfo':
        #lin_solve = nm.minres
        #lin_solve_args.update({'full_reortho': True})
    elif args.krylov_method == 'gmres':
        lin_solve = nm.gmres
    else:
        raise ValueError('Unknown Krylov solver ''%s''.' % args.krylov_method)

    print('Solving the system (len(x) = %d, bordering: %r)...' % (len(x), args.bordering),)
    start_time = time.clock()
    timer = False
    out = lin_solve(jacobian, rhs,
                    x0new,
                    tol = args.tolerance,
                    Mr = P,
                    M = prec,
                    #maxiter = 2*num_coords,
                    maxiter = 500,
                    inner_product = modeleval.inner_product,
                    explicit_residual = True,
                    #timer=timer
                    #exact_solution = ref_sol
                    )
    end_time = time.clock()
    print('done. (%gs)' % (end_time - start_time))
    print('(%d,%d)' % (2*num_coords, len(out['relresvec'])-1))


    # compute actual residual
    #res = rhs - jacobian * out['xk']
    #print '||b-Ax|| = %g' % np.sqrt(modeleval.inner_product(res, res))

    if timer:
        # pretty-print timings
        print(' '*22 + 'sum'.rjust(14) + 'mean'.rjust(14) + 'min'.rjust(14) + 'std dev'.rjust(14))
        for key, item in out['times'].items():
            print('\'%s\': %12g  %12g  %12g  %12g'
                 % (key.ljust(20), item.sum(), item.mean(), item.min(), item.std()))

    # Get the number of MG cycles.
    # 'modeleval.num_cycles' contains the number of MG cycles executed
    # for all AMG calls run.
    # In nm.minres, two calls to the precondictioner are done prior to the
    # actual iteration for the normalization of the residuals.
    # With explicit_residual=True, *two* calls to the preconditioner are done
    # in each iteration.
    # What we would like to have here is the number of V-cycles done per loop
    # when explicit_residual=False. Also, forget about the precondictioner
    # calls for the initialization.
    # Hence, cut of the first two and replace it by 0, and out of the
    # remainder take every other one.
    #nc = [0] + modeleval.tot_amg_cycles[2::2]
    #nc_cumsum = np.cumsum(nc)
    #pp.semilogy(nc_cumsum, out['relresvec'], color='0.0')
    #pp.show()
    #import matplotlib2tikz
    #matplotlib2tikz.save('cycle10.tex')

    #matplotlib2tikz.save('inf.tex')

    return out['relresvec']
Exemplo n.º 8
0
def _solve_system(modeleval, filename, timestep, mu, args):
    # read the mesh
    print(("Reading current psi...", ))
    start = time.time()
    mesh, point_data, field_data = meshplex.read(filename, timestep=timestep)
    total = time.time() - start
    print(("done (%gs)." % total))

    num_coords = len(mesh.node_coords)

    # set psi at which to create the Jacobian
    print(("Creating initial guess and right-hand side...", ))
    start = time.time()
    current_psi = (point_data["psi"][:, 0] +
                   1j * point_data["psi"][:, 1]).reshape(-1, 1)

    # Perturb a bit.
    eps = 1.0e-10
    perturbation = eps * (np.random.rand(num_coords) +
                          1j * np.random.rand(num_coords))
    current_psi += perturbation.reshape(current_psi.shape)

    if args.bordering:
        phi0 = np.zeros((num_coords + 1, 1), dtype=complex)
        # right hand side
        x = np.empty((num_coords + 1, 1), dtype=complex)
        x[0:num_coords] = current_psi
        x[num_coords] = 0.0
    else:
        # create right hand side and initial guess
        phi0 = np.zeros((num_coords, 1), dtype=complex)
        x = current_psi
    # right hand side
    # rhs = np.ones( (num_coords,1), dtype=complex )

    # rhs = np.empty( num_coords, dtype = complex )
    # radius = np.random.rand( num_coords )
    # arg    = np.random.rand( num_coords ) * 2.0 * cmath.pi
    # for k in range( num_coords ):
    # rhs[ k ] = cmath.rect(radius[k], arg[k])
    rhs = modeleval.compute_f(x=x, mu=mu, g=1.0)
    end = time.time()
    print(("done. (%gs)" % (end - start)))
    print(("||rhs|| = %g" % np.sqrt(modeleval.inner_product(rhs, rhs))))

    # create the linear operator
    print(("Getting Jacobian...", ))
    start_time = time.clock()
    jacobian = modeleval.get_jacobian(x=x, mu=mu, g=1.0)
    end_time = time.clock()
    print(("done. (%gs)" % (end_time - start_time)))

    # create precondictioner object
    print(("Getting preconditioner...", ))
    start_time = time.clock()
    prec = modeleval.get_preconditioner_inverse(x=x, mu=mu, g=1.0)
    end_time = time.clock()
    print(("done. (%gs)" % (end_time - start_time)))

    # Get reference solution
    # print 'Get reference solution (dim = %d)...' % (2*num_coords),
    # start_time = time.clock()
    # ref_sol, info, relresvec, errorvec = nm.minres_wrap( jacobian, rhs,
    # x0 = phi0,
    # tol = 1.0e-14,
    # M = prec,
    # inner_product = modeleval.inner_product,
    # explicit_residual = True
    # )
    # end_time = time.clock()
    # if info == 0:
    # print 'success!',
    # else:
    # print 'no convergence.',
    # print ' (', end_time - start_time, 's,', len(relresvec)-1 ,' iters).'

    if args.use_deflation:
        W = 1j * x
        AW = jacobian * W
        P, x0new = nm.get_projection(W,
                                     AW,
                                     rhs,
                                     phi0,
                                     inner_product=modeleval.inner_product)
    else:
        # AW = np.zeros((len(current_psi),1), dtype=np.complex)
        P = None
        x0new = phi0

    if args.krylov_method == "cg":
        lin_solve = nm.cg
    elif args.krylov_method == "minres":
        lin_solve = nm.minres
    # elif args.krylov_method == 'minresfo':
    # lin_solve = nm.minres
    # lin_solve_args.update({'full_reortho': True})
    elif args.krylov_method == "gmres":
        lin_solve = nm.gmres
    else:
        raise ValueError("Unknown Krylov solver "
                         "%s"
                         "." % args.krylov_method)

    print(("Solving the system (len(x) = %d, bordering: %r)..." %
           (len(x), args.bordering), ))
    start_time = time.clock()
    timer = False
    out = lin_solve(
        jacobian,
        rhs,
        x0new,
        tol=args.tolerance,
        Mr=P,
        M=prec,
        # maxiter = 2*num_coords,
        maxiter=500,
        inner_product=modeleval.inner_product,
        explicit_residual=True,
        # timer=timer
        # exact_solution = ref_sol
    )
    end_time = time.clock()
    print(("done. (%gs)" % (end_time - start_time)))
    print(("(%d,%d)" % (2 * num_coords, len(out["relresvec"]) - 1)))

    # compute actual residual
    # res = rhs - jacobian * out['xk']
    # print '||b-Ax|| = %g' % np.sqrt(modeleval.inner_product(res, res))

    if timer:
        # pretty-print timings
        print((" " * 22 + "sum".rjust(14) + "mean".rjust(14) +
               "min".rjust(14) + "std dev".rjust(14)))
        for key, item in list(out["times"].items()):
            print(("'%s': %12g  %12g  %12g  %12g" %
                   (key.ljust(20), item.sum(), item.mean(), item.min(),
                    item.std())))

    # Get the number of MG cycles.
    # 'modeleval.num_cycles' contains the number of MG cycles executed
    # for all AMG calls run.
    # In nm.minres, two calls to the precondictioner are done prior to the
    # actual iteration for the normalization of the residuals.
    # With explicit_residual=True, *two* calls to the preconditioner are done
    # in each iteration.
    # What we would like to have here is the number of V-cycles done per loop
    # when explicit_residual=False. Also, forget about the precondictioner
    # calls for the initialization.
    # Hence, cut of the first two and replace it by 0, and out of the
    # remainder take every other one.
    # nc = [0] + modeleval.tot_amg_cycles[2::2]
    # nc_cumsum = np.cumsum(nc)
    # pp.semilogy(nc_cumsum, out['relresvec'], color='0.0')
    # pp.show()
    # import matplotlib2tikz
    # matplotlib2tikz.save('cycle10.tex')

    # matplotlib2tikz.save('inf.tex')

    return out["relresvec"]