def test_restart_GMRES(N, eps, max_iter): # Initial values h = 1 / N # nr of lines # Discretisation A = scipy.sparse.diags([-eps / h - 1, 2 * eps / h + 1, -eps / h], [-1, 0, 1], shape=(N - 1, N - 1)).toarray() f = np.zeros(N - 1) f[0] = eps / h + 1 # bring bc to rhs counter = gmres_counter() u_re, res_lst_re = gmres(A, f, callback=counter, M=np.linalg.inv( np.identity(N - 1) * (2 * eps / h)), callback_type="pr_norm", restart=max_iter, maxiter=1)[0], counter.rk_lst counter = gmres_counter() u_gm, res_lst_gm = gmres(A, f, x0=u_re, callback=counter, M=np.linalg.inv( np.identity(N - 1) * (2 * eps / h)), callback_type="pr_norm", restart=len(A), maxiter=1)[0], counter.rk_lst return u_gm, np.concatenate((res_lst_re, res_lst_gm[1:]))
def solve_for_pressure(profile1, profile2, normal_load, red_influ_mat, init_displ, delta_x, delta_y, print_prog=True): """ Solve system of equations: [pressure] = [influence matrix]^-1 * [displacement] Stop solver once inner and outer forces are in equilibrium """ # initialise variables x_value = [0] fx_value = [normal_load] pressure = [] resulting_force = 0 profile = -(profile1 + profile2) threshold_factor = 0.005 # do while difference between inner forces and outer forces is significant while abs(resulting_force - normal_load) > threshold_factor * normal_load: displacement_field = np.subtract(np.ones(profile.shape) * init_displ, profile) u = np.reshape(displacement_field, (profile.shape[0] * profile.shape[1])) # lots of options to solve this, the active implementation proved to be # the fastest for me # p = np.linalg.solve(red_influ_mat, u) p = spla.gmres(red_influ_mat, u)[0] p_index = np.zeros(len(p)) negative_p = np.where(p < 0)[0] p_neg = copy.deepcopy(negative_p) # do while there are elements with negative pressure while len(negative_p) > 0: p[p_neg] = 0 p_index[p_neg] = 1 u_new_reduced = np.delete(u, [p_neg], axis=0) g_new_reduced = np.delete(red_influ_mat, [p_neg], axis=0) g_new_reduced = np.delete(g_new_reduced, [p_neg], axis=1) if p[np.where(p_index == 0)].size > 0: # again, lots of options available here, this seems to be the # fastest for most cases p[np.where(p_index == 0)] = \ spla.gmres(g_new_reduced, u_new_reduced)[0] negative_p = np.where(p < 0)[0] p_neg = np.append(p_neg, negative_p) # calculate resulting force and adjust displacement for next calculation # loop pressure = np.reshape(p, (profile.shape[0], profile.shape[1])) resulting_force = sum(sum(np.multiply(delta_x * delta_y, pressure))) x_value = np.append(x_value, [init_displ]) fx_value = np.append(fx_value, [resulting_force - normal_load]) init_displ = secant_method(x_value, fx_value) if print_prog is True: print_rel_prox_to_sol(resulting_force, normal_load, threshold_factor) return pressure, resulting_force, x_value[-1]
def calcHmeanval(MPS, R, C, guess): chir, chic, aux = MPS.shape QHAAAAR = getQHaaaaR(MPS, R, C) if (chir, chic) < guess.shape: guess = guess[-chir:, -chic:] linOpWrapped = functools.partial(linearOpForK, MPS, R) linOpForLsol = spspla.LinearOperator((chir * chir, chic * chic), matvec=linOpWrapped, dtype=MPS.dtype) K, info = spspla.lgmres(linOpForLsol, QHAAAAR, tol=1.e-13, maxiter=maxIter, x0=guess.reshape(chir * chic)) if info > 0: K, info = spspla.gmres(linOpForLsol, QHAAAAR, tol=expS, x0=K, maxiter=maxIter) elif info < 0: K, info = spspla.gmres(linOpForLsol, QHAAAAR, tol=expS, maxiter=maxIter) if info != 0: print >> sys.stderr, "calcHmeanval: Error", I, "lgmres and gmres failed" K = np.reshape(K, (chir, chic)) print "QHAAAAR", QHAAAAR.shape, "info", info, np.isfinite( K).all(), "K\n", K return K
def test_restart_GMRES2D(N, atol=1e-6, max_iter=1): A = A2dim(N) M_inv = np.linalg.inv(np.eye(len(A)) * A[0, 0]) f = np.ones(len(A)) counter = gmres_counter() u_re, res_lst_re = gmres(A, f, callback=counter, M=M_inv, callback_type="pr_norm", restart=max_iter, maxiter=0)[0], counter.rk_lst counter = gmres_counter() u_gm, res_lst_gm = gmres(A, f, x0=u_re, callback=counter, M=M_inv, callback_type="pr_norm", restart=len(A), maxiter=1, atol=atol)[0], counter.rk_lst return u_gm, np.concatenate((res_lst_re, res_lst_gm[1:]))
def test_compact_equivalence(self): """Tests the compact operator has the same solution as the full""" domain = Domain(extents=2 * [(0., 1.)], num_elements=2, num_points=4) solution = ProductOfSinusoids(wave_numbers=2 * [pi]) domain.set_data(solution.source, 'source') boundary_conditions = 2 * [( AnalyticSolution(BoundaryCondition.DIRICHLET, solution=solution.field), AnalyticSolution(BoundaryCondition.DIRICHLET, solution=solution.field), )] A_kwargs = dict(domain=domain, system=Poisson, boundary_conditions=boundary_conditions) gmres_kwargs = dict(tol=1.e-10, atol=1.e-14, maxiter=100, restart=100) A_full = DgOperator(formulation='flux-full', **A_kwargs) b_full = A_full.compute_source('source') sol_full, info = gmres(A_full, b_full, **gmres_kwargs) assert info == 0, "Linear solve failed" domain.set_data(sol_full, ['v_full', 'u_full'], fields_valence=(1, 0)) A_compact = DgOperator(formulation='flux', **A_kwargs) b_compact = A_compact.compute_source('source') sol_compact, info = gmres(A_compact, b_compact, **gmres_kwargs) assert info == 0, "Linear solve failed" domain.set_data(sol_compact, 'u_compact', storage_order='F') npt.assert_allclose(domain.get_data('u_full'), domain.get_data('u_compact'), rtol=0., atol=1.e-9)
def calcHmeanval(MPS, R, C, guess): chir, chic, aux = MPS.shape QHAAAAR = getQHaaaaR(MPS, R, C) if (chir, chic) < guess.shape: guess = guess[-chir:, -chic:] linOpWrapped = functools.partial(linearOpForK, MPS, R) linOpForLsol = spspla.LinearOperator((chir * chir, chic * chic), matvec = linOpWrapped, dtype = MPS.dtype) K, info = spspla.lgmres(linOpForLsol, QHAAAAR, tol = 1.e-13, maxiter = maxIter, x0 = guess.reshape(chir * chic)) if info > 0: K, info = spspla.gmres(linOpForLsol, QHAAAAR, tol = expS, x0 = K, maxiter = maxIter) elif info < 0: K, info = spspla.gmres(linOpForLsol, QHAAAAR, tol = expS, maxiter = maxIter) if info != 0: print >> sys.stderr, "calcHmeanval: Error", I, "lgmres and gmres failed" K = np.reshape(K, (chir, chic)) print "QHAAAAR", QHAAAAR.shape, "info", info, np.isfinite(K).all(), "K\n", K return K
def GMRES(): EquiA1 = np.vstack((np.hstack((E,R,D)),np.hstack((R.T,A,Z6)),\ np.hstack((D.T,Z6,Z6)))) # Assemble solution vector for first equation Equib1 = np.vstack((np.zeros((nd, 6)), Tr.T, Z6)) sol1 = np.zeros((nd + 12, 6)) for i in range(6): sol1[:, i] = gmres(EquiA1, Equib1[:, i]) sol1 = gmres(EquiA1, Equib1) # Recover gradient of displacement as a function of force and moment # resutlants dXdz = sol1[0:nd, :] # Save the gradient of section strains as a function of force and # moment resultants dYdz = sol1[nd:nd + 6, :] # Set up the first of two solution vectors for second equation Equib2_1 = np.vstack((np.hstack((-(C - C.T), L)), np.hstack( (-L.T, Z6)), np.zeros((6, nd + 6)))) # Set up the second of two solution vectors for second equation Equib2_2 = np.vstack((np.zeros((nd, 6)), np.eye(6, 6), Z6)) # Add solution vectors and solve second equillibrium equation sol2 = np.zeros((nd + 12, 6)) Equib2 = np.dot(Equib2_1, sol1[0:nd + 6, :]) + Equib2_2 for i in range(6): sol2[:, i] = gmres(EquiA1, Equib2[:, i]) X = sol2[0:nd, 0:6] # Store the section strain as a function of force and moment resultants Y = sol2[nd:nd + 6, 0:6] return dXdz, dYdz, X, Y
def jacknife_kriging_all_chosen(X, cluster_x, cluster_y, allPars, lambda_w=100.0): if len(X) <= 1: print "Jacknife: Not enough points" return X[:, 2], np.ones((1)) * np.inf combPars = interp_pars(X[:, 0], X[:, 1], cluster_x, cluster_y, allPars, lambda_w=lambda_w) bigSigma = memory_saver_C_sph_nugget_ns(X[:, 0], X[:, 1], combPars, nblocks=1) mu = X[:, 2].mean() predicted = np.zeros((len(X))) krigvar = np.zeros((len(X))) Npoints = X.shape[0] for k in range(len(X)): logging.debug("Jacknife_kriging_all_chosen: %d/%d" % (k, len(X))) rowsAll = [i for i in range(Npoints) if not i == k] A = bigSigma[np.ix_(rowsAll, rowsAll)] phi = splinalg.gmres(A, X[rowsAll, 2] - X[rowsAll, 2].mean())[0] crossSigma = bigSigma[k, rowsAll] crossSigma = csc_matrix(crossSigma) predicted[k] = X[rowsAll, 2].mean() + crossSigma.dot(phi) rhs = crossSigma.toarray().T psi = splinalg.gmres(A, rhs, tol=0.1)[0] krigvar[k] = bigSigma[k, k] - np.inner(crossSigma.toarray(), psi)[0] return predicted, krigvar
def engine_ImplicitDiffusion3D_ADI_GMRES(sim): """ Computes the discretization of the diffusion equation using the Alternating Direction Implicit method for 2D Uses the function scipy.sparse.linalg.gmres(A, b) to **quickly but approximately** solve the equation Ax=b for the matrix A and vectors x and b """ dt = sim._time_step_in_seconds dx = sim.get_cell_spacing() c = sim.fields[0].data alpha = sim.D * dt / dx**2 dim = sim.get_dimensions() matrix1d_x = diffusion_matrix_1d(dim[2], 1 + 2 * alpha, -alpha) matrix1d_y = diffusion_matrix_1d(dim[1], 1 + 2 * alpha, -alpha) matrix1d_z = diffusion_matrix_1d(dim[0], 1 + 2 * alpha, -alpha) for i in range( dim[0]): #iterate through ADI method in the x direction first for j in range(dim[1]): c[i, j], exitCode = gmres(matrix1d_x, c[i, j], atol='legacy') for i in range( dim[0]): #then iterate through ADI method in the y direction for j in range(dim[2]): c[i, :, j], exitCode = gmres(matrix1d_y, c[i, :, j], atol='legacy') for i in range( dim[1]): #finally, iterate through ADI method in the z direction for j in range(dim[2]): c[:, i, j], exitCode = gmres(matrix1d_z, c[:, i, j], atol='legacy') sim.fields[0].data = c
def engine_CrankNicolsonDiffusion2D_ADI_GMRES(sim): """ Computes the discretization of the diffusion equation using the Alternating Direction Implicit method for 2D, extended to use the Crank-Nicolson scheme Uses the Peaceman-Rachford discretization (explicit x + implicit y, then explicit y + implicit x) Uses the function scipy.sparse.linalg.gmres(A, b) to **quickly but approximately** solve the equation Ax=b for the matrix A and vectors x and b """ dt = sim._time_step_in_seconds dx = sim.get_cell_spacing() c = sim.fields[0].data alpha = 0.5 * sim.D * dt / dx**2 dim = sim.get_dimensions() matrix1d_x = diffusion_matrix_1d(dim[1], 1 + 2 * alpha, -alpha) matrix1d_y = diffusion_matrix_1d(dim[0], 1 + 2 * alpha, -alpha) c_explicit = (1 - 2 * alpha) * c + alpha * ( np.roll(c, 1, 0) + np.roll(c, -1, 0)) #explicit in x for i in range( dim[1] ): #iterate through ADI method in the y direction first for P-R c[:, i], exitCode = gmres(matrix1d_y, c_explicit[:, i], atol='legacy') c_explicit = (1 - 2 * alpha) * c + alpha * ( np.roll(c, 1, 1) + np.roll(c, -1, 1)) #explicit in y for i in range( dim[0]): #then iterate through ADI method in the x direction c[i], exitCode = gmres(matrix1d_x, c_explicit[i], atol='legacy') sim.fields[0].data = c
def GMRES(): EquiA1 = np.vstack((np.hstack((E,R,D)),np.hstack((R.T,A,Z6)),\ np.hstack((D.T,Z6,Z6)))) # Assemble solution vector for first equation Equib1 = np.vstack((np.zeros((nd,6)),Tr.T,Z6)) sol1 = np.zeros((nd+12,6)) for i in range(6): sol1[:,i] = gmres(EquiA1,Equib1[:,i]) sol1 = gmres(EquiA1,Equib1) # Recover gradient of displacement as a function of force and moment # resutlants dXdz = sol1[0:nd,:] # Save the gradient of section strains as a function of force and # moment resultants dYdz = sol1[nd:nd+6,:] # Set up the first of two solution vectors for second equation Equib2_1 = np.vstack((np.hstack((-(C-C.T),L)),np.hstack((-L.T,Z6)),np.zeros((6,nd+6)))) # Set up the second of two solution vectors for second equation Equib2_2 = np.vstack((np.zeros((nd,6)),np.eye(6,6),Z6)) # Add solution vectors and solve second equillibrium equation sol2 = np.zeros((nd+12,6)) Equib2 = np.dot(Equib2_1,sol1[0:nd+6,:])+Equib2_2 for i in range(6): sol2[:,i] = gmres(EquiA1,Equib2[:,i]) X = sol2[0:nd,0:6] # Store the section strain as a function of force and moment resultants Y = sol2[nd:nd+6,0:6] return dXdz, dYdz, X, Y
def solve_linear(self, d_outputs, d_residuals, mode): if mode == 'fwd': print("incoming initial guess", d_outputs['states']) d_outputs['states'] = gmres(self.state_jac, d_residuals['states'], x0=d_outputs['states'])[0] elif mode == 'rev': d_residuals['states'] = gmres(self.state_jac, d_outputs['states'], x0=d_residuals['states'])[0]
def solve_kriging_system(X, Y, cluster_x, cluster_y, allPars, lambda_w=100.0, get_covar=True): """Helper function to solve linear system of equations related to kriging """ combX = np.hstack((Y[:, 0], X[:, 0])) combY = np.hstack((Y[:, 1], X[:, 1])) combPars = interp_pars(combX, combY, cluster_x, cluster_y, allPars, lambda_w=lambda_w) nblocks = 1 if len(combX) > 1000: nblocks = 10 bigSigma = memory_saver_C_sph_nugget_ns(combX, combY, combPars, nblocks=nblocks) Npoint = len(X) Nsel = len(Y) gen1 = range(Nsel, Nsel + Npoint) # Z gen2 = range(Nsel) # Z* pointSigma = bigSigma[np.ix_(gen1, gen1)] crossSigma = bigSigma[np.ix_(gen2, gen1)] selSigma = bigSigma[np.ix_(gen2, gen2)] pointSigma = csc_matrix(pointSigma) mu = X[:, 2].mean() phi = splinalg.gmres(pointSigma, X[:, 2] - mu, tol=1.0e-4) crossSigma = csc_matrix(crossSigma) predicted = mu + crossSigma.dot(phi[0]) psi = np.zeros((Npoint, Nsel)) for k in range(Nsel): A = pointSigma b = crossSigma[k, :].toarray().T temp = splinalg.gmres(A, b, tol=0.1) psi[:, k] = temp[0] if get_covar: oerk = crossSigma.dot(psi) oerk = csc_matrix(oerk) predSigma = (selSigma - oerk).toarray() else: predSigma = selSigma.diagonal() - np.sum(crossSigma.toarray() * psi.T, 1) return predicted, predSigma, combPars[:Nsel, :]
def solve_linear(self, d_outputs, d_residuals, mode): if mode == 'fwd': print("incoming initial guess", d_outputs['states']) if LooseVersion(scipy.__version__) < LooseVersion("1.1"): d_outputs['states'] = gmres(self.state_jac, d_residuals['states'], x0=d_outputs['states'])[0] else: d_outputs['states'] = gmres(self.state_jac, d_residuals['states'], x0=d_outputs['states'], atol='legacy')[0] elif mode == 'rev': if LooseVersion(scipy.__version__) < LooseVersion("1.1"): d_residuals['states'] = gmres(self.state_jac, d_outputs['states'], x0=d_residuals['states'])[0] else: d_residuals['states'] = gmres(self.state_jac, d_outputs['states'], x0=d_residuals['states'], atol='legacy')[0]
def advanceSolImplicit2(main, MZ, eqns): old = np.zeros(np.shape(main.a0)) old[:] = main.a0[:] main.a0[:] = main.a.a[:] main.getRHS(main, eqns) R0 = np.zeros(np.shape(main.RHS)) R0[:] = main.RHS[:] alpha = (2. - np.sqrt(2.)) / 2. def mv(v): vr = np.reshape(v, np.shape(main.a.a)) eps = 1.e-5 main.a.a[:] = main.a0[:] + eps * vr main.getRHS(main, eqns) R1 = np.zeros(np.shape(main.RHS)) R1[:] = main.RHS[:] Av = vr - main.dt * alpha * (R1 - R0) / eps main.a.a[:] = main.a0[:] return Av.flatten() def printnorm(r): print('GMRES norm = ' + str(np.linalg.norm(r))) A = LinearOperator((np.size(main.a.a), np.size(main.a.a)), matvec=mv) #stage 1 sol = gmres(A, main.dt * alpha * R0.flatten(), x0=np.zeros(np.size(R0)), tol=1e-07, restart=60, maxiter=None, xtype=None, M=None, callback=printnorm, restrt=None) main.a.a = main.a0 + np.reshape(sol[0], np.shape(main.a.a)) main.getRHS(main, eqns) R2 = main.dt * ((1 - alpha) * main.RHS + alpha * R0).flatten() sol = gmres(A, R2, x0=np.zeros(np.size(R2)), tol=1e-07, restart=60, maxiter=None, xtype=None, M=None, callback=printnorm, restrt=None) main.a.a = main.a0 + np.reshape(sol[0], np.shape(main.a.a)) main.t += main.dt main.iteration += 1
def solve_gmres(A, b): LOG.debug(f"Solve with GMRES for {A}.") if LOG.isEnabledFor(logging.DEBUG): counter = Counter() x, info = ssl.gmres(A, b, atol=1e-6, callback=counter) LOG.debug(f"End of GMRES after {counter.nb_iter} iterations.") else: x, info = ssl.gmres(A, b, atol=1e-6) if info != 0: LOG.warning(f"No convergence of the GMRES. Error code: {info}") return x
def _do_one_inner_iteration(self, A, b, **kwargs): r""" This method solves AX = b and returns the result to the corresponding algorithm. """ logger.info('Solving AX = b for the sparse matrices') if A is None: A = self.A if b is None: b = self.b if self._iterative_solver is None: X = sprslin.spsolve(A, b) else: if self._iterative_solver not in ['cg', 'gmres']: raise Exception('GenericLinearTransport does not support the' + ' requested iterative solver!') params = kwargs.copy() solver_params = ['x0', 'tol', 'maxiter', 'xtype', 'M', 'callback'] [params.pop(item, None) for item in kwargs.keys() if item not in solver_params] tol = kwargs.get('tol') if tol is None: tol = 1e-20 params['tol'] = tol if self._iterative_solver == 'cg': result = sprslin.cg(A, b, **params) elif self._iterative_solver == 'gmres': result = sprslin.gmres(A, b, **params) X = result[0] self._iterative_solver_info = result[1] return X
def solve_system(self, rhs, factor, u0, t): """ Simple linear solver for (I-dtA)u = rhs using GMRES Args: rhs (dtype_f): right-hand side for the nonlinear system factor (float): abbrev. for the node-to-node stepsize (or any other factor required) u0 (dtype_u): initial guess for the iterative solver (not used here so far) t (float): current time (e.g. for time-dependent BCs) Returns: dtype_u: solution as mesh """ b = rhs.values.flatten() cb = Callback() sol, info = gmres(self.Id - factor * self.M, b, x0=u0.values.flatten(), tol=self.params.gmres_tol_limit, restart=self.params.gmres_restart, maxiter=self.params.gmres_maxiter, callback=cb) # If this is a dummy call with factor==0.0, do not log because it should not be counted as a solver call if factor != 0.0: self.gmres_logger.add(cb.getcounter()) me = self.dtype_u(self.init) me.values = unflatten(sol, 4, self.N[0], self.N[1]) return me
def _jacobian_callback(self, X): """This function is passed to the internal solver to return the jacobian of the states with respect to the residuals.""" n_edge = 2*len(X) n_res = n_edge/2 A = LinearOperator((n_edge, n_edge), matvec=self._matvecFWD, dtype=float) J = np.zeros((n_res, n_res)) self._cache_J = self.provideJ() for irhs in np.arange(n_res): RHS = np.zeros((n_edge, 1)) RHS[irhs, 0] = 1.0 # Call GMRES to solve the linear system dx, info = gmres(A, RHS, tol=1.0e-9, maxiter=100) if info > 0: msg = "ERROR in '%s': gmres failed to converge after %d iterations at index %d" self._logger.error(msg % (self.get_pathname(), info, irhs)) elif info < 0: self._logger.error("ERROR in '%s': gmres failed at index %d" % (self.get_pathname(),irhs)) J[:, irhs] = dx[n_res:] return J
def f_solve(self, b, alpha, u0): cb = Callback() sol, info = LA.gmres( self.problem.Id - alpha*(self.problem.D_upwind + self.problem.M), b, x0=u0, tol=self.problem.gmres_tol_limit, restart=self.problem.gmres_restart, maxiter=self.problem.gmres_maxiter, callback=cb) if alpha!=0.0: #print "DIRK-%1i: Number of GMRES iterations: %3i --- Final residual: %6.3e" % ( self.order, cb.getcounter(), cb.getresidual() ) self.logger.add(cb.getcounter()) return sol
def solve_ip(self, kptlist, ps, qs, omegas): if not isinstance(ps, collections.Iterable): ps = [ps] if not isinstance(qs, collections.Iterable): qs = [qs] cc = self.cc print("solving ip portion") Sw = initial_ip_guess(cc) e_vector = list() for ikpt, kp in enumerate(kptlist): for q in qs: e_vector.append(greens_e_vector_ip_rhf(cc, q, kp)) gfvals = np.zeros((len(kptlist), len(ps), len(qs), len(omegas)), dtype=complex) for ikpt, kp in enumerate(kptlist): for ip, p in enumerate(ps): b_vector = greens_b_vector_ip_rhf(cc, p, kp) cc.kshift = kp diag = cc.ipccsd_diag() for iw, omega in enumerate(omegas): invprecond_multiply = lambda x: x / (omega + diag + 1j * self.eta) def matr_multiply(vector, args=None): return greens_func_multiply(cc.ipccsd_matvec, vector, omega + 1j * self.eta) size = len(b_vector) Ax = spla.LinearOperator((size, size), matr_multiply) mx = spla.LinearOperator((size, size), invprecond_multiply) Sw, info = spla.gmres(Ax, b_vector, x0=Sw, M=mx) for iq, q in enumerate(qs): gfvals[ip, iq, iw] = -np.dot(e_vector[iq], Sw) if len(ps) == 1 and len(qs) == 1: return gfvals[0, 0, :] else: return gfvals
def solvePrimal(self): """Solve the primal problem""" if 'matLocal' in locals(): # if matLocal exists, # only change the mesh instead of initializing again matLocal.mesh = self.mesh else: matLocal = discretization(self.coeff, self.mesh) matGroup = matLocal.matGroup() A, B, _, C, D, E, F, G, H, L, R = matGroup # solve by exploiting the local global separation K = -cat((C.T, G), axis=1)\ .dot(np.linalg.inv(np.bmat([[A, -B], [B.T, D]])) .dot(cat((C, E)))) + H sK = csr_matrix(K) F_hat = np.array([L]).T - cat((C.T, G), axis=1)\ .dot(np.linalg.inv(np.bmat([[A, -B], [B.T, D]])))\ .dot(np.array([cat((R, F))]).T) def invRHS(vec): """Construct preconditioner""" matVec = spla.spsolve(sK, vec) return matVec n = len(F_hat) preconditioner = spla.LinearOperator((n, n), invRHS) stateFace = spla.gmres(sK, F_hat, M=preconditioner)[0] # stateFace = np.linalg.solve(K, F_hat) gradState = np.linalg.inv(np.asarray(np.bmat( [[A, -B], [B.T, D]]))).dot(cat((R, F)) - cat((C, E)).dot(stateFace)) self.primalSoln = cat((gradState, stateFace))
def computeGreensFunc(self): L = LinearOperator((self.signalDataLen, self.signalDataLen), matvec=self.CNOperator, dtype=numpy.float32) rhs = numpy.zeros(self.gridDim, dtype=numpy.float32) pos = numpy.array( self.signalling.gridOrig, dtype=numpy.float32) + 0.5 * numpy.array( self.gridDim[1:], dtype=numpy.float32) * numpy.array( self.signalling.gridSize, dtype=numpy.float32) #idx = ( math.floor(self.gridDim[1]*0.5), math.floor(self.gridDim[2]*0.5), math.floor(self.gridDim[3]*0.5) ) #for s in xrange(self.nSignals): # rhs[(s,)+idx] = 1.0 # ~delta function in each signal self.signalling.interpAddToGrid(pos, numpy.ones(self.nSignals), rhs) (self.greensFunc, info) = gmres(L, rhs.reshape( self.signalDataLen)) # Solve impulse response = greens func # Take only bounding box of region where G > threshold self.greensFunc.shape = self.gridDim inds = numpy.transpose( numpy.nonzero( self.greensFunc.reshape(self.gridDim) > self.greensThreshold)) self.greensFunc = self.greensFunc[:, min(inds[:,1]):max(inds[:,1])+1, \ min(inds[:,2]):max(inds[:,2])+1, \ min(inds[:,3]):max(inds[:,3])+1] print "Truncated Green's function size is " + str( self.greensFunc.shape)
def solve_for_NR_step(RHS, u, x0, x1, L, R, N, nu): # Compute the RHS for the pre-conditioned system. b = copy(RHS) b = mult_by_Pinv(b, x0, x1, N, nu) # Set up the linear operator. def mulA(v): return mult_by_A(v, u, x0, x1, L, R, N, nu) A = LinearOperator((N, N), matvec=mulA) # Initialize iteration counter to 0 and call GMRES. counter = gmres_counter() counter.__init__() # NOTE: GMRES tolerances are now hard-coded! w, gmres_conv = gmres(A, b, maxiter=N, callback=counter, tol=1e-8, atol=1e-12) if gmres_conv > 0: print('No convergence in GMRES after %d iterations' % (gmres_conv)) elif gmres_conv < 0: print('Illegal input or breakdown in GMRES') # We still have to solve P^t du = w... du = mult_by_PTinv(w, x0, x1, N, nu) return du, counter.niter
def solve(self): ''' Method that solves the linear equations system. Param: - Return: - ''' G = self.__matrix.getMatrix() f = self.__matrix.getfv() if self.__algorithm == 'linalg': self.__lam = np.linalg.solve(G, f) elif self.__algorithm == 'bicgstab': A = sps.csr_matrix(G) self.__lam = spla.bicgstab(A, f)[0] elif self.__algorithm == 'bicg': A = sps.csr_matrix(G) self.__lam = spla.bicg(A, f)[0] elif self.__algorithm == 'cg': A = sps.csr_matrix(G) self.__lam = spla.cg(A, f)[0] elif self.__algorithm == 'gmres': A = sps.csr_matrix(G) self.__lam = spla.gmres(A, f)[0]
def rbf_fd(inner_nodes, boundary_nodes, l, pdim, rbf_tag='r^3', boundary=boundary): n = len(inner_nodes) n_b = len(boundary_nodes) C, b_vec = gen_system(inner_nodes, boundary_nodes, l, pdim, rbf_tag=rbf_tag, boundary=boundary) A_mat = C[:, :n] rhs = C[:, n:] @ b_vec tol = 1e-14 if n <= 400: u = spsolve(A_mat, rhs) else: ilu_A = spilu(A_mat) M = LinearOperator((n, n), lambda x: ilu_A.solve(x)) u, info = gmres(A_mat, rhs, M=M, tol=tol) if info != 0: print('gmres failed') print('n: %d\tinfo: %d' % (n, info)) u = spsolve(A_mat, rhs) u = np.concatenate((u.ravel(), -b_vec.ravel()), axis=0) return u, C, b_vec
def solve_ea(self, ps, qs, omegas): if not isinstance(ps, collections.Iterable): ps = [ps] if not isinstance(qs, collections.Iterable): qs = [qs] cc = self.cc print("solving ea portion") Sw = initial_ea_guess(cc) diag = cc.eaccsd_diag() e_vector = list() for p in ps: e_vector.append(greens_e_vector_ea_rhf(cc, p)) gfvals = np.zeros((len(ps), len(qs), len(omegas)), dtype=complex) for iq, q in enumerate(qs): b_vector = greens_b_vector_ea_rhf(cc, q) for iw, omega in enumerate(omegas): invprecond_multiply = lambda x: x / (-omega + diag + 1j * self. eta) def matr_multiply(vector, args=None): return greens_func_multiply(cc.eaccsd_matvec, vector, -omega + 1j * self.eta) size = len(b_vector) Ax = spla.LinearOperator((size, size), matr_multiply) mx = spla.LinearOperator((size, size), invprecond_multiply) Sw, info = spla.gmres(Ax, b_vector, x0=Sw, tol=10e-14, M=mx) for ip, p in enumerate(ps): gfvals[ip, iq, iw] = np.dot(e_vector[ip], Sw) if len(ps) == 1 and len(qs) == 1: print 'ea gfs', gfvals[0, 0, :] return gfvals[0, 0, :] else: print 'ea gfs', gfvals return gfvals
def solve_system(self,rhs,factor,u0,t): """ Simple linear solver for (I-dtA)u = rhs Args: rhs: right-hand side for the nonlinear system factor: abbrev. for the node-to-node stepsize (or any other factor required) u0: initial guess for the iterative solver (not used here so far) t: current time (e.g. for time-dependent BCs) Returns: solution as mesh """ b = rhs.values.flatten() cb = Callback() sol, info = LA.gmres( self.Id - factor*self.M, b, x0=u0.values.flatten(), tol=self.gmres_tol, restart=self.gmres_restart, maxiter=self.gmres_maxiter, callback=cb) # If this is a dummy call with factor==0.0, do not log because it should not be counted as a solver call if factor!=0.0: #print "SDC: Number of GMRES iterations: %3i --- Final residual: %6.3e" % ( cb.getcounter(), cb.getresidual() ) self.logger.add(cb.getcounter()) me = mesh(self.nvars) me.values = unflatten(sol, 4, self.N[0], self.N[1]) return me
def solver_scipy_benchmark(sp_matrix): # get sparse matrix shape n_row, n_col = sp_matrix.shape n_row = int(n_row) n_col = int(n_col) print("Sparse matrix row:", n_row, ", column:", n_col) # get CSR data csr_rowptr = sp_matrix.indptr csr_colidx = sp_matrix.indices csr_val = sp_matrix.data.astype(np.float32) # set x and get y x_exact = np.ones(n_col, dtype=np.float32) sp_A = csr_matrix((csr_val, csr_colidx, csr_rowptr), shape=(n_row, n_col)) y = sp_A.dot(x_exact) # === SciPy test === start = time.perf_counter() x, exitCode = gmres(sp_A, y) # exit code 0 = converge end = time.perf_counter() err = np.linalg.norm( x - x_exact, np.inf) / np.linalg.norm(x_exact, np.inf) print("SciPy run time:", (end - start)) print("SciPy exit code:", exitCode) print("SciPy result error:", err) print("")
def fast_solve(self): self.precondieitoner() tgdof = self.tensorspace.number_of_global_dofs() vgdof = self.vectorspace.number_of_global_dofs() gdof = tgdof + vgdof start = timer() print("Construting linear system ......!") self.M, self.B = self.get_left_matrix() S = self.B@spdiags(1/self.D, 0, tgdof, tgdof)@self.B.transpose() self.SL = tril(S).tocsc() self.SU = triu(S, k=1).tocsr() self.SUT = self.SL.transpose().tocsr() self.SLT = self.SU.transpose().tocsr() b = self.get_right_vector() AA = bmat([[self.M, self.B.transpose()], [self.B, None]]).tocsr() bb = np.r_[np.zeros(tgdof), b] end = timer() print("Construct linear system time:", end - start) start = timer() P = LinearOperator((gdof, gdof), matvec=self.linear_operator) x, exitCode = gmres(AA, bb, M=P, tol=1e-8) print(exitCode) end = timer() print("Solve time:", end-start) self.sh[:] = x[0:tgdof] self.uh[:] = x[tgdof:]
def _step(self, dt): if dt != self.dt: self.LHS = self.M + dt/2*self.L self.RHS_matrix = self.M - dt/2*self.L #self.LU = spla.splu(LHS.tocsc(), permc_spec='NATURAL') self.dt = dt if (self.axis == 'full'): np.copyto(self.data, self.X.data) data_shape = self.data.shape flattened_data = self.data.reshape(np.prod(data_shape)) self.RHS = self.RHS.reshape(flattened_data.shape) apply_matrix(self.RHS_matrix, flattened_data, 0, out=self.RHS) #self.data = self.LU.solve(self.RHS).reshape(data_shape) self.data,exitCode = gmres(self.LHS,self.RHS) self.data=self.data.reshape(data_shape) np.copyto(self.X.data, self.data) else: self._transpose_pre() # change view self.RHS = self.RHS.reshape(self.data.shape) apply_matrix(self.RHS_matrix, self.data, 0, out=self.RHS) self.data = self.LU.solve(self.RHS) self._transpose_post()
def bvp(n, domain, exact_test): # domain = QuadratureInfo(n) normals_x, normals_y = domain.normals.reshape(2, -1) nodes_x, nodes_y = domain.curve_nodes.reshape(2, -1) # taking exp_radius as panel_length / 2 from QBX paper qbx_radius = np.repeat(domain.panel_lengths, domain.npoints) / 2 total_points = nodes_x.shape[0] normal_mat_x = np.broadcast_to(normals_x, (total_points, total_points)) normal_mat_y = np.broadcast_to(normals_y, (total_points, total_points)) node_mat_x = np.broadcast_to(nodes_x, (total_points, total_points)) node_mat_y = np.broadcast_to(nodes_y, (total_points, total_points)) radius_mat = np.broadcast_to(qbx_radius, (total_points, total_points)).T # take care of normal signs here D_qbx_int = qbx_exp(0, node_mat_x.T, node_mat_y.T, node_mat_x, node_mat_y, -normal_mat_x.T, -normal_mat_y.T, normal_mat_x, normal_mat_y, radius_mat) * domain.curve_weights.reshape(-1) D_qbx_ext = qbx_exp(0, node_mat_x.T, node_mat_y.T, node_mat_x, node_mat_y, normal_mat_x.T, normal_mat_y.T, normal_mat_x, normal_mat_y, radius_mat) * domain.curve_weights.reshape(-1) test_density = np.ones((total_points, 1)) print(np.average((D_qbx_int + D_qbx_ext) * 0.5 @ test_density)) rhs = exact_test.reshape(-1) # averaging interior exterior limits A = (D_qbx_int + D_qbx_ext) * 0.5 - 0.5 * np.identity(total_points) soln_density, msg = gmres(A, rhs, tol=1e-13, callback=counter) print("GMRES iter:", counter.niter) return soln_density.reshape(n, -1)
def personal_rank_mat(graph, root, alpha, recom_num=10): """ Args: graph:user item graph root:the fix user to recom alpha:the prob to random walk recom_num:recom item num Return: a dict, key: itemid, value: pr score A*r = r0 """ m, vertex, address_dict = mat_util.graph_to_m(graph) if root not in address_dict: return {} score_dict = {} recom_dict = {} mat_all = mat_util.mat_all_point(m, vertex, alpha) index = address_dict[root] initial_list = [[0] for _ in range(len(vertex))] initial_list[index] = [1] r_zero = np.array(initial_list) res = gmres(mat_all, r_zero, tol=1e-8)[0] for index in range(len(res)): point = vertex[index] if len(point.strip().split('_')) < 2: continue if point in graph[root]: continue score_dict[point] = round(res[index], 3) for zuhe in sorted(score_dict.items(), key=operator.itemgetter(1), reverse=True)[:recom_num]: point, score = zuhe[0], zuhe[1] recom_dict[point] = score return recom_dict
def _gmres(self, op, rhs): result, info = spla.gmres(op, rhs.ravel()) if info > 0: self.log.warn('Gmres failed to converge') elif info < 0: self.log.warn('Illegal Gmres input or breakdown') return result
def _jacobian_callback(self, X): """This function is passed to the internal solver to return the jacobian of the states with respect to the residuals.""" n_edge = 2*len(X) n_res = n_edge/2 A = LinearOperator((n_edge, n_edge), matvec=self._matvecFWD, dtype=float) J = np.zeros((n_res, n_res)) self._cache_J = self.provideJ() for irhs in np.arange(n_res): RHS = np.zeros((n_edge, 1)) RHS[irhs, 0] = 1.0 # Call GMRES to solve the linear system dx, info = gmres(A, RHS, tol=1.0e-9, maxiter=100) J[:, irhs] = dx[n_res:] return J
def _jacobian_callback(self, X): """This function is passed to the internal solver to return the jacobian of the states with respect to the residuals.""" n_edge = 2 * len(X) n_res = n_edge / 2 A = LinearOperator((n_edge, n_edge), matvec=self._matvecFWD, dtype=float) J = np.zeros((n_res, n_res)) self._cache_J = self.provideJ() for irhs in np.arange(n_res): RHS = np.zeros((n_edge, 1)) RHS[irhs, 0] = 1.0 # Call GMRES to solve the linear system dx, info = gmres(A, RHS, tol=1.0e-9, maxiter=100) if info > 0: msg = "ERROR in '%s': gmres failed to converge after %d iterations at index %d" self._logger.error(msg % (self.get_pathname(), info, irhs)) elif info < 0: self._logger.error("ERROR in '%s': gmres failed at index %d" % (self.get_pathname(), irhs)) J[:, irhs] = dx[n_res:] return J
def solve(self, b, tol=1.0e-10): ''' Solve `Ax = b` for `x` Parameters ---------- b : (n,) array tol : float, optional Returns ------- (n,) array ''' # solve the system using GMRES and define the callback function to # print info for each iteration def callback(res, _itr=[0]): l2 = np.linalg.norm(res) LOGGER.debug('GMRES error on iteration %s: %s' % (_itr[0], l2)) _itr[0] += 1 LOGGER.debug('solving the system with GMRES') x, info = spla.gmres(self.A, b / self.n, tol=tol, M=self.M, callback=callback) LOGGER.debug('finished GMRES with info %s' % info) return x
def solve(self, rhs_mat, system, mode): """ Solves the linear system for the problem in self.system. The full solution vector is returned. Args ---- rhs_mat : dict of ndarray Dictionary containing one ndarry per top level quantity of interest. Each array contains the right-hand side for the linear solve. system : `System` Parent `System` object. mode : string Derivative mode, can be 'fwd' or 'rev'. Returns ------- dict of ndarray : Solution vectors """ unknowns_mat = {} for voi, rhs in rhs_mat.items(): # Scipy can only handle one right-hand-side at a time. self.voi = voi n_edge = len(rhs) A = LinearOperator((n_edge, n_edge), matvec=self.mult, dtype=float) self.system = system options = self.options self.mode = mode # Call GMRES to solve the linear system d_unknowns, info = gmres(A, rhs, tol=options['atol'], maxiter=options['maxiter']) # TODO: Talk about warn/error logging if info > 0: msg = "ERROR in solve in '%s': gmres failed to converge " \ "after %d iterations" print(msg) #logger.error(msg, system.name, info) elif info < 0: msg = "ERROR in solve in '%s': gmres failed" print(msg) #logger.error(msg, system.name) unknowns_mat[voi] = d_unknowns #print system.name, 'Linear solution vec', d_unknowns self.system = None return unknowns_mat
def calc_gradient_adjoint(wflow, inputs, outputs, n_edge, shape): """Returns the gradient of the passed outputs with respect to all passed inputs. Calculation is done in adjoint mode. """ # Size the problem A = LinearOperator((n_edge, n_edge), matvec=wflow.matvecREV, dtype=float) J = zeros(shape) # Each comp calculates its own derivatives at the current # point. (i.e., linearizes) wflow.calc_derivatives(first=True) # Adjoint mode, solve linear system for each output j = 0 for output in outputs: if isinstance(output, tuple): output = output[0] i1, i2 = wflow.get_bounds(output) if isinstance(i1, list): out_range = i1 else: out_range = range(i1, i2) options = wflow._parent.gradient_options for irhs in out_range: RHS = zeros((n_edge, 1)) RHS[irhs, 0] = 1.0 # Call GMRES to solve the linear system dx, info = gmres(A, RHS, tol=options.gmres_tolerance, maxiter=options.gmres_maxiter) i = 0 for param in inputs: if isinstance(param, tuple): param = param[0] k1, k2 = wflow.get_bounds(param) if isinstance(k1, list): J[j, i:i+(len(k1))] = dx[k1:k2] i += len(k1) else: J[j, i:i+(k2-k1)] = dx[k1:k2] i += k2-k1 j += 1 #print inputs, '\n', outputs, '\n', J, dx return J
def test_gmres_basic(): A = np.vander(np.arange(10) + 1)[:, ::-1] b = np.zeros(10) b[0] = 1 x = np.linalg.solve(A, b) x_gm, err = spla.gmres(A, b, restart=5, maxiter=1) assert_almost_equal(x_gm[0], 0.359, decimal=2)
def gmres(self, mat, rhs, lu): if 1: size = len(rhs) A = aslinearoperator(mat) M = LinearOperator((size, size), dtype=float, matvec=lu.solve) self.counter = 0 sol, info = gmres(A, rhs, M=M, maxiter=10, #callback=self.callback, tol=1e-12) return sol else: return lu.solve(rhs)
def _linear_analysis(self, method, **kwargs): """Performs the linear analysis, in which the pressure and flow fields are computed. INPUT: method: This can be either 'direct' or 'iterative' **kwargs precision: The accuracy to which the ls is to be solved. If not supplied, machine accuracy will be used. (This only applies to the iterative solver) OUTPUT: The maximum, mean, and median pressure change. Moreover, pressure and flow are modified in-place. """ G = self._G A = self._A.tocsr() if method == 'direct': linalg.use_solver(useUmfpack=True) x = linalg.spsolve(A, self._b) elif method == 'iterative': if kwargs.has_key('precision'): eps = kwargs['precision'] else: eps = self._eps AA = smoothed_aggregation_solver(A, max_levels=10, max_coarse=500) x = abs(AA.solve(self._b, x0=None, tol=eps, accel='cg', cycle='V', maxiter=150)) # abs required, as (small) negative pressures may arise elif method == 'iterative2': # Set linear solver ml = rootnode_solver(A, smooth=('energy', {'degree':2}), strength='evolution' ) M = ml.aspreconditioner(cycle='V') # Solve pressure system #x,info = gmres(A, self._b, tol=self._eps, maxiter=50, M=M, x0=self._x) #x,info = gmres(A, self._b, tol=self._eps/10000000000000, maxiter=50, M=M) x,info = gmres(A, self._b, tol=self._eps/10000, maxiter=50, M=M) if info != 0: print('SOLVEERROR in Solving the Matrix') pdiff = map(abs, [(p - xx) / p if p > 0 else 0.0 for p, xx in zip(G.vs['pressure'], x)]) maxPDiff = max(pdiff) meanPDiff = np.mean(pdiff) medianPDiff = np.median(pdiff) log.debug(np.nonzero(np.array(pdiff) == maxPDiff)[0]) G.vs['pressure'] = x G.es['flow'] = [abs(G.vs[edge.source]['pressure'] - \ G.vs[edge.target]['pressure']) * \ edge['conductance'] for edge in G.es] self._maxPDiff=maxPDiff self._meanPDiff=meanPDiff self._medianPDiff=medianPDiff return maxPDiff, meanPDiff, medianPDiff
def test(mesh, normalize=False, scipy_solver='lu'): V = FunctionSpace(mesh, 'Lagrange', 1) bc= DirichletBC(V, Constant(0.0), DomainBoundary()) u =TrialFunction(V) v = TestFunction(V) f = Constant(1.0) a = inner(grad(u), grad(v))*dx L = f*v*dx A, b = assemble_system(a, L, bc) if normalize: max = A.array().max() A /= max b /= max u = Function(V) solve(A, u.vector(), b) plot(u, interactive=True, title='dolfin') x = A.array() print "Value of A are [%g, %g]" %(x.min(), x.max()) print "Num of entries in A larger theb 100", np.where(x > 1E2)[0].sum() print "Number of mesh cells", mesh.num_cells() # see about scipy rows, cols, values = A.data() B = csr_matrix((values, cols, rows)) d = b.array().T if scipy_solver == 'cg': v_, info = cg(B, d) elif scipy_solver == 'bicg': v_, info = bicg(B, d) elif scipy_solver == 'bicgstab': v_, info = bicgstab(B, d) elif scipy_solver == 'gmres': v_, info = gmres(B, d) elif scipy_solver == 'minres': v_, info = minres(B, d) else: v_ = spsolve(B, d) v = Function(V) v.vector()[:] = v_ plot(v, interactive=True, title='scipy') try: print "info", info, 'v_max', v_.max() except: pass
def calcbase(): A = np.array([[1.,2.] # 行列Aの生成 ,[3.,4.]]) print("A=\n" + str(A)) rankA = np.linalg.matrix_rank(A) # 行列AのRank(階数)を計算 print("rank(A) = "+str(rankA)) detA = np.linalg.det(A) # 行列式の計算 print("det(A)="+str(detA)) print ("norm(A)="+str(np.linalg.norm(A))) B = A.T # 行列Aの転置 print("transposeofA = \n" + str(B)) #print(np.linalg.det(B)) invA = np.linalg.inv(A) # Aの逆行列 print( "invA=\n" + str(invA) ) # 計算結果の表示 # print(np.linalg.det(invA)) #L = np.linalg.cholesky(A) #print("L=\n"+str(L)) mean = np.mean(A) # 算術平均を計算 print(u"算術平均:"+str(mean)) # 結果を表示 y = [1., 2., 3., 4., 5., 5.5, 7., 9.] diff_y = np.diff(y) # yの差分を計算 print("y="+str(y)) # 結果を表示 print("diff(y)="+str(diff_y)) #連立方程式を解く A = np.array([[1.,3.] # 行列Aの生成 ,[4.,2.]]) B = np.array([1.,1.]) # 行列Bの生成 X = np.linalg.solve(A, B) # 計算結果の表示 print( "X=\n" + str(X) ) print np.linalg.eig(A) print spla.gmres(A,B)
def computeGreensFunc(self): L = LinearOperator((self.signalDataLen,self.signalDataLen), matvec=self.CNOperator, dtype=numpy.float32) rhs = numpy.zeros(self.gridDim, dtype=numpy.float32) idx = ( math.floor(self.gridDim[1]*0.5), math.floor(self.gridDim[2]*0.5), math.floor(self.gridDim[3]*0.5) ) for s in xrange(self.nSignals): rhs[(s,)+idx] = 1.0 # ~delta function in each signal (self.greensFunc, info) = gmres(L,rhs.reshape(self.signalDataLen)) # Solve impulse response = greens func # Take only bounding box of region where G > threshold self.greensFunc.shape = self.gridDim inds = numpy.transpose(numpy.nonzero(self.greensFunc.reshape(self.gridDim)>self.greensThreshold)) self.greensFunc = self.greensFunc[:, min(inds[:,1]):max(inds[:,1])+1, \ min(inds[:,2]):max(inds[:,2])+1, \ min(inds[:,3]):max(inds[:,3])+1] print "Truncated Green's function size is " + str(self.greensFunc.shape)
def solveLinSys(Q_, R_, way, myGuess, method = None): chi, chi = Q_.shape linOpWrap = functools.partial(linOpForT, Q_, R_, way) linOpForSol = spspla.LinearOperator((chi * chi, chi * chi), matvec = linOpWrap, dtype = 'float64') if(method == 'bicgstab'): S, info = spspla.lgmres(linOpForSol, np.zeros(chi * chi), tol = expS, x0 = myGuess, maxiter = maxIter, outer_k = 6) else:#if(method == 'gmres'): S, info = spspla.gmres(linOpForSol, np.zeros(chi * chi), tol = expS, x0 = myGuess, maxiter = maxIter) return info, S.reshape(chi, chi)
def iterative_solver_list(self, which, rhs, *args): """Solves the linear problem Ab = x using the sparse matrix Parameters ---------- rhs : ndarray the right hand side which : string choose which solver is used bicg(A, b[, x0, tol, maxiter, xtype, M, ...]) Use BIConjugate Gradient iteration to solve A x = b bicgstab(A, b[, x0, tol, maxiter, xtype, M, ...]) Use BIConjugate Gradient STABilized iteration to solve A x = b cg(A, b[, x0, tol, maxiter, xtype, M, callback]) Use Conjugate Gradient iteration to solve A x = b cgs(A, b[, x0, tol, maxiter, xtype, M, callback]) Use Conjugate Gradient Squared iteration to solve A x = b gmres(A, b[, x0, tol, restart, maxiter, ...]) Use Generalized Minimal RESidual iteration to solve A x = b. lgmres(A, b[, x0, tol, maxiter, M, ...]) Solve a matrix equation using the LGMRES algorithm. minres(A, b[, x0, shift, tol, maxiter, ...]) Use MINimum RESidual iteration to solve Ax=b qmr(A, b[, x0, tol, maxiter, xtype, M1, M2, ...]) Use Quasi-Minimal Residual iteration to solve A x = b """ if which == 'bicg': return spla.bicg(self.sp_matrix, rhs, args) elif which == "cg": return spla.cg(self.sp_matrix, rhs, args) elif which == "bicgstab": return spla.bicgstab(self.sp_matrix, rhs, args) elif which == "cgs": return spla.cgs(self.sp_matrix, rhs, args) elif which == "gmres": return spla.gmres(self.sp_matrix, rhs, args) elif which == "lgmres": return spla.lgmres(self.sp_matrix, rhs, args) elif which == "qmr": return spla.qmr(self.sp_matrix, rhs, args) else: raise NotImplementedError("this solver is unknown")
def gmres_solve(I,hx,q,sigma_t,sigma_s,N,BCs, tolerance = 1.0e-8,maxits = 100, LOUD=False, restart = 100, sweep1D = sweepDD1D ): """Solve, via GMRES, a single-group steady state problem Inputs: I: number of zones hx: size of each zone q: source array sigma_t: array of total cross-sections sigma_s: array of scattering cross-sections N: number of angles tolerance: the relative convergence tolerance for the iterations maxits: the maximum number of iterations LOUD: boolean to print out iteration stats Outputs: x: value of center of each zone phi: value of scalar flux in each zone """ #compute left-hand side LHS = np.zeros(I) MU, W = np.polynomial.legendre.leggauss(N) for n in range(N): tmp_psi = sweep1D(I,hx,q,sigma_t,MU[n],BCs[n]) LHS += tmp_psi*W[n] #define linear operator for gmres def linop(phi): tmp = phi*0 #sweep over each direction for n in range(N): tmp_psi = sweep1D(I,hx,phi*sigma_s,sigma_t,MU[n],BCs[n]) tmp += tmp_psi*W[n] return phi-tmp A = spla.LinearOperator((I,I), matvec = linop, dtype='d') #define a little function to call when the iteration is called iteration = np.zeros(1) err_list = [] def callback(rk, iteration=iteration, err_list=err_list): iteration += 1 err_list.append(np.linalg.norm(rk)) if (LOUD>0): print("Iteration",iteration[0],"norm of residual",np.linalg.norm(rk)) #now call GMRES phi,info = spla.gmres(A,LHS,x0=LHS,restart=restart, maxiter=maxits,tol=tolerance, callback=callback) if (LOUD): print("Finished in",iteration[0],"iterations.") if (info >0): print("Warning, convergence not achieved") x = np.linspace(hx*.5,I*hx-hx*.5,I) return x, phi, err_list
def solveForMu(Q_, R_, way, myGuess, method, X): chi, chi = Q_.shape inhom = supOp(R_, R_, way, X).reshape(chi * chi) #print "solveForMu:", way linOpWrap = functools.partial(linOpForExp, Q_, R_, way) linOpForSol = spspla.LinearOperator((chi * chi, chi * chi), matvec = linOpWrap, dtype = 'float64') if(method == 'bicgstab'): S, info = spspla.lgmres(linOpForSol, inhom, tol = expS, x0 = myGuess, maxiter = maxIter, outer_k = 6) else:#if(method == 'gmres'): S, info = spspla.gmres(linOpForSol, inhom, tol = expS, x0 = myGuess, maxiter = maxIter) return info, S.reshape(chi, chi)
def sweepFlux(self): """ For each angle and energy, solve a system of linear equations to update the flux scalar field on the mesh. """ innerResid = 0 for g in range(self.nG): for o in range(self.sNords): self.scFluxField[g, o], Aresid = \ spl.gmres(sps.csc_matrix(self.sysA[g, o]), self.sysRHS[g, o], tol=1e-5) innerResid += Aresid self.totFluxField += self.scFluxField for regionID, region in self.regions.iteritems(): fluxStor = (self.scFluxField, self.totFluxField) region.updateEleFluxes(fluxStor) return np.linalg.norm(self.scFluxField), innerResid
def sweepFlux(self, tolr): """ For each angle and energy, solve a system of linear equations to update the flux scalar field on the mesh. """ innerResid, Aresid = 0, 0 for g in range(self.nG): for o in range(self.sNords): self.scFluxField[g, o], Aresid = \ spl.gmres(self.sysA[g, o], self.sysRHS[g, o], tol=tolr, M=self.sysP[g, o]) if Aresid > 0: print("WARNING: Linear system solve failed. Terminated at gmres iter: " + str(Aresid)) self.totFluxField += self.scFluxField for regionID, region in self.regions.iteritems(): fluxStor = (self.scFluxField, self.totFluxField) region.updateEleFluxes(fluxStor) return np.linalg.norm(self.scFluxField) / np.linalg.norm(self.totFluxField), innerResid
def LinSolve(A,b,x0,method): if method=='bicg': x,info = bicg(A,b,x0) if method=='cgs': x,info = cgs(A,b,x0) if method=='bicgstab': x,info = bicgstab(A,b,x0) if (info): print 'INFO=',info if method=='superLU': x = linsolve.spsolve(A,b,use_umfpack=False) if method=='umfpack': x = linsolve.spsolve(A,b,use_umfpack=True) if method=='gmres': x,info = gmres(A,b,x0) if method=='lgmres': x,info = lgmres(A,b,x0) return x
def krylovMethod(self,tol=1e-8): """ Here we use the 'gmres' solver for the system of linear equations. It searches in Krylov subspace for a vector with minimal residual. Code due to http://stackoverflow.com/questions/21308848/ """ P = self.getTransitionMatrix() size = P.shape[0] dP = P - eye(size) A = vstack([np.ones(size), dP.T[1:,:]]).tocsr() rhs = np.zeros((size,)) rhs[0] = 1 pi, info = gmres(A, rhs, tol=tol) if info != 0: raise RuntimeError("gmres did not converge") self.pi = pi
def execute_Newton(self): """ Solver execution loop: Newton-Krylov. """ # Find dimension of our problem. nEdge = self.workflow.initialize_residual() A = LinearOperator((nEdge, nEdge), matvec=self.workflow.matvecFWD, dtype=float) # Initial Run self.run_iteration() # Initial residuals norm = numpy.linalg.norm(self.workflow.calculate_residuals()) print "Residual vector norm:\n", norm # Loop until convergence of residuals iter_num = 0 while (norm > self.tolerance) and (iter_num < self.max_iteration): # Each comp calculates its own derivatives at the current # point. (i.e., linearizes) self.workflow.calc_derivatives(first=True) # Call GMRES to solve the linear system dv, info = gmres(A, -self.workflow.res, tol=self.tolerance, maxiter=100) # Increment the model input edges by dv self.workflow.set_new_state(dv) # Run all components self.run_iteration() # New residuals norm = numpy.linalg.norm(self.workflow.calculate_residuals()) print "Residual vector norm:\n", norm iter_num += 1 self.record_case()
def solve(self, b, maxiter = 1000, tol = 1.e-10): """ Compute Q^{-1}b Parameters: ----------- b: (n,) ndarray given right hand side maxiter: int, optional. default = 1000 Maximum number of iterations for the linear solver tol: float, optional. default = 1.e-10 Residual stoppingtolerance for the iterative solver Notes: ------ If 'Dense' then inverts using LU factorization otherwise uses iterative solver - MINRES if used without preconditioner or GMRES with preconditioner. Preconditioner is not guaranteed to be positive definite. """ if self.method == 'Dense': from scipy.linalg import solve x = solve(self.mat, b) else: from scipy.sparse.linalg import gmres, aslinearoperator, minres P = self.P Aop = aslinearoperator(self) residual = _Residual() if P != None: x, info = gmres(Aop, b, tol = tol, restart = 30, maxiter = 1000, callback = residual, M = P) else: x, info = minres(Aop, b, tol = tol, maxiter = maxiter, callback = residual ) self.solvmatvecs += residual.itercount() if self.verbose: print "Number of iterations is %g and status is %g"% (residual.itercount(), info) return x
def update_propability_mass(self): """Create a total flux matrix, and propogate self.pv one time-step.""" # import scipy.linalg as spla # import matplotlib.pyplot as plt # # if self.simulation.t > .09: # # for key, val in self.total_input_dict.items(): # print key, val # # evs = spla.eigvals(J*self.simulation.dt) # evs_re = np.real(evs) # evs_im = np.imag(evs) # plt.plot(evs_re, evs_im, '.') # plt.show() if self.update_method == 'exact': J = self.get_total_flux_matrix() self.pv = util.exact_update_method(J, self.pv, dt=self.simulation.dt) elif self.update_method == 'approx': J = self.get_total_flux_matrix() if self.approx_order == None: self.pv = util.approx_update_method_tol(J, self.pv, tol=self.tol, dt=self.simulation.dt, norm=self.norm) else: self.pv = util.approx_update_method_order(J, self.pv, approx_order=self.approx_order, dt=self.simulation.dt) elif self.update_method == 'gmres': self.update_propability_mass_backward_euler(lambda J, x0: spsla.gmres(J, x0, x0=x0, tol=self.tol)[0]) else: raise Exception('Unrecognized population update method: "%s"' % self.update_method) # pragma: no cover # Checking stability of if len(np.where(self.pv<0)[0]) != 0 or np.abs(np.abs(self.pv).sum() - 1) > 1e-15: self.pv[np.where(self.pv<0)] = 0 self.pv /= self.pv.sum() logger.critical('Normalizing Probability Mass')
def computeProductCompressor(formMatrix,L,R,new_dimension): if L.shape[1] != L.shape[2]: raise ValueError("left inward dimensions do not match (given " + str(L.shape) + ")") if R.shape[0] != R.shape[1]: raise ValueError("right inward dimensions do not match (given " + str(R.shape) + ")") if L.shape[1] != R.shape[1]: raise ValueError("left and right shapes are incompatible (given " + str(L.shape) + " and " + str(R.shape) + ")") old_dimension = L.shape[1] b = L.contractWith(R,(1,2,3),(0,1,2)).toArray().ravel() compressor = NDArrayData.newRandom(old_dimension,new_dimension).unitize() for _ in range(4): A = formMatrix(L,compressor.conj(),compressor.transpose().conj(),compressor.transpose(),R).toArray() At = A.transpose().conj() x, info = gmres( LinearOperator((old_dimension*new_dimension,)*2,lambda v: dot(At,dot(A,v)),dtype=complex128), dot(At,b) ) assert info == 0 compressor = NDArrayData(x.reshape(old_dimension,new_dimension)).unitize() return compressor.transpose()
def solve(self, initial_guess = 0., solver = 'spsolve'): """ Solves the full saddle points system after construction of the LHS and RHS of the problem. Returns the full solution vector. """ self.solution = np.zeros(self.mesh.get_number_of_faces() + self.mesh.get_number_of_cells()) if solver == 'spsolve': self.lhs = self.lhs.tocsc() self.solution = linalg.spsolve(self.lhs, self.rhs) elif solver == 'gmres': self.lhs = self.lhs.tocsc() [self.solution, converged] = linalg.gmres(self.lhs, self.rhs, tol=1.e-8) if converged > 0: print "did not converge after", converged return self.solution
def solve_bvp(self,wave_number,rhs): from scipy.sparse.linalg import gmres from bempp.tools import RealOperator self._residuals[wave_number] = [] def evaluate_residual(res): self._residuals[wave_number].append(res) n = len(rhs[0]) rhs_dual = (self._identity*rhs[0].reshape(n,1)).ravel() op_found_in_cache = False if self._operator_cache: try: op = self._boundary_operator_cache(wave_number) op_found_in_cache = True except: pass if not op_found_in_cache: slp_bnd_op = _bempplib.createMaxwell3dSingleLayerBoundaryOperator(self._context,self._space, self._space,self._space, 1.0j*wave_number).weakForm() slp_bnd_op_real = RealOperator(slp_bnd_op) prec = None if self._use_aca_lu_preconditioner: prec = RealOperator(_bempplib.acaOperatorApproximateLuInverse(slp_bnd_op,self._aca_lu_delta)) if self._operator_cache: self._boundary_operator_cache.insert(wave_number,(slp_bnd_op_real,prec)) rhs_dual_real = _np.hstack([_np.real(rhs_dual),_np.imag(rhs_dual)]) sol_real,info = gmres(slp_bnd_op_real,rhs_dual_real,tol=self._gmres_tol,maxiter=self._gmres_max_iter,M=prec,callback=evaluate_residual) if info != 0: raise Exception('GMRES did not converge for wavenumber '+str(wave_number)+'.') sol = sol_real[:n]+1j*sol_real[n:] return [sol.ravel()]