def _calc_sc_1ph(net, bus): """ calculation method for single phase to ground short-circuit currents """ _add_auxiliary_elements(net) # pos. seq bus impedance ppc, ppci = _pd2ppc(net) _calc_ybus(ppci) # zero seq bus impedance ppc_0, ppci_0 = _pd2ppc_zero(net) _calc_ybus(ppci_0) if net["_options"]["inverse_y"]: _calc_zbus(net, ppci) _calc_zbus(net, ppci_0) else: # Factorization Ybus once ppci["internal"]["ybus_fact"] = factorized(ppci["internal"]["Ybus"]) ppci_0["internal"]["ybus_fact"] = factorized( ppci_0["internal"]["Ybus"]) _calc_rx(net, ppci, bus=bus) _add_kappa_to_ppc(net, ppci) _calc_rx(net, ppci_0, bus=bus) _calc_ikss_1ph(net, ppci, ppci_0, bus=bus) if net._options["branch_results"]: _calc_branch_currents(net, ppci, bus=bus) ppc_0 = _copy_results_ppci_to_ppc(ppci_0, ppc_0, "sc") ppc = _copy_results_ppci_to_ppc(ppci, ppc, "sc") _extract_results(net, ppc, ppc_0, bus=bus) _clean_up(net)
def __init__(self, shape, viscosity, quantities): self.shape = shape # Defining these here keeps the code somewhat more readable vs. computing them every time they're needed. self.size = np.product(shape) self.dimensions = len(shape) # Variable viscosity, both in time and in space, is easy to set up; but it conflicts with the use of # SciPy's factorized function because the diffusion matrix must be recalculated every frame. # In order to keep the simulation speedy I use fixed viscosity. self.viscosity = viscosity # By dynamically creating advected-diffused quantities as needed prototyping becomes much easier. self.quantities = {} for q in quantities: self.quantities[q] = np.zeros(self.size) self.velocity_field = np.zeros((self.size, self.dimensions)) # The reshaping here corresponds to a partial flattening so that self.indices # has the same shape as self.velocity_field. # This makes calculating the advection map as simple as a single vectorized subtraction each frame. self.indices = np.dstack(np.indices(self.shape)).reshape( self.size, self.dimensions) self.gradient = ops.matrices( shape, ops.differences(1, (1, ) * self.dimensions), False) # Both viscosity and pressure equations are just Poisson equations similar to the steady state heat equation. laplacian = ops.matrices(shape, ops.differences(1, (2, ) * self.dimensions), True) self.pressure_solver = factorized(laplacian) # Making sure I use the sparse version of the identity function here so I don't cast to a dense matrix. self.viscosity_solver = factorized( sp.identity(self.size) - laplacian * viscosity)
def set_matrices(self): """Set up all required matrices.""" self.set_A1() self.set_A2() self.set_B1() self.set_B2() self.set_M() self.fA1 = linalg.factorized(self.A1) self.fA2 = linalg.factorized(self.A2) self.fM = linalg.factorized(self.M) self.fA2t = linalg.factorized(self.A2[1:-1, 1:-1])
def generate_direct_solver(self, grid=None): """Generates direct solver from a LU factorization of the sparse matrix """ if grid is None: # LOG.debug("Generate Solver for internal Spare Matrix: %s" % self.sp_matrix) solver = spla.factorized(self.sp_matrix) else: # LOG.debug("Generate Solver for given Grid %s" % (grid,)) sp_matrix = self.to_sparse_matrix(grid, "csc") # LOG.debug(" with Sparse Matrix: %s" % sp_matrix.todense()) # print("Jahier\n", sp_matrix.todense()) # print("Jahier.shape\n", sp_matrix.todense().shape) solver = spla.factorized(sp_matrix) return solver
def __init__(me, V, max_smooth_vectors=50): R = fenics.FunctionSpace(V.mesh(), 'R', 0) u_trial = fenics.TrialFunction(V) v_test = fenics.TestFunction(V) c_trial = fenics.TrialFunction(R) d_test = fenics.TestFunction(R) a11 = fenics.inner(fenics.grad(u_trial), fenics.grad(v_test)) * fenics.dx a12 = c_trial * v_test * fenics.dx a21 = u_trial * d_test * fenics.dx A11 = convert_fenics_csr_matrix_to_scipy_csr_matrix( fenics.assemble(a11)) A12 = convert_fenics_csr_matrix_to_scipy_csr_matrix( fenics.assemble(a12)) A21 = convert_fenics_csr_matrix_to_scipy_csr_matrix( fenics.assemble(a21)) me.A = sps.bmat([[A11, A12], [A21, None]]).tocsc() solve_A = spla.factorized(me.A) m = u_trial * v_test * fenics.dx me.M = convert_fenics_csr_matrix_to_scipy_csr_matrix( fenics.assemble(m)).tocsc() solve_M = spla.factorized(me.M) def solve_neumann(f_vec): fe_vec = np.concatenate([f_vec, np.array([0])]) ue_vec = solve_A(fe_vec) u_vec = ue_vec[:-1] return u_vec me.solve_neumann_linop = spla.LinearOperator((V.dim(), V.dim()), matvec=solve_neumann) me.solve_M_linop = spla.LinearOperator((V.dim(), V.dim()), matvec=solve_M) ee, UU = spla.eigsh(me.solve_neumann_linop, k=max_smooth_vectors - 1, M=me.solve_M_linop, which='LM') me.U_smooth = np.zeros((V.dim(), max_smooth_vectors)) const_fct = np.ones(V.dim()) me.U_smooth[:, 0] = const_fct / np.sqrt( np.dot(const_fct, me.M * const_fct)) me.U_smooth[:, 1:] = solve_M(UU[:, ::-1]) me.k = 0
def __init__(self,shape,As,projector,gamma,B=None,metric=None,verificators=None,solver='factorize') : self.metric=sp.eye(shape[0]) if metric is None else metric self.verificators=len(As)*[None] if verificators is None else verificators self.solver=solver self.check_init(shape,As,projector,gamma,B,self.metric,self.verificators,self.solver) self.Alist=As self.gamma=gamma self.ATlist=[A.T.tocsr() for A in self.Alist] # print('transposition done') M=self.metric.copy() for (A,AT,g) in zip(self.Alist,self.ATlist,self.gamma) : M=M+g*g*AT.dot(A) # print('Matrix M assembly done') self.M= M if B==None else sp.bmat([[M,B.T],[B,None]]) if self.solver=='factorize' : self.M_factorized=factorized(self.M.tocsc()) self.Alist=[A.tocsr() for A in self.Alist] # print('Matrix M factorization done') self.projector=projector self.shape_x=(shape[0],shape[1]) self.indices_y=[] begin=0 for A in self.Alist : self.indices_y.append((begin,begin+A.shape[0])) begin+=A.shape[0] self.shape_y=(begin,self.shape_x[1])
def solve(A, weights, reg, x0, b, precomputed_ATW=None, precomputed_ATWA=None, precomputed_K_factorized=None): """regularized weighted solve Parameters ---------- A : :class:`scipy.sparse.csr` the matrix, N (equations) x M (degrees of freedom) weights : :class:`scipy.sparse.csr_matrix` N x N diagonal matrix containing weights reg : :class:`scipy.sparse.csr_matrix` M x M diagonal matrix containing regularizations x0 : :class:`numpy.ndarray` M x nsolve float constraint values for the DOFs b : :class:`numpy.ndarray`: N x nsolve float right-hand-side(s) precomputed_ATW : :class:`scipy.sparse.csc_matrix` value to use rather than computing A.T.dot(weights) precomputed_ATWA : :class:`scipy.sparse.csc_matrix` value to use rather than computing A.T.dot(weights).dot(A) precomputed_K_factorized : func factorized solve function to use rather than computing scipy.sparse.linalg.factorized(A.T.dot(weights).dot(A) + reg) Returns ------- solution : list of numpy.ndarray list of numpy arrays of x and y vertex positions of solution errx : numpy.ndarray numpy array of x residuals erry : numpy.ndarray numpy array of y residuals """ ATW = (A.transpose().dot(weights) if precomputed_ATW is None else precomputed_ATW) if precomputed_K_factorized is None: K = (ATW.dot(A) if precomputed_ATWA is None else precomputed_ATWA) + reg K_factorized = factorized(K) else: K_factorized = precomputed_K_factorized solution = [] i = 0 for x in x0: Lm = reg.dot(x) + ATW.dot(b[:, i]) i += 1 solution.append(K_factorized(Lm)) errx = A.dot(solution[0]) - b[:, 0] erry = A.dot(solution[1]) - b[:, 1] return solution, errx, erry
def _init_matrices(self): from scipy.sparse.linalg import factorized from scipy.sparse import csc_matrix intp_mat = np.zeros((self.n_window * self.dim_ext, self.n_window * self.dim_ext)) sum_mat = np.zeros((self.dim_ext, self.n_window * self.dim_ext)) # nex = self.n_ext nwi = self.n_window nwi2 = (self.n_window - 1) / 2 # print self.dim_ext for i in range(0, self.dim_ext): for m in range(nwi): intp_mat[nwi * i + m, nwi * i:nwi * (1 + i)] = ( self.grid_ext[i:i + nwi]**m * self.widths_ext[i:i + nwi]) idx = lambda i: [(i-k)*nwi + k + nwi2 for k in range(-nwi2, nwi2 +1) if 0 <= ((i-k)*nwi + k + nwi2) < self.n_window*self.dim_ext] for i in range(self.dim_ext): sum_mat[i, idx(i)] = 1. self.intp_mat = csc_matrix(intp_mat) self.sum_mat = csc_matrix(sum_mat) self.solver = factorized(self.intp_mat)
def make_matrix_square_root_applier(A, check_error=True): A = A.tocsr() weights, poles, _ = matrix_inverse_square_root_rational_weights_and_poles( A) N = len(weights) AA = [A - poles[k] * sps.eye(A.shape[0]) for k in range(N)] AA_solvers = [spla.factorized(A) for A in AA] def apply_isqrtA(v): u = np.zeros(v.shape) for k in range(N): u = u + weights[k] * AA_solvers[k](v) return u def apply_sqrtA(v): return A * apply_isqrtA(v) if check_error: v = np.random.randn(A.shape[1]) u1 = apply_sqrtA(apply_sqrtA(v)) u2 = A * v sqrt_err = np.linalg.norm(u1 - u2) / np.linalg.norm(u2) print('sqrt_err=', sqrt_err) return apply_sqrtA
def modified_newton(func, U0, jac, tol=1.0e-6, maxiter=10, ifprint=False): """ 修正牛顿法求解非线性方程组(荷载步内不更新刚度矩阵) func ---- 函数,平衡方程,变量为U U0 ---- 解的初始估计值 jac ---- 切线刚度 \partial{func} / \partial{U} tol ---- 收敛容差(相对) maxiter ---- 最多迭代次数 """ U = U0 conv = 0 K = jac(U) solve = spsl.factorized(K) # Makes LU decomposition. for niter in xrange(maxiter): UF = func(U) dU = -solve(UF) # Uses the LU factors. nerr = np.linalg.norm(dU) / np.linalg.norm(U) if nerr > tol: U = U0 + dU else: break if ifprint: if niter < maxiter - 1: print "Converged after %d iterations, norm error = %.4g %%." % (niter + 1, nerr) conv = 1 else: print "Fail to Converge after %d iterations, norm error = %.4g %%." % (maxiter, nerr) return U, conv
def _kappa_method_c(net, ppc): if net.f_hz == 50: fc = 20 elif net.f_hz == 60: fc = 24 else: raise ValueError( "Frequency has to be 50 Hz or 60 Hz according to the standard") ppc_c = copy.deepcopy(ppc) ppc_c["branch"][:, BR_X] *= fc / net.f_hz zero_conductance = np.where(ppc["bus"][:, GS] == 0) ppc["bus"][zero_conductance, BS] *= net.f_hz / fc conductance = np.where(ppc["bus"][:, GS] != 0) z_shunt = 1 / (ppc_c["bus"][conductance, GS] + 1j * ppc_c["bus"][conductance, BS]) y_shunt = 1 / (z_shunt.real + 1j * z_shunt.imag * fc / net.f_hz) ppc_c["bus"][conductance, GS] = y_shunt.real[0] ppc_c["bus"][conductance, BS] = y_shunt.imag[0] _calc_ybus(ppc_c) if net["_options"]["inverse_y"]: _calc_zbus(net, ppc_c) else: # Factorization Ybus once ppc_c["internal"]["ybus_fact"] = factorized(ppc_c["internal"]["Ybus"]) _calc_rx(net, ppc_c, bus=None) rx_equiv_c = ppc_c["bus"][:, R_EQUIV] / ppc_c["bus"][:, X_EQUIV] * fc / net.f_hz return _kappa(rx_equiv_c)
def setUp(self): self.NV = 200 self.NP = 40 self.NY = 5 self.NU = self.NY + 3 self.verbose = False self.comprthresh = 1e-6 # threshhold for SVD trunc. for compr. of Z self.nwtn_adi_dict = dict(adi_max_steps=300, adi_newZ_reltol=1e-11, nwtn_max_steps=24, nwtn_upd_reltol=4e-7, nwtn_upd_abstol=4e-7, full_upd_norm_check=True, verbose=self.verbose) # -F, M spd -- coefficient matrices self.F = -sps.eye(self.NV) - \ sps.rand(self.NV, self.NV) * sps.rand(self.NV, self.NV) self.M = sps.eye(self.NV) + \ sps.rand(self.NV, self.NV) * sps.rand(self.NV, self.NV) try: self.Mlu = spsla.factorized(self.M.tocsc()) except RuntimeError: print 'M is not full rank' # bmatrix that appears in the nonliner ric term X*B*B.T*X self.bmat = np.random.randn(self.NV, self.NU) # right-handside: C= -W*W.T self.W = np.random.randn(self.NV, self.NY) # smw formula Asmw = A - UV self.U = 1e-4 * np.random.randn(self.NV, self.NY) self.Usp = 1e-4 * sps.rand(self.NV, self.NY) self.V = np.random.randn(self.NY, self.NV) self.uvs = sps.csr_matrix(np.dot(self.U, self.V)) self.uvssp = sps.csr_matrix(self.Usp * self.V) # initial value for newton adi self.Z0 = np.random.randn(self.NV, self.NY) # we need J sparse and of full rank for auxk in range(10): try: self.J = sps.rand(self.NP, self.NV, density=0.03, format='csr') spsla.splu((self.J * self.J.T).tocsc()) break except RuntimeError: if self.verbose: print 'J not full row-rank.. I make another try' try: spsla.splu((self.J * self.J.T).tocsc()) except RuntimeError: raise Warning('Fail: J is not full rank') # the Leray projector MinvJt = lau.app_luinv_to_spmat(self.Mlu, self.J.T) Sinv = np.linalg.inv(self.J * MinvJt) self.P = np.eye(self.NV) - np.dot(MinvJt, Sinv * self.J)
def compute_cycle_currents(r_mat, v_vec, cyclebasis): # special case for no cycles (which otherwise makes a singular matrix) if len(cyclebasis) == 0: return np.array([], dtype=v_vec.dtype) solver = spla.factorized(r_mat.tocsc()) return solver(v_vec).reshape([len(cyclebasis)])
def gaussSeidel(A): dd = A.diagonal() D = spsp.dia_matrix(A.shape) D.setdiag(dd) L = spsp.tril(A, -1) U = spsp.triu(A, 1) return splinalg.factorized(D + L)
def diff_tangent(self, dependees_diff_u): if hasattr(self, 'residual') and self.residual: resid_diff_u, = dependees_diff_u if resid_diff_u is 0: return 0 else: # inverse of Jacobian matrix resid_diff_self = self.jacobian # check if diagonal matrix n = resid_diff_self.shape[0] try: is_diag = resid_diff_self.indices.size == n and \ resid_diff_self.indptr.size == n+1 and \ all(resid_diff_self.indices == np.arange(n)) and \ all(resid_diff_self.indptr == np.arange(n+1)) except TypeError: is_diag = False if is_diag: # inverse of diagonal matrix self_diff_resid = resid_diff_self.copy() self_diff_resid.data = 1 / np.array(self_diff_resid.data) self_diff_u = -self_diff_resid * resid_diff_u return self_diff_u else: if hasattr(resid_diff_u, 'todense'): resid_diff_u = resid_diff_u.todense() resid_diff_u = np.array(resid_diff_u) self_diff_resid = splinalg.factorized(resid_diff_self.tocsc()) self_diff_u = np.transpose([-self_diff_resid(b) \ for b in resid_diff_u.T]) self_diff_u = self_diff_u.reshape(resid_diff_u.shape) return sp.csr_matrix(self_diff_u) else: return 0
def matricles(): N = 2000 # A = scipy.sparse.rand(N,N,0.2) # A = A + scipy.sparse.spdiags(np.ones(N),0,N,N) # A = A.tocoo() # AC = cvxopt.spmatrix(A.data.tolist(),A.row.tolist(), A.col.tolist()) # b = cvxopt.normal(N,1) for superIx in range(5): A = scipy.sparse.rand(N,N,0.2) A = A + scipy.sparse.spdiags(np.ones(N),0,N,N) A = A.tocsr() b = np.random.randn(N) for ix in range(1): b = np.random.randn(N) ti = time.time() P = wrapCvxopt.staticSolver(A) uOPT = P(b) print 'cvx opt time = ' + repr(time.time()-ti) ti = time.time() Q = lin.factorized(A) uSPS = Q(b) print 'scipy time = ' + repr(time.time() - ti) print np.linalg.norm(uOPT-uSPS)
def test_factorized(B): if B.__class__.__name__[:3] != 'csc': return LU = spla.factorized(B) npt.assert_allclose(LU(np.array([1, 2])), np.linalg.solve(B.todense(), [1, 2]))
def diff_adjoint(self, f_diff_dependers): f_diff_self = 0 iter_f_diff_dependers = iter(f_diff_dependers) if hasattr(self, 'solution') and self.solution(): f_diff_soln = next(iter_f_diff_dependers) if f_diff_soln is not 0: # inverse of Jacobian matrix self_diff_soln = self.solution().jacobian.T # check if diagonal matrix n = self_diff_soln.shape[0] try: is_diag = all(self_diff_soln.indices == arange(n)) and \ all(self_diff_soln.indptr == arange(n+1)) except TypeError: is_diag = False if is_diag: assert f_diff_soln.shape[-1] == n # inverse of diagonal matrix soln_diff_self = self_diff_soln.copy() soln_diff_self.data = 1. / np.array(soln_diff_self.data) f_diff_self = -f_diff_soln * soln_diff_self else: if hasattr(f_diff_soln, 'todense'): f_diff_soln = f_diff_soln.todense() f_diff_soln = np.array(f_diff_soln) soln_diff_self = splinalg.factorized(self_diff_soln.tocsc()) f_diff_self = np.array([-soln_diff_self(b) \ for b in f_diff_soln]) f_diff_self = np.matrix(f_diff_self.reshape(f_diff_soln.shape)) f_diff_self_1 = IntermediateState.diff_adjoint(self, iter_f_diff_dependers) return _add_ops(f_diff_self, f_diff_self_1)
def solveDirect_scipy(self, b, factorize): """ Use solve instead of this interface. :param numpy.ndarray b: the right hand side :param bool factorize: if you want to factorize and store factors :rtype: numpy.ndarray :return: x """ if factorize and self.dsolve is None: self.A = self.A.tocsc() # for efficiency self.dsolve = linalg.factorized(self.A) if len(b.shape) == 1 or b.shape[1] == 1: # Just one RHS if factorize: return self.dsolve(b.flatten()) else: return linalg.dsolve.spsolve(self.A, b) # Multiple RHSs X = np.empty_like(b) for i in range(b.shape[1]): if factorize: X[:,i] = self.dsolve(b[:,i]) else: X[:,i] = linalg.dsolve.spsolve(self.A,b[:,i]) return X
def Modif_Ytrans(): global Ytrans, Ytrans_mod, Y_Vsp_PV, N, Buses_type, solve, branches_buses, list_gen Ytrans_mod = np.zeros((2 * N, 2 * N), dtype=float) Y_Vsp_PV = [] for i in range(N): if Buses_type[i] == 'Slack': Ytrans_mod[2 * i][2 * i] = 1 Ytrans_mod[2 * i + 1][2 * i + 1] = 1 else: for j in branches_buses[i]: Ytrans_mod[2 * i][2 * j] = Ytrans[i][j].real Ytrans_mod[2 * i][2 * j + 1] = Ytrans[i][j].imag * -1 Ytrans_mod[2 * i + 1][2 * j] = Ytrans[i][j].imag Ytrans_mod[2 * i + 1][2 * j + 1] = Ytrans[i][j].real for i in list_gen: array = np.zeros(2 * len(branches_buses[i]), dtype=float) pos = 0 for k in branches_buses[i]: array[pos] = Ytrans_mod[2 * k][2 * i] array[pos + 1] = Ytrans_mod[2 * k + 1][2 * i] Ytrans_mod[2 * k][2 * i] = 0 Ytrans_mod[2 * k + 1][2 * i] = 0 pos += 2 Y_Vsp_PV.append([i, array.copy()]) Ytrans_mod[2 * i + 1][2 * i] = 1 # Return a function for solving a sparse linear system, with Ytrans_mod pre-factorized. solve = factorized(csc_matrix(Ytrans_mod))
def get_regularized_c(Ct=None, J=None, Mt=None): """apply the regularization (projection to divfree vels) i.e. compute rC = C*[I-M^-1*J.T*S^-1*J] as rCT = [I - J.T*S.-T*J*M.-T]*C.T """ raise UserWarning('deprecated - use more explicit approach to proj via ' + 'sadpoints systems as implemented in linalg_utils') Nv, NY = Mt.shape[0], Ct.shape[1] try: rCt = np.load('data/regCNY{0}vdim{1}.npy'.format(NY, Nv)) except IOError: print 'no data/regCNY{0}vdim{1}.npy'.format(NY, Nv) MTlu = spsla.factorized(Mt) auCt = np.zeros(Ct.shape) # M.-T*C.T for ccol in range(NY): auCt[:, ccol] = MTlu(np.array(Ct[:, ccol].todense())[:, 0]) # J*M.-T*C.T auCt = J * auCt # S.-T*J*M.-T*C.T auCt = lau.app_schurc_inv(MTlu, J, auCt) rCt = Ct - J.T * auCt np.save('data/regCNY{0}vdim{1}.npy'.format(NY, Nv), rCt) return np.array(rCt)
def _calc_sc(net, bus): _add_auxiliary_elements(net) ppc, ppci = _pd2ppc(net) _calc_ybus(ppci) if net["_options"]["inverse_y"]: _calc_zbus(net, ppci) else: # Factorization Ybus once ppci["internal"]["ybus_fact"] = factorized(ppci["internal"]["Ybus"]) _calc_rx(net, ppci, bus) # kappa required inverse of Zbus, which is optimized if net["_options"]["kappa"]: _add_kappa_to_ppc(net, ppci) _calc_ikss(net, ppci, bus) if net["_options"]["ip"]: _calc_ip(net, ppci) if net["_options"]["ith"]: _calc_ith(net, ppci) if net._options["branch_results"]: _calc_branch_currents(net, ppci, bus) ppc = _copy_results_ppci_to_ppc(ppci, ppc, "sc") _extract_results(net, ppc, ppc_0=None, bus=bus) _clean_up(net) if "ybus_fact" in ppci["internal"]: # Delete factorization object ppci["internal"].pop("ybus_fact")
def __init__(self, y): # Pre-cache a sparse LU decomposition of the FL matrix from pygfl.utils import get_1d_penalty_matrix from scipy.sparse.linalg import factorized from scipy.sparse import csc_matrix D = get_1d_penalty_matrix(y.shape[0]) D = np.vstack([D, np.zeros(y.shape[0])]) D[-1,-1] = 1e-6 # Nugget for full rank matrix D = csc_matrix(D) self.invD = factorized(D) # Setup the fast GFL solver from pygfl.solver import TrailSolver from pygfl.trails import decompose_graph from pygfl.utils import hypercube_edges, chains_to_trails from networkx import Graph edges = hypercube_edges(y.shape) g = Graph() g.add_edges_from(edges) chains = decompose_graph(g, heuristic='greedy') ntrails, trails, breakpoints, edges = chains_to_trails(chains) self.solver = TrailSolver() self.solver.set_data(y, edges, ntrails, trails, breakpoints) from pygfl.easy import solve_gfl self.beta = solve_gfl(y)
def calculate_continuity_constant(gq, lq): A = gq["op"].matrix H1 = gq["k_product"].matrix Y = H1 X = H1 try: a = gq["data"]['boundary_info'].dirichlet_boundaries(2) b = np.arange(A.shape[0]) c = np.delete(b, a) A = A[:, c][c, :] X = X[:, c][c, :] Y = Y[:, c][c, :] except KeyError: pass Yinv = sp.factorized(Y.astype(complex)) def mv(v): return A.H.dot(Yinv(A.dot(v))) M1 = LinearOperator(A.shape, matvec=mv) eigvals = sp.eigs(M1, M=X, k=1, tol=1e-4)[0] eigvals = np.sqrt(np.abs(eigvals)) eigvals[::-1].sort() result = eigvals[0] gq["continuity_constant"] = result print("calculated_continuity_constant: ", result) return result
def update_z(xyz, Q, C, p, free, fixed, updateloads, tol=1e-3, kmax=100, display=False): Ci = C[:, free] Cf = C[:, fixed] Ct = C.transpose() Cit = Ci.transpose() A = Cit.dot(Q).dot(Ci) A_solve = factorized(A) B = Cit.dot(Q).dot(Cf) CtQC = Ct.dot(Q).dot(C) updateloads(p, xyz) for k in range(kmax): if display: print(k) xyz[free, 2] = A_solve(p[free, 2] - B.dot(xyz[fixed, 2])) updateloads(p, xyz) r = CtQC.dot(xyz[:, 2]) - p[:, 2] residual = norm(r[free]) if residual < tol: break return residual
def solveDirect_scipy(self, b, factorize): """ Use solve instead of this interface. :param numpy.ndarray b: the right hand side :param bool factorize: if you want to factorize and store factors :rtype: numpy.ndarray :return: x """ if factorize and self.dsolve is None: self.A = self.A.tocsc() # for efficiency self.dsolve = linalg.factorized(self.A) if len(b.shape) == 1 or b.shape[1] == 1: # Just one RHS if factorize: return self.dsolve(b.flatten()) else: return linalg.dsolve.spsolve(self.A, b) # Multiple RHSs X = np.empty_like(b) for i in range(b.shape[1]): if factorize: X[:, i] = self.dsolve(b[:, i]) else: X[:, i] = linalg.dsolve.spsolve(self.A, b[:, i]) return X
def solver_umfpack(A): """ Return a function for solving a sparse linear system using UMFPACK. Parameters ---------- A : (N, N) array_like Input. Returns ------- solve : callable To solve the linear system of equations given in `A`, the `solve` callable should be passed an ndarray of shape (N,). """ import scipy.sparse.linalg as spla #_useUmfpack = spla.dsolve.linsolve.useUmfpack spla.use_solver(useUmfpack=True) A.indptr = A.indptr.astype(np.int64) A.indices = A.indices.astype(np.int64) iA = spla.factorized(A) def solver(b, x0=None): return iA(b) #spla.use_solver(useUmfpack=_useUmfpack) return solver,
def solver_superlu(A): """ Return a function for solving a sparse linear system using SuperLU. Parameters ---------- A : (N, N) array_like Input. Returns ------- solve : callable To solve the linear system of equations given in `A`, the `solve` callable should be passed an ndarray of shape (N,). """ import scipy.sparse.linalg as spla _useUmfpack = spla.dsolve.linsolve.useUmfpack spla.use_solver(useUmfpack=False) iA = spla.factorized(A) def solver(b, x0=None): return iA(b) spla.use_solver(useUmfpack=_useUmfpack) return solver,
def Modif_Ytrans(): global Ytrans, Ytrans_mod, N, Buses_type, K, slack, solve, branches_buses, list_gen Ytrans_mod = np.zeros((2*N+1,2*N+1),dtype=float) for i in range(N): if Buses_type[i]=='Slack': Ytrans_mod[2*i][2*i]=1 Ytrans_mod[2*i + 1][2*i + 1]=1 elif Buses_type[i]=='PQ': for j in branches_buses[i]: Ytrans_mod[2*i][2*j]=Ytrans[i][j].real Ytrans_mod[2*i][2*j + 1]=Ytrans[i][j].imag*-1 Ytrans_mod[2*i + 1][2*j]=Ytrans[i][j].imag Ytrans_mod[2*i + 1][2*j + 1]=Ytrans[i][j].real elif Buses_type[i]=='PVLIM' or Buses_type[i]=='PV': Ytrans_mod[2*i + 1][2*i]=1 for j in branches_buses[i]: Ytrans_mod[2*i][2*j]=Ytrans[i][j].real Ytrans_mod[2*i][2*j + 1]=Ytrans[i][j].imag*-1 # Last row for k in branches_buses[slack]: Ytrans_mod[2*N][2*k] = Ytrans[slack][k].real Ytrans_mod[2*N][2*k+1] = Ytrans[slack][k].imag*-1 # last Column for i in list_gen: Ytrans_mod[i*2][2*N]=-K[i] Ytrans_mod[2*N][2*N]=-K[slack] # Return a function for solving a sparse linear system, with Ytrans_mod pre-factorized. solve = factorized(csc_matrix(Ytrans_mod))
def make_prior_preconditioner_and_adjoint(M, check_adjoint_correctness=True): # Square root of covariance operator, C, and transpose # C = (Laplacian + I)^(-2) vt = TestFunction(M) ut = TrialFunction(M) C_form = inner(grad(vt), grad(ut)) * dx + vt * ut * dx C = fenics_to_scipy_matrix_conversion(assemble(C_form)) solve_C = spla.factorized(C) W_form = ut*vt*dx W = fenics_to_scipy_matrix_conversion(assemble(W_form)) apply_sqrtW = make_matrix_square_root_applier(W) def apply_sqrtC(f_vec): return solve_C(apply_sqrtW(f_vec)) def apply_sqrtC_T(u_vec): return apply_sqrtW(solve_C(u_vec)) if check_adjoint_correctness: xl = np.random.randn(M.dim()) xr = np.random.randn(M.dim()) smooth_vector_adjoint_err = np.dot(apply_sqrtC(xl).copy(), xr) - np.dot(xl, apply_sqrtC_T(xr).copy()) print('prior_adjoint_err=', smooth_vector_adjoint_err) return apply_sqrtC, apply_sqrtC_T
def comp_proj_lyap_res_norm(Z, amat=None, mmat=None, wmat=None, jmat=None, umat=None, vmat=None, Sinv=None): """compute the squared f norm of projected lyap residual res = Pt*[ Ft*ZZt*M + Mt*ZZt*M + W*Wt ]*P """ if Z.shape[1] >= Z.shape[0]: raise Warning('TODO: catch cases where Z has more cols than rows') if Sinv is None: Mlu = spsla.factorized(mmat) MinvJt = lau.app_luinv_to_spmat(Mlu, jmat.T) Sinv = np.linalg.inv(jmat * MinvJt) def _app_pt(Z, jmat, MinvJt, Sinv): return Z - jmat.T * np.dot(Sinv, np.dot(MinvJt.T, Z)) if umat is None and vmat is None: amattZ = amat.T * Z else: amattZ = amat.T * Z - lau.comp_uvz_spdns(vmat.T, umat.T, Z) PtFtZ = _app_pt(amattZ, jmat, MinvJt, Sinv) PtMtZ = _app_pt(mmat.T * Z, jmat, MinvJt, Sinv) PtW = _app_pt(wmat, jmat, MinvJt, Sinv) return lau.comp_sqfnrm_factrd_lyap_res(PtMtZ, PtFtZ, PtW)
def calculate_inf_sup_constant(gq, lq, bases): op = gq["op_fixed"] rhs = gq["rhs"] spaces = gq["spaces"] localizer = gq["localizer"] operator_reductor = LRBOperatorProjection(op, rhs, localizer, spaces, bases, spaces, bases) A = operator_reductor.get_reduced_operator().matrix H1 = gq["k_product"] operator_reductor = LRBOperatorProjection(H1, rhs, localizer, spaces, bases, spaces, bases) X = operator_reductor.get_reduced_operator().matrix Y = operator_reductor.get_reduced_operator().matrix Yinv = sp.factorized(Y.astype(complex)) def mv(v): return A.H.dot(Yinv(A.dot(v))) M1 = LinearOperator(A.shape, matvec=mv) eigvals = sp.eigs(M1, M=X, which='SM', tol=1e-4)[0] eigvals = np.sqrt(np.abs(eigvals)) eigvals.sort() result = eigvals[0] gq["inf_sup_constant"] = result print("calculated_inf_sup_constant: ", result) return result
def _lufactorized(A): r"""Return a function for solving a sparse linear system (LU decomposition). Parameters ---------- A : array Matrix A represented as an (m x n) array. Returns ------- callable Function to solve linear system with input matrix (n x 1). Notes ----- LU decomposition factors a matrix as the product of a lower triangular and an upper triangular matrix L and U. .. math:: \mathbf{A} = \mathbf{L} \mathbf{U} Examples -------- >>> fn = _lufactorized(array([[3, 2, -1], [2, -2, 4], [-1, 0.5, -1]])) >>> fn(array([1, -2, 0])) array([ 1., -2., -2.]) """ return factorized(A)
def compute_cycle_currents(r_mat, v_vec, cyclebasis): # special case for no cycles (which otherwise makes a singular matrix) if len(cyclebasis) == 0: return np.array([], dtype=v_vec.dtype) solver = spla.factorized(r_mat.tocsc()) return solver(v_vec).reshape([len(cyclebasis)])
def comp_proj_lyap_res_norm(Z, amat=None, mmat=None, wmat=None, jmat=None, umat=None, vmat=None, Sinv=None): """compute the squared f norm of projected lyap residual res = Pt*[ Ft*ZZt*M + Mt*ZZt*M + W*Wt ]*P """ if Z.shape[1] >= Z.shape[0]: raise Warning('TODO: catch cases where Z has more cols than rows') if Sinv is None: Mlu = spsla.factorized(mmat) MinvJt = lau.app_luinv_to_spmat(Mlu, jmat.T) Sinv = np.linalg.inv(jmat * MinvJt) def _app_pt(Z, jmat, MinvJt, Sinv): return Z - jmat.T * np.dot(Sinv, np.dot(MinvJt.T, Z)) if umat is None and vmat is None: amattZ = amat.T * Z else: amattZ = amat.T*Z - lau.comp_uvz_spdns(vmat.T, umat.T, Z) PtFtZ = _app_pt(amattZ, jmat, MinvJt, Sinv) PtMtZ = _app_pt(mmat.T * Z, jmat, MinvJt, Sinv) PtW = _app_pt(wmat, jmat, MinvJt, Sinv) return lau.comp_sqfnrm_factrd_lyap_res(PtMtZ, PtFtZ, PtW)
def factorize(self): # function to solve Cx = b, using cyclic reduction if len(self.Dinv) != 0: print("the matrix is already factorized") elif self.nblocks == 1: # if we are in a leaf, i.e. we are dealing with a dense matrix self.Dinv.append(la.inv(self.D[0].toarray())) else: # defining the indices IdxO = np.arange(0, self.nblocks, 2) IdxE = np.arange(1, self.nblocks, 2) # we start inverting the diagonal blocks Dinv = [] for ii in range(len(IdxO)): Dinv.append(spla.factorized(self.D[IdxO[ii]])) E, D, F = [], [], [] for ii in range(len(IdxE)): jj = IdxE[ii] Dlocal = np.zeros(self.D[jj].shape) Dlocal += self.D[jj] if jj > 0: # this should never be false, but just in case # update the diagonal Dlocal -= self.E[jj].dot(Dinv[ii](self.F[jj - 1].toarray())) if jj < self.nblocks - 1: # this can be true # update the diagonal Dlocal -= self.F[jj].dot(Dinv[ii + 1](self.E[jj + 1].toarray())) # now treating the off-diagonal blocks if jj > 0 and ii > 0: Elocal = -self.E[jj].dot(Dinv[ii]( self.E[jj - 1].toarray())) else: Elocal = np.zeros((self.n, self.n)) if jj < self.nblocks - 1 and ii < len(IdxE) - 1: Flocal = -self.F[jj].dot(Dinv[ii + 1]( self.F[jj + 1].toarray())) else: Flocal = np.zeros((self.n, self.n)) E.append(Elocal) D.append(Dlocal) F.append(Flocal) # defining the local inverses self.Dinv = Dinv # building the matrix for the resulting problem self.C = CyclicMatrix(self.n, len(IdxE), E, D, F) #factorizing the new matrix self.C.factorize()
def __init__(self, M): """Initialize the linear operator :param M: The matrix to be factorized/solved. :type M: Sparse Matrix """ self.solve = sla.factorized(M) self.shape = M.shape
def S(u): """evaluate control-to-state mapping""" u_fe.vector()[:] = u A = assemble_csr(inner(u_fe*grad(w), grad(v))*dc(1) + inner(umin*grad(w), grad(v))*dx) AMinv = factorized(csc_matrix(M+sigma*dt*dt*A)) y = forward(A, AMinv) return y
def get_atmtlu(At, Mt, jmat, ms): """compute the LU of the projection matrix """ NP = jmat.shape[0] sysm = sps.vstack([sps.hstack([At + ms.conjugate() * Mt, -jmat.T]), sps.hstack([jmat, sps.csr_matrix((NP, NP))])], format='csc') return spsla.factorized(sysm)
def fwd_solve(self, ind): '''Does the clean solve for the given index. The factorization is not cached''' strm = time.time() self.gogo[ind] = lin.factorized(sparse.csc_matrix(self.nabla2+self.getk(ind)) ) print 'factor time = ' + repr(time.time()-strm) # self.gogo[ind] = superSolve.wrapCvxopt.staticSolver(self.nabla2+self.getk(ind)) strm = time.time() self.sol[ind] = self.gogo[ind](self.rhs.flatten()) print 'sol time ' + repr(ind) + ' time = ' + repr(time.time()-strm)
def factor(self, A): """Compute internal factorization of A.""" self.m, self.n = A.shape if self.use_sub_factor: self.sub_factor(A) else: self.A_factorized = spla.factorized(A)
def test_luinv_to_spmat_complex(self): """check the application of the inverse of a lu-factored matrix to a sparse mat""" alusolve = spsla.factorized(self.A) Z = sps.csr_matrix(self.U+1j*self.V.T) AinvZ = lau.app_luinv_to_spmat(alusolve, Z) self.assertTrue(np.allclose(Z.todense(), self.A * AinvZ))
def initOpt(self, uHat, D): self.rho = D['rho'] self.xi = D['xi'] self.uHat = uHat self.upperBound = D['uBound'] self.lmb = D['lmb'] self.obj = np.zeros(D['maxIter']) # add some local vars for ease self.s = self.fwd.getS() # 1j*self.muo*self.w self.A = self.fwd.nabla2+self.fwd.getk(0) ''' create some lists so that I can see how the algorithm progresses''' self.gap = list() self.objInt = list() self.pL = list() self.phaseList = list() self.rlist = list() self.us = np.zeros(self.fwd.N,dtype='complex128') # just to make life easier: self.ub = self.fwd.sol[0] # shouldn't need --> .flatten() self.pp = np.zeros(self.fwd.getXSize(),dtype='complex128') self.r = np.zeros(self.fwd.getXSize(),dtype='complex128') # primal self.rt = np.zeros(self.fwd.getXSize(),dtype='complex128') # twiddle self.rd = np.zeros(self.fwd.getXSize(), dtype='complex128') # dual self.z = np.zeros(2*self.fwd.getXSize(), dtype='complex128') #primal? self.zt = np.zeros(self.fwd.getXSize(), dtype='complex128') # twiddle self.zd = np.zeros(self.fwd.getXSize(), dtype='complex128') # dual # self.pp = sparse.spdiags(np.exp(1j*np.angle(self.fwd.x2u.T*self.ub)),0,self.fwd.getXSize(),self.fwd.getXSize()) self.fwd.setCTRX() ''' subtract out the background field ''' self.uHat = self.uHat - self.fwd.Ms*self.ub ''' create the system KKT matrix ''' uu = self.fwd.Ms.T*self.fwd.Ms + self.rho*(self.upperBound*self.fwd.x2u*self.fwd.x2u.T*self.upperBound) ur = -self.rho*self.upperBound*self.fwd.x2u ul = self.A.T.conj() rr = 2*self.rho*sparse.eye(self.fwd.getXSize(),self.fwd.getXSize()) rl = self.s.conj()*self.fwd.x2u.T ll = sparse.coo_matrix((self.fwd.N,self.fwd.N)) SM = spTools.vCat([spTools.hCat([uu,ur,ul]),\ spTools.hCat([ur.T.conj(), rr, rl]), \ spTools.hCat([ul.T.conj(), rl.T.conj(), ll])]) self.internalGo = lin.factorized(SM)
def getBinv(Bbus, bus): n = Bbus.shape[0] rhs = zeros(n-1) solve = factorized(Bbus[:-1,:-1]) Binv = {} # dictionary with a key per wind bus, value is column array for i in bus: if not 'avg' in bus[i]: continue # only compute column if wind bus rhs[i] = 1 Binv[i] = append(solve(rhs), 0) rhs[i] = 0 return Binv
def __inv_greens_matrix(self, E, H): zplus = complex(0.0, 1.0) * 10 ** (-12) # sig1 = np.zeros((H.Ny * Nx, H.Ny * Nx), dtype = complex) # sig2 = np.zeros((H.Ny * Nx, H.Ny * Nx), dtype = complex) # if self.bc == 'open': # sig1[0,0] = self.calculate_self_energy_for_1d(E, -0.05) # sig2[-1,-1] = self.calculate_self_energy_for_1d(E, 0.05) matrix = (E + zplus) * sparse.eye(H.Ntot, H.Ntot, k=0, dtype=complex) - H.mtot solver = linalg.factorized(matrix.tocsc()) return solver
def initialize_matrix(self): """Set up the state vector, matrix, and index variables Pre-factor the matrix for efficiency in the time loop """ n = self.nx * self.ny # keep only points where u is not 0 ukeep = self.msk.flatten() * (self.IE * self.msk.flatten()) # keep only points where v is not 0 vkeep = self.msk.flatten() * (self.IN * self.msk.flatten()) hkeep = self.msk.flatten() keep = np.hstack([ukeep, vkeep, hkeep]) ikeep = np.nonzero(keep)[0] self.ikeep = ikeep #self.sbig = self.s self.s = self.sbig[np.nonzero(keep)] # indices of ocean points in the 2-d fields self.ih = np.nonzero(hkeep) self.iu = np.nonzero(ukeep) self.iv = np.nonzero(vkeep) # indices of variables inside the big s vector self.iubig = np.nonzero(np.hstack([ukeep, np.zeros(vkeep.shape), np.zeros(hkeep.shape)])) self.ivbig = np.nonzero(np.hstack([np.zeros(ukeep.shape), vkeep, np.zeros(hkeep.shape)])) self.ihbig = np.nonzero(np.hstack([np.zeros(ukeep.shape), np.zeros(vkeep.shape), hkeep])) dt = 0.5 * self.dx / self.cg I = sparse.eye(3*n, 3*n).tocsc() A = I + (dt / 2) * self.L B = I - (dt / 2) * self.L A = A[ikeep, :] A = A[:, ikeep] # does this get used? B = B[ikeep, :] self.B = B[:, ikeep] self.dt = dt print 'Factoring the big matrix...', tic = time.time() self.solve = linalg.factorized(A) print 'Elapsed time: ', time.time() - tic self.h = np.zeros(self.msk.shape).flatten() self.u = np.zeros(self.msk.shape).flatten() self.v = np.zeros(self.msk.shape).flatten() self.V = self.v.reshape(self.msk.shape) self.U = self.u.reshape(self.msk.shape) self.Z = self.h.reshape(self.msk.shape)
def initOpt(self, uHat, D): self.rho = D['rho'] self.xi = D['xi'] self.uHat = uHat self.upperBound = D['uBound'] self.lmb = D['lmb'] self.obj = np.zeros(D['maxIter']) # add some local vars for ease self.s = self.fwd.getS() # 1j*self.muo*self.w self.A = self.fwd.nabla2+self.fwd.getk(0) # variables for the scattered fields self.us = np.zeros(self.fwd.N,dtype='complex128') self.uT = np.zeros(self.fwd.getXSize(),dtype='complex128') self.uD = np.zeros(self.fwd.getXSize(),dtype='complex128') # variables for the contrast source self.x = np.zeros(self.fwd.getXSize(),dtype='complex128') self.xT = np.zeros(self.fwd.getXSize(),dtype='complex128') self.xD = np.zeros(self.fwd.getXSize(),dtype='complex128') # variables for theta self.tT = np.zeros(self.fwd.nRx*self.fwd.nRy, dtype='complex128') self.tD = np.zeros(self.fwd.nRx*self.fwd.nRy, dtype='complex128') # just to make life easier: self.ub = self.fwd.sol[0] # shouldn't need --> .flatten() self.uHat = uHat - self.fwd.Ms*self.fwd.sol[0] # create some new operators for doing what is necessary for the # contrast X work self.fwd.setCTRX() # self.indefinite = projector() uu = self.fwd.Ms.T*self.fwd.Ms + self.fwd.Md.T*self.fwd.Md*self.rho ux = sparse.coo_matrix((self.fwd.N,self.fwd.getXSize())) ul = self.A.T.conj() xx = sparse.eye(self.fwd.getXSize(),self.fwd.getXSize())*self.rho xl = self.fwd.x2u.T ll = sparse.coo_matrix((self.fwd.N, self.fwd.N)) M = spt.vCat([spt.hCat([uu, ux, ul]), \ spt.hCat([ux.T, xx, xl]),\ spt.hCat([ul.T.conj(), xl.T.conj(), ll])]) print M.shape self.aux = lin.factorized(M)
def reNumber(): N = 2000 A = scipy.sparse.rand(N,N,0.2) + scipy.sparse.eye(N,N) b = np.random.randn(N) aLocal = A.tocoo() I = aLocal.row.tolist() J = aLocal.col.tolist() D = aLocal.data.tolist() print len(D) # print A.shape alltm = time.time() Fs = wrapCvxopt.createSymbolic(A) solA = wrapCvxopt.solveNumeric(A, b, Fs) # return A,Fs # print A.shape print 'symb and num ' + repr(time.time()-alltm) lnf = time.time() Q = lin.factorized(A) uSPS = Q(b) print 'umfpack + scipy ' + repr(time.time()-lnf) M = scipy.sparse.coo_matrix((np.random.randn(len(D)),(I,J))) numTim = time.time() solB = wrapCvxopt.solveNumeric(M, b, Fs) print Fs print 'num only ' + repr(time.time()-numTim) lnf = time.time() Q = lin.factorized(M) uSPS = Q(b) print 'umfpack + scipy ' + repr(time.time()-lnf)
def diff_tangent(self, dependees_diff_u): if hasattr(self, 'residual') and self.residual: resid_diff_u, = dependees_diff_u if resid_diff_u is 0: return 0 else: if hasattr(resid_diff_u, 'todense'): resid_diff_u = resid_diff_u.todense() resid_diff_u = np.array(resid_diff_u) # inverse of Jacobian matrix resid_diff_self = self.jacobian self_diff_resid = splinalg.factorized(resid_diff_self.tocsc()) self_diff_u = np.transpose([-self_diff_resid(b) \ for b in resid_diff_u.T]) return np.matrix(self_diff_u.reshape(resid_diff_u.shape)) else: return 0
def test_smw_formula_complex(self): """check the use of the smw formula for the inverse of A-UV""" # check the branch with direct solves apoi = self.A + 1j * self.M AuvInvZ = lau.app_smw_inv(apoi, umat=self.U, vmat=self.V, rhsa=self.Z, Sinv=None) AAinvZ = apoi * AuvInvZ - np.dot(self.U, np.dot(self.V, AuvInvZ)) self.assertTrue(np.allclose(AAinvZ, self.Z)) # check the branch where A comes as LU alusolve = spsla.factorized(apoi) AuvInvZ = lau.app_smw_inv(alusolve, umat=self.U, vmat=self.V, rhsa=self.Z, Sinv=None) AAinvZ = apoi * AuvInvZ - np.dot(self.U, np.dot(self.V, AuvInvZ)) self.assertTrue(np.allclose(AAinvZ, self.Z))
def test_smw_formula_spv(self): """check the use of the smw formula with sparse v for the inverse of A-UV with v sparse""" # check the branch with direct solves AuvInvZ = lau.app_smw_inv(self.A, umat=self.U, vmat=self.Vsp, rhsa=self.Z, Sinv=None) AAinvZ = self.A * AuvInvZ - np.dot(self.U, self.Vsp * AuvInvZ) self.assertTrue(np.allclose(AAinvZ, self.Z)) # check the branch where A comes as LU alusolve = spsla.factorized(self.A) AuvInvZ = lau.app_smw_inv(alusolve, umat=self.U, vmat=self.Vsp, rhsa=self.Z, Sinv=None) AAinvZ = self.A * AuvInvZ - np.dot(self.U, self.Vsp * AuvInvZ) self.assertTrue(np.allclose(AAinvZ, self.Z))
def apply_massinv(M, rhsa, output=None): """ Apply the inverse of mass or any other spd matrix to a rhs array TODO: by now just a wrapper for spsla.spsolve change e.g. to CG Parameters ---------- M : (N,N) sparse matrix symmetric strictly positive definite rhsa : (N,K) ndarray array or sparse matrix array the inverse of M is to be applied to output : string, optional set to 'sparse' if rhsa has many zero columns to get the output as a sparse matrix Returns ------- , : (N,K) ndarray or sparse matrix the inverse of `M` applied to `rhsa` """ if output == 'sparse': colinds = rhsa.tocsr().indices colinds = np.unique(colinds) rhsa_cpy = rhsa.tolil() for col in colinds: rhsa_cpy[:, col] = np.atleast_2d(spsla.spsolve(M, rhsa_cpy[:, col])).T return rhsa_cpy else: mlusolve = spsla.factorized(M.tocsc()) try: mirhs = np.copy(rhsa.todense()) except AttributeError: mirhs = np.copy(rhsa) for ccol in range(mirhs.shape[1]): mirhs[:, ccol] = mlusolve(mirhs[:, ccol]) return mirhs
def time_integrate(operators, forcing, coeffs, times, initial, constant_load=False, solver='trapezoid'): """Integrate a linear convection-diffusion problem in time. Arguments: - `operators`: an instance of Operators1D. - `forcing`: forcing function, capable of taking numpy arrays as input: see the `get_load_vector` of Operators1D. - `coeffs`: coefficients for the linear problem. Should be a dictionary with keys 'diffusion' and 'convection'. - `times`: time indices. - `initial`: Initial value of solution. - `constant_load`: truth-value of whether or not the load vector varies in time. Defaults to False. - `solver`: time integrator to use. Defaults to 'trapezoid'. Returns: An instance of ArchiveDictionary. """ time_steps = times[1:] - times[:-1] if np.linalg.norm(time_steps - time_steps.mean()) > 10e-12: raise NotImplementedError("Unequal time stepping not available") timestep = times[1] - times[0] archive = ad.ArchiveDictionary() archive[times[0]] = initial if solver == 'trapezoid': operator_lhs = operators.mass + timestep/2.0*( coeffs['diffusion']*operators.stiffness + coeffs['convection']*operators.convection) if constant_load: load = operators.get_load_vector(0.0, forcing) else: load = None op.set_boundary_condition_rows(operator_lhs, value=1.0) factorized = splg.factorized(operator_lhs.tocsc()) for index, time in enumerate(times[1:], start=1): archive[time] = trapezoid_step(operators, forcing, coeffs, factorized, archive[times[index - 1]], time, timestep, constant_load=constant_load, load=load) else: raise NotImplementedError return archive
def diff_recurse(self, u): if u is self or hasattr(self, '_self_diff_u') or self.residual is None: return IntermediateState.diff_recurse(self, u) resid_diff_u = self.residual.diff_recurse(u) if resid_diff_u is 0: self_diff_u = 0 else: if hasattr(resid_diff_u, 'todense'): resid_diff_u = resid_diff_u.todense() resid_diff_u = np.array(resid_diff_u) # inverse of Jacobian matrix resid_diff_self = self.jacobian self_diff_resid = splinalg.factorized(resid_diff_self.tocsc()) self_diff_u = np.transpose([-self_diff_resid(b) \ for b in resid_diff_u.T]) self_diff_u = np.matrix(self_diff_u.reshape(resid_diff_u.shape)) self.self_diff_u = self_diff_u return self_diff_u
def initOpt(self,uHat, D): ''' prepare for upcoming iterations ''' self.rho = D['rho'] self.xi = D['xi'] self.uHat = uHat self.lmb = D['lmb'] self.uBound = D['uBound'] self.F = np.zeros(self.fwd.N,dtype='complex128') self.E = np.zeros(self.fwd.N,dtype='complex128') self.us = np.zeros(self.fwd.N,dtype='complex128') self.v = np.zeros(self.fwd.N,dtype='complex128') self.ub = self.fwd.sol[0] # -- update sol should be flat self.obj = np.zeros(D['maxIter']) # the update for the first step can be precomputed self.A = self.fwd.nabla2+self.fwd.getk(0) self.s = self.fwd.getS() # print self.xi self.Q = sparse.vstack([self.A, -self.xi*sparse.eye(self.fwd.N,self.fwd.N)]) self.Moo = self.rho*(self.Q.conj().T*self.Q) + self.fwd.Ms.T*self.fwd.Ms self.M = lin.factorized(self.Moo.tocsc())
def diff_adjoint(self, f_diff_dependers): f_diff_self = 0 iter_f_diff_dependers = iter(f_diff_dependers) if hasattr(self, 'solution') and self.solution(): f_diff_soln = next(iter_f_diff_dependers) if f_diff_soln is not 0: if hasattr(f_diff_soln, 'todense'): f_diff_soln = f_diff_soln.todense() f_diff_soln = np.array(f_diff_soln) # inverse of Jacobian matrix self_diff_soln = self.solution().jacobian.T soln_diff_self = splinalg.factorized(self_diff_soln.tocsc()) f_diff_self = np.array([-soln_diff_self(b) \ for b in f_diff_soln]) f_diff_self = np.matrix(f_diff_self.reshape(f_diff_soln.shape)) f_diff_self_1 = IntermediateState.diff_adjoint(self, iter_f_diff_dependers) return _add_ops(f_diff_self, f_diff_self_1)
def backward_iteration(A, mu, x0, tol=1e-15, maxiter=100): r"""Find eigenvector to approximate eigenvalue via backward iteration. Parameters ---------- A : (N, N) scipy.sparse matrix Matrix for which eigenvector is desired mu : float Approximate eigenvalue for desired eigenvector x0 : (N, ) ndarray Initial guess for eigenvector tol : float Tolerace parameter for termination of iteration Returns ------- x : (N, ) ndarray Eigenvector to approximate eigenvalue mu """ T = A - mu * eye(A.shape[0], A.shape[0]) T = T.tocsc() """Prefactor T and return a function for solution""" solve = factorized(T) """Starting iterate with ||y_0||=1""" r0 = 1.0 / np.linalg.norm(x0) y0 = x0 * r0 """Local variables for inverse iteration""" y = 1.0 * y0 r = 1.0 * r0 N = 0 for i in range(maxiter): x = solve(y) r = 1.0 / np.linalg.norm(x) y = x * r if r <= tol: return y msg = "Failed to converge after %d iterations, residuum is %e" % (maxiter, r) raise RuntimeError(msg)
def __init__(self,a=0,b=1,N=100): """Parameters are for spatial discretization (method of lines)""" self.N = N self.a = a self.b = b h = double(b-a)/(N+1) self.h = h # Function handles self.u_handle = lambda x: x*sin(pi*x) self.f_handle = lambda x: x*sin(pi*x)#exp(-t)*((pi**2-1)*x*sin(pi*x) - 2*pi*cos(pi*x)) #self.f_handle = lambda x: x#(x*sin(pi*x))**2 # Mass matrix d = h/6*ones(N+1) self.M = sp.spdiags([d,4*d,d],[-1,0,1],N,N).tocsc() # store LU factors to speed up solving self.M_LUsolve = sl.factorized(self.M) # Stiffness matrix d = ones(N+1)/h self.A = sp.spdiags([-d,2*d,-d],[-1,0,1],N,N).tocsc() # store domain self.xvals = a+h*r_[1:N+1] self.xvals_full = a+h*r_[0:N+2] # shape functions shap_LFE = lambda x: (x<0)*(x+1.) + (x>=0)*(1.-x) ## quadrature weights and nodes (overkill quadrature!): self.quad_x,self.quad_w = gaussNodes(1000) self.shap = shap_LFE(self.quad_x) # precompute shape functions # Load Vector self.F = zeros(self.N) for i in range(self.N): xi = self.a+h*(i+1) fvals = self.f_handle(h*self.quad_x+xi) self.F[i] = h*sum(self.quad_w*self.shap*fvals) # store standard initial values self.init1 = self.xvals*sin(pi*self.xvals) self.sol1 = HEsol
def prepProjector(self): ''' create a projection function, stored inside, that does the u,x projection step''' n = self.fwd.N m = self.fwd.getXSize() uu = self.fwd.Ms.T*self.fwd.Ms + self.xi*sparse.eye(n,n) ux = sparse.coo_matrix((n,m),dtype='complex128') ul = self.A.T.conj() xu = sparse.coo_matrix((m,n),dtype='complex128') xx = self.rho*sparse.eye(m,m,dtype='complex128') xl = self.fwd.x2u.T.conj() lu = self.A lx = self.fwd.x2u ll = sparse.coo_matrix((n,n),dtype='complex128') M = spt.vCat([spt.hCat([uu,ux,ul]),\ spt.hCat([xu,xx,xl]),\ spt.hCat([lu,lx,ll])]) self.projector = lin.factorized(M.tocsc())
def adjoint_recurse(self, f): if f is self or hasattr(self, '_f_diff_self') or \ self.solution() is None: return IntermediateState.adjoint_recurse(self, f) f_diff_soln = self.solution().adjoint_recurse(f) if f_diff_soln is 0: return IntermediateState.adjoint_recurse(self, f) else: if hasattr(f_diff_soln, 'todense'): f_diff_soln = f_diff_soln.todense() f_diff_soln = np.array(f_diff_soln) # inverse of Jacobian matrix self_diff_soln = self.solution().jacobian.T soln_diff_self = splinalg.factorized(self_diff_soln.tocsc()) f_diff_self = np.array([-soln_diff_self(b) for b in f_diff_soln]) f_diff_self = np.matrix(f_diff_self.reshape(f_diff_soln.shape)) f_diff_self_0 = IntermediateState.adjoint_recurse(self, f) f_diff_self = _add_ops(f_diff_self, f_diff_self_0) self.f_diff_self = f_diff_self return f_diff_self