def prob6(N=10): """Time regular and sparse linear system solvers. Plot the system size versus the execution times. As always, use log scales where appropriate. """ domain = 2**np.arange(2,N+1) solve, spsolve = [], [] for n in domain: A = prob5(n).tocsr() b = np.random.random(n) start = time() spla.spsolve(A, b) spsolve.append(time()-start) A = A.toarray() start = time() la.solve(A, b) solve.append(time()-start) plt.subplot(121) plt.plot(domain, spsolve, '.-', lw=2, label="spla.spsolve()") plt.plot(domain, solve, '.-', lw=2, label="la.solve()") plt.xlabel("n"); plt.ylabel("Seconds") plt.legend(loc="upper left") plt.subplot(122) plt.loglog(domain, spsolve, '.-', basex=2, basey=2, lw=2) plt.loglog(domain, solve, '.-', basex=2, basey=2, lw=2) plt.xlabel("n") plt.suptitle("Problem 6 Solution") plt.show()
def mode_solver(mode, solver_data, shift, w): #safeguard stratagy with positive shifts: if shift.real > 0: shift = -shift.real + 1j * shift.imag #safeguard strategy with complex shifts: if math.fabs(shift.imag) < 1e-10 * math.fabs(shift.real) and la.norm(w.imag) < 1e-10 * la.norm(w): shift, w = shift.real, w.real time_count_start(solver_data['solver_timing']) if (mode == 'pyamg' or mode == 'pyamgE'): #and not np.any(solver_data['is_solver_direct']): #print 'Try pyamg' amg_hierarchy, orig_hierarchy = solver_data['amg_hierarchy'], solver_data['orig_hierarchy'] pyamg_solver_shifting(amg_hierarchy, shift, orig_hierarchy) v = amg_hierarchy.solve(w, cycle = 'W', accel = 'gmres', tol = solver_data['solver_tol'], maxiter = 300).reshape(-1, 1) a, id_n = solver_data['a'], solver_data['id_n'] if la.norm(a.dot(v) + shift * v - w) > solver_data['solver_tol'] * la.norm(w) * 1e5: print 'Fail, direct solver is used.', shift, la.norm(a.dot(v) + shift * v - w) v = sla.spsolve(a + shift * id_n, w).reshape(-1, 1) solver_data['is_solver_direct'].append(True) else: solver_data['is_solver_direct'].append(False) elif mode == 'splu': v = solver_data['lu'].solve(w).reshape(-1, 1) solver_data['is_solver_direct'].append(False) else: a, id_n = solver_data['a'], solver_data['id_n'] v = sla.spsolve(a + shift * id_n, w).reshape(-1, 1) solver_data['is_solver_direct'].append(True) time_count_finish(solver_data['solver_timing']) return v
def solve(a, y, negative=True): """ A wrapper for solving linear system 'ax = y' using: 1) np.linalg.solve (if scipy is not available) 2) cholesky decompose (if scipy is available and a is not sparse) 3) spsolve (if scipy is available a is sparse) If scipy is available and matrix a is not sparse and is not positive definite, LinAlgError will be thrown :param a : 'a' :param y : 'y' :param negative : If True, we'll solve '-ax = y' instead :return : 'x' """ if scipy_flag: if issparse(a): if negative: return sparse_lin.spsolve(-a, y) return sparse_lin.spsolve(a, y) l = linalg.cholesky(a, lower=True) if negative: z = linalg.solve_triangular(-l, y, lower=True) else: z = linalg.solve_triangular(l, y, lower=True) return linalg.solve_triangular(l.T, z) if negative: return np.linalg.solve(-a, y) return np.linalg.solve(a, y)
def ssor(A, b, x0=None, w=1., maxiter=200, tol=1E-6): '''For symmetric matrices combine forward and backward SOR.''' assert is_symmetric(A, tol=1E-6) L, D, U = tril(A, k=-1), diags(A.diagonal(), 0), triu(A, k=1) # Forward MF = L + D/w NF = (1/w - 1)*D - U # Backward MB = U + D/w NB = (1/w - 1)*D - L # Start from 0 initial guess if x0 is None: x0 = np.zeros(A.shape[1]) r = b - A.dot(x0) residuals = [np.linalg.norm(r)] count = 0 while residuals[-1] > tol and count < maxiter: # Update x0 = spsolve(MF, NF.dot(x0) + b) x0 = spsolve(MB, NB.dot(x0) + b) # Error r = b - A.dot(x0) residuals.append(np.linalg.norm(r)) # Count count += 1 converged = residuals[-1] < tol n_iters = len(residuals) - 1 data = {'status': converged, 'iter count': n_iters, 'residuals': residuals} return x0, data
def _pade(A, m): n = np.shape(A)[0] c = _padecoeff(m) if m != 13: apows = [[] for jj in range(int(np.ceil((m + 1) / 2)))] apows[0] = sp.eye(n, n, format='csc') apows[1] = A * A for jj in range(2, int(np.ceil((m + 1) / 2))): apows[jj] = apows[jj - 1] * apows[1] U = sp.lil_matrix((n, n)).tocsc() V = sp.lil_matrix((n, n)).tocsc() for jj in range(m, 0, -2): U = U + c[jj] * apows[jj // 2] U = A * U for jj in range(m - 1, -1, -2): V = V + c[jj] * apows[(jj + 1) // 2] F = spla.spsolve((-U + V), (U + V)) return F.tocsr() elif m == 13: A2 = A * A A4 = A2 * A2 A6 = A2 * A4 U = A * (A6 * (c[13] * A6 + c[11] * A4 + c[9] * A2) + c[7] * A6 + c[5] * A4 + c[3] * A2 + c[1] * sp.eye(n, n).tocsc()) V = A6 * (c[12] * A6 + c[10] * A4 + c[8] * A2) + c[6] * A6 + c[4] * \ A4 + c[2] * A2 + c[0] * sp.eye(n, n).tocsc() F = spla.spsolve((-U + V), (U + V)) return F.tocsr()
def sparse_power_iteration(P, x, tol=10e-16, maxiter=200): """Preconditioned power iteration for a sparse stochastic matrix Parameters --------------- P : array, shape (n, n), sparse transition matrix of a Markov Chain x : array, shape (n, ) On entry, the initial guess. On exit, the final solution. """ t = 0 eps = tol + 1 n = P.shape[0] # ILU factorization LU = ilu0_factor(P) L = sparse.tril(LU) U = sparse.triu(LU) # New matrix Q Q = P.copy() Q.setdiag(1 - Q.diagonal()) Q *= -1 Q = Q.T info = -1 t = -1 for t in range(maxiter): ## dot() is matrix multiplication dx = spla.spsolve(U, spla.spsolve(L, Q.matvec(x))) x -= dx relres = tvnorm(dx) if relres < tol: info = 0 break t += 1 return (info, t, relres)
def scoreBoth(s,lap,pts,lap_t,pst_t,wt): try: f = lin.spsolve(lap, pts) h = lin.spsolve(lap_t, pst_t) except: # a singular matrix ... must solve each vector separately vecs = pts.shape[1] vlen = pts.shape[0] #print(vecs) fsolns = [] hsolns = [] for i in range(vecs): pts2 = pts[:,i].todense() pst_t2 = pst_t[:,i].todense() f1 = lin.bicgstab(lap, pts2)[0] h1 = lin.bicgstab(lap_t, pst_t2)[0] fsolns.append(f1) hsolns.append(h1) f = np.matrix(fsolns) h = np.matrix(hsolns) f = f.transpose() h = h.transpose() if type(f) == type(np.array([])): # came back as an array fh = f+h score = fh.sum() touch = (fh > s["tx"]).sum() else: # came back as a sparse matrix fsum = np.array(f.sum(1)).flatten() hsum = np.array(h.sum(1)).flatten() fh = fsum + hsum touch = sum(fh > s["tx"]) # best score; best touch # return((touch+wt, touch))
def func_energy(E, tt, U_bias, A, spB_s, spB_d): eta = globvars.eta Nx = globvars.Nx Vd = Vdc.value Temp = Te fermi_flag = fermiflag1.value ee = E ep = ee+eta ck = 1-((ep-U_bias[0])/(2.0*tt)) con_s = -tt*np.exp(1j*np.arccos(ck)) ck = 1-((ep-U_bias[Nx-1])/(2*tt)) con_d = -tt*np.exp(1j*np.arccos(ck)) U_eff = U_bias U_eff = U_eff + 0j U_eff[0] = U_bias[0]+con_s U_eff[Nx-1] = U_bias[Nx-1]+con_d G_inv = (ep*np.eye(Nx))-A-np.diag(U_eff) G_s = spsolve(sparse.csr_matrix(G_inv), spB_s) G_d = spsolve(sparse.csr_matrix(G_inv), spB_d) f_1 = fermi(((-Vs-ee)/(k_B*Temp/q)), fermi_flag, -1.0/2.0) f_2 = fermi(((-Vd-ee)/(k_B*Temp/q)), fermi_flag, -1.0/2.0) N_den = -abs(G_s)**2*np.imag(con_s)*2.0*f_1-abs(G_d)**2*np.imag(con_d)*2.0*f_2 return N_den
def compute_time_step(self, P_n): """ Computes a single time-step solution for the choice of solver method given in the input deck (implicit, explicit, mixed) """ #Pointer reassignment for convenience method = self.solver_method dt = self.time_step theta = self.solver_theta T = self.T B = self.B Q = self.Q #If mixed, or explicit are specified, otherwise default is implicit #therefore it's not actually required to be placed in the input deck if method == 'mixed': A = ((1.0 - theta) * T + B / dt) b = (B / dt - theta * T).dot(P_n) + Q P_np1 = spsolve(A, b) elif method == 'explicit': P_np1 = P_n + 1 / B * dt * (Q - T.dot(P_n)) else: A = T + B / dt b = (B / dt).dot(P_n) + Q P_np1 = spsolve(A, b) #Return solution vector from a single time-step return P_np1
def FlattenMesh( vertex, faces ): """ Flattens a mesh (with one hole) by mapping the edge to a unit circle vertex 3xN numpy.array: vertices faces 3xM numpy.array: faces Return the vertices Nx2 numpy.array of the flattening (faces are the same). """ n = vertex.shape[1] L = ComputeLaplacian( vertex, faces ) boundary = np.array( GetSurfaceBoundary( faces ) ) p = boundary.size t = np.linspace(0, 2*np.pi, p+1, endpoint=False) x0 = np.cos(t); y0 = np.sin(t); L = L.tolil() L[boundary,:] = 0; for i in range(p): L[boundary[i],boundary[i]] = 1; Rx = np.zeros(n); Rx[boundary] = x0; Ry = np.zeros(n); Ry[boundary] = y0; L = L.tocsr() result = np.zeros( (Rx.size, 2) ) result[:,0] = linalg_sp.spsolve(L, Rx); #x result[:,1] = linalg_sp.spsolve(L, Ry); #y return result
def solve(self, b, x, tol=1e-8, maxiter=None, trans=False): # cannot solve rectangular system assert self.square, "System is not square!" # make sure the matrix is sparse CSR assert self.finalized, "Matrix assembly not finalized!" # if this is a serial solve, just use standard sparse solvers if self.comm_size == 1: if not trans: x.data = la.spsolve(self.data, b.data) else: x.data = la.spsolve(self.data.T, b.data) return 1 else: # construct different matvecs depending on the system we're solving if not trans: def matvec(u, v): self.product(u, v, trans=False) else: def matvec(u, v): self.product(u, v, trans=True) # solve the system return bicgstab( matvec, b, x, self.precond, tol, maxiter, rank=self.rank)
def main(): print "Solve small matrix..." R = array([0, 0, 1, 1, 1, 2, 2]) C = array([0, 1, 0, 1, 2, 1, 2]) V = array([4.0, -1.0, -1.0, 4.0, -1.0, -1.0, 4.0]) b = array([3.0, 2.0, 3.0]) A = coo_matrix((V, (R, C)), shape=(3, 3)) # convert to csr format for efficiency x = spsolve(A.tocsr(), b) print "x = ", x print "Solve psd matrix..." # skip the first row (n, nnz) A = numpy.genfromtxt('../data/psd.txt', skiprows=1) b = numpy.genfromtxt('../data/b.txt') coo = coo_matrix((A[:, 2], (A[:, 0], A[:, 1]))) x = spsolve(coo.tocsr(), b) print 'x = ', x print "Solve big matrix..." A = numpy.genfromtxt('../data/mat_helmholtz.txt', skiprows=1) coo = coo_matrix((A[:, 2], (A[:, 0], A[:, 1]))) n = coo.shape[0] b = numpy.ones(n) x = spsolve(coo.tocsr(), b) print 'x = ', x
def updateIntEfrom(self): if self.type_connection=='YgYg': b=csr_matrix(-self.I_to - dot(self.Yss, self.E_to)) a=csr_matrix(self.Ysp) self.E_temp=spsolve(a,b) if self.type_connection!='YgYg': # for other type of connection Ysp is singular. therefore some tricks # have to be done. # for definition of Yss1 and Ysp1 see self.__init__() b=csr_matrix(-self.I_tod - dot(self.Yss1, self.E_to)) a=csr_matrix(self.Ysp1) #self.E_temp=spsolve(a,b) # this contains no zero sequence components #print"HHHHHHHHHHHHHHHHHHH" # below zero sequence component is added. This is ok for Yg Delta connection # what I do not understand at this moment is how about DD and DYg. ## if self.type_connection=='YgD': ## self.E_from0=sum(self.E_from)/3.0 ## #print "****************YgD********************" self.E_temp=spsolve(a,b) + self.E_from0 # this function should not update the from_bus.E because # in current update only current is updated. if self.type_connection=='UV': A=csr_matrix(self.Ysp[0:2,0:2]) b=-self.I_tod - dot(self.Yss1, self.E_to) B=csr_matrix(b[0:2]) ## print B.shape Epm=spsolve(A,B) self.E_temp=append(Epm,0) +self.E_from0 # what is the value of E_from[2] here? return self.E_temp# This is the intermediate primary voltage.
def direct(A, b, x=None, I=None, use_umfpack=True): """Solve system Ax=b with Dirichlet boundary conditions. Parameters ---------- A : scipy sparse matrix The system matrix. b : numpy array The right hand side. x : (OPTIONAL) numpy array For implementing inhomogeneous Dirichlet conditions. Must be of size b.shape[0]. I : (OPTIONAL) numpy array The interior nodes. A list of integers to x corresponding to interior nodes. """ if I is None: x = spl.spsolve(A, b, use_umfpack=use_umfpack) else: if x is None: x = np.zeros(A.shape[0]) x[I] = spl.spsolve(A[I].T[I].T, b[I], use_umfpack=use_umfpack) else: D = np.setdiff1d(np.arange(A.shape[0]), I) x[I] = spl.spsolve(A[I].T[I].T, b[I] - A[I].T[D].T.dot(x[D]), use_umfpack=use_umfpack) return x
def solveSq(gates, pads, weights, start, end, botL, topR): A, bx, by = getVars(gates, pads, weights, start, end, botL, topR) csrA = A.tocsr() x = spsolve(csrA, bx) y = spsolve(csrA, by) return x,y
def executeIgarashi(): global v2 b1 = igarashi.buildB1(pins, pinPoses, w, nEdges) v1 = spla.spsolve(sqA1, tA1 * b1) b2 = igarashi.buildB2(heVectors, heIndices, edges, pinPoses, w, G, v1) v2x = spla.spsolve(sqA2, tA2 * b2[:, 0]) v2y = spla.spsolve(sqA2, tA2 * b2[:, 1]) v2 = np.vstack((v2x, v2y)).T
def fit(self, A, u): n = A.shape[0] D = sparse.diags(np.asarray(A.sum(axis=1).T), [0]) L = D - A self.f = la.spsolve(L+self.alpha*sparse.identity(n), u) #self.f = la.spsolve(self.beta*L/(n**2)+self.alpha*sparse.identity(n), u) # <- this is the correct formula, self.f = la.spsolve(self.beta*L+self.alpha*sparse.identity(n), u) # but we use this one for convenience self.f = np.maximum(0.0, self.f) return self
def generate_matrix(gate,pad): C = {} b_x = {} b_y = {} for i in range(len(gate)): C[i] = {} for j in range(len(gate)): C[i][j] = 0 for i in range(len(gate)): for k in gate[i].net_connection: for j in range(i+1,len(gate)): if k in gate[j].net_connection: C[i][j] = C[i][j]+1 #if gate i connected to gate j more than once, will add the weight 1 C[j][i] = C[i][j] for t in range(len(pad)): if k in pad[t].net_connection: if i not in b_x: b_x[i] = pad[t].x b_y[i] = pad[t].y #print "in line 83", b_x[i],b_y[i] else: b_x[i] = b_x[i]+pad[t].x #if one gate connected to multiple pads, will calculate as w1x1+w2x2, now weight is 1. b_y[i] = b_y[i]+pad[t].y C[i][i] = C[i][i]+1 #if one gate connected to multiple pads, will calculate each weight sum w for i in range(len(gate)): C[i][i] = sum(C[i].values()) fp = open("data",'w') for i in C: for j in C[i]: if(C[i][j] != 0): if(i!=j): fp.write('%d %d %d\n' %(i,j,-C[i][j])) else: fp.write('%d %d %d\n' %(i,j,C[i][j])) fp.close() fp = open("b_x","w") for i in range(len(gate)): if i in b_x: fp.write('%.10f\n' %(b_x[i])) else: fp.write('%f\n' %(0.0)) fp.close() fp = open("b_y","w") for i in range(len(gate)): if i in b_y: fp.write('%.10f\n' %(b_y[i])) else: fp.write('%f\n' %(0.0)) fp.close() A = numpy.genfromtxt('data') b_x_array = numpy.genfromtxt('b_x') b_y_array = numpy.genfromtxt('b_y') coo = coo_matrix((A[:, 2], (A[:, 0], A[:, 1])),shape = (len(gate),len(gate))) x = spsolve(coo.tocsr(), b_x_array) y = spsolve(coo.tocsr(), b_y_array) return (x,y)
def check_input_opa(NU, femp=None): if femp is None: # from dolfin_navier_scipy.problem_setups import cyl_fems # femp = cyl_fems(2) from dolfin_navier_scipy.problem_setups import drivcav_fems femp = drivcav_fems(20) V = femp["V"] Q = femp["Q"] cdcoo = femp["cdcoo"] # get the system matrices stokesmats = dts.get_stokessysmats(V, Q) # check the B B1, Mu = cou.get_inp_opa(cdcoo=cdcoo, V=V, NU=NU, xcomp=0) B2, Mu = cou.get_inp_opa(cdcoo=cdcoo, V=V, NU=NU, xcomp=1) # get the rhs expression of Bu Bu1 = spsla.spsolve( stokesmats["M"], B1 * np.vstack([np.linspace(0, 1, NU).reshape((NU, 1)), np.linspace(0, 1, NU).reshape((NU, 1))]), ) Bu2 = spsla.spsolve( stokesmats["M"], B2 * np.vstack([np.linspace(0, 1, NU).reshape((NU, 1)), np.linspace(0, 1, NU).reshape((NU, 1))]), ) Bu3 = spsla.spsolve(stokesmats["M"], B1 * np.vstack([1 * np.ones((NU, 1)), 0.2 * np.ones((NU, 1))])) bu1 = dolfin.Function(V) bu1.vector().set_local(Bu1) bu1.vector()[2] = 1 # for scaling and illustration purposes bu2 = dolfin.Function(V) bu2.vector().set_local(Bu2) bu2.vector()[2] = 1 # for scaling and illustration purposes bu3 = dolfin.Function(V) bu3.vector().set_local(Bu3) bu3.vector()[2] = 1 # for scaling and illustration purposes plt.figure(11) dolfin.plot(bu1, title="plot of Bu - extending in x") plt.figure(12) dolfin.plot(bu2, title="plot of Bu - extending in y") plt.figure(13) dolfin.plot(bu3, title="plot of Bu - extending in y") # dolfin.plot(V.mesh()) dolfin.interactive() plt.show(block=False)
def TStar(self,g,out=None): g = g.core() if out is None: out = NumpyVector(g.shape) v = spsolve(self.system,self.B*g) self.assemble_Trhs(self.beta,self.u,v) w = spsolve(self.B,self.Trhs) return NumpyVector(w)
def time_solve(self, n, solver): if solver == 'dense': linalg.solve(self.P_dense, self.b) elif solver == 'cg': cg(self.P_sparse, self.b) elif solver == 'minres': minres(self.P_sparse, self.b) elif solver == 'spsolve': spsolve(self.P_sparse, self.b) else: raise ValueError('Unknown solver: %r' % solver)
def Solve_PDE(C, size): n=size Y1=np.zeros([n,n]) for j in range(n): C[0,j]=C[1,j] C[n-1,j]=C[n-2,j] for i in range(1,n-1): for j in range(1,n-1): Y1[i,j]=(C[i-1,j]-2*C[i,j]+C[i+1,j])*-b+C[i,j] for i in range(n): Y1[i,0]=Y1[i,1] Y1[i,n-1]=Y1[i,n-2] X1=np.zeros([n,n]) for i in range(0,n): X1[i,:] = spsolve(A,Y1[i,:]) for i in range(n): X1[i,0]=X1[i,1] X1[i,n-1]=X1[i,n-2] X2=np.zeros([n,n]) for i in range(1,n-1): for j in range(1,n-1): X2[i,j]=(X1[i,j-1]-2*X1[i,j]+X1[i,j+1])*-b+X1[i,j] for j in range(n): X2[0,j]=X2[1,j] X2[n-1,j]=X2[n-2,j] Y2=np.zeros([n,n]) for j in range(0,n): Y2[:,j] = spsolve(A,X2[:,j]) for i in range(n): Y2[i,0]=Y2[i,1] Y2[i,n-1]=Y2[i,n-2] for j in range(n): Y2[0,j]=Y2[1,j] Y2[n-1,j]=Y2[n-2,j] return Y2
def solve(self): self.u[0,:] = self.v A1 = self._getA(init=True) A = self._getA(init=False) b = self._rhs(1) self.u[1,1:self.nx-1] = linalg.spsolve(A1,b) for it in range(2,self.nt,1): b = self._rhs(it) self.u[it,1:self.nx-1] = linalg.spsolve(A,b) return self.u
def SolveMat(self, gates, pads): (R, C, V) = self.GetMatA(gates, pads) (bx, by) = self.GetVecb(gates, pads) print R print C print V print bx print by A = coo_matrix((V, (R, C)), shape=(len(bx), len(bx))) # convert to csr format for efficiency x = spsolve(A.tocsr(), bx) y = spsolve(A.tocsr(), by) return (list(x), list(y))
def updateForward(self): # 1. Calculate primary current injaction # update voltage at from_bus self.updateEfrom() self.E_from0=sum(self.E_from)/3.0 #self.I_from=conj(self.S_from/self.E_from) self.I_fromd=self.I_from.copy() self.I_fromd[2]=0 # 2. Calculate secondary voltage # 2.a. if Yps is invertible if self.type_connection=='YgYg': #b=csr_matrix(self.I_to-dot(self.Ysp,self.from_bus.E)) b=csr_matrix(self.I_from-dot(self.Ypp,self.from_bus.E)) #a=csr_matrix(self.Yss) a=csr_matrix(self.Yps) # This Yps is singular for other type of connection self.E_to=spsolve(a,b) # 2.b. if Yps is NOT invertibel i.e. singular if self.type_connection!='YgYg': # Calculate secondary voltage positive+negative segquence part b=csr_matrix( self.I_fromd -dot(self.Ypp2,self.E_from)) a=csr_matrix(self.Yps2) #self.E_to0=sum(self.to_bus.E)/3. self.E_to_temp=spsolve(a,b) # this contains NO zero sequence part # Calculate secondary voltage zero sequence part self.E_to0=0 # this is a potential error # a. when Yss is NOT singular ==> YgYg and DYg if self.type_connection=='DYg': #or self.type_connection=='YgYg': b=csr_matrix( -self.I_to -dot(self.Ysp,self.E_from)) a=csr_matrix(self.Yss) self.E_to_temp=spsolve(a,b) #self.E_to0=sum(self.E_to)/3.0 #this leads to nonconvergences #print '================Update Forwad', self.type_connection # in the rest of connection types, zero components of secondary # voltage depend on downstream network situation. In situation # where there is multigrounded system, it is NOT zero and therefore # this assuption is wrong. # It is unfortunate that this feature is not yet developed as it # is very situational. # however, in most of situation this assumption is correct. if self.type_connection=='YgD' or self.type_connection=='YD' : self.E_to0=sum(self.E_to)/3.0 ## print 'find me!' if self.type_connection=='UV': ## print 'UV Forward sweep' b=csr_matrix( self.I_fromd -dot(self.Ypp2,self.E_from)) a=csr_matrix(self.Yps2) self.E_to_temp=spsolve(a,b) self.E_to0=sum(self.E_to)/3 # Sum all sequences self.E_to=self.E_to_temp+self.E_to0
def test2(): n = 10 scale = 10 xy, triangles = planemesh.build(n, scale) halfedges = halfedge.build(triangles) heVectors = np.asarray([xy[he.ivertex, :] - xy[he.prev().ivertex, :] for he in halfedges]) pins = np.asarray([0, n]) #pinPoses = xy[pins, :] pinPoses = np.asarray(( (-scale, 0), (0, 0) )) w = 1000.0 nVertices = xy.shape[0] edges, heIndices = halfedge.toEdge(halfedges) nEdges = edges.shape[0] A1top, G = buildA1top(heVectors, halfedges, edges, heIndices, nVertices) A1bottom = buildA1bottom(pins, w, nVertices) b1 = buildB1(pins, pinPoses, w, nEdges) A1 = sp.vstack((A1top, A1bottom)) tA1 = A1.transpose() v1 = spla.spsolve(tA1 * A1, tA1 * b1) A2top = buildA2top(edges, nVertices) A2bottom = buildA2bottom(pins, w, nVertices) b2 = buildB2(heVectors, heIndices, edges, pinPoses, w, G, v1) A2 = sp.vstack((A2top, A2bottom)) tA2 = A2.transpose() v2x = spla.spsolve(tA2 * A2, tA2 * b2[:, 0]) v2y = spla.spsolve(tA2 * A2, tA2 * b2[:, 1]) v2 = np.vstack((v2x, v2y)).T if n == 1: answerA1top = np.asarray(( ( 0, 0, -0.25, 0.25, -0.25, -0.25, 0.5, 0), ( 0, 0, -0.25, -0.25, 0.25, -0.25, 0, 0.5), (-0.333, 0.333, 0.666, 0, 0, 0, -0.333, -0.333), (-0.333, -0.333, 0, 0.666, 0, 0, 0.333, -0.333), ( 0.5, 0, -0.5, -0.5, 0, 0, 0, 0.5), ( 0, 0.5, 0.5, -0.5, 0, 0, -0.5, 0), (-0.333, -0.333, 0, 0, 0.666, 0, -0.333, 0.333), ( 0.333, -0.333, 0, 0, 0, 0.666, -0.333, -0.333), ( 0, 0.5, 0, 0, -0.5, -0.5, 0.5, 0), ( -0.5, 0, 0, 0, 0.5, -0.5, 0, 0.5) )) print "Error of G : %e" % la.norm(A1top - answerA1top, np.Inf) #print "Full A1top : ", A1top.todense() v1 = v1.reshape(-1, 2) plt.figure() plt.gca().set_aspect('equal') plt.triplot(v2[:,0], v2[:,1], triangles) plt.show()
def aggregatorSemiParallel(self,S, comm): ''' Do the aggregation step in parallel whoop! ''' ''' oh this is going to get trickier when we return to 3d & multivariates''' n = S[0].fwd.getPSize() nX = S[0].fwd.getXSize() ''' matrix method, i.e. TM, TE3D req'd' ''' uL = sparse.lil_matrix((n,n),dtype='complex128') bL = np.zeros(n,dtype='complex128') for L in S: M = L.s*(sparse.spdiags(L.fwd.x2u.T*(L.ub+L.us),0,nX,nX))*self.fwd.p2x uL = uL + M.T.conj()*M bL = bL + M.T.conj()*(L.X + L.Z) U = sparse.lil_matrix((n,n),dtype='complex128') B = np.zeros(n,dtype='complex128') U = comm.allreduce(uL,U,op=MPI.SUM) B = comm.allreduce(bL,B,op=MPI.SUM) ''' interesting: += isn't implemented?''' U = U + sparse.spdiags((self.lmb/self.rho)*np.ones(n), 0, n, n) P = lin.spsolve(U,B) self.pL.append(lin.spsolve(uL,bL)) ''' matrix free method ''' # uL = np.zeros(n,dtype='complex128') # bL = np.zeros(n,dtype='complex128') # for L in S: # uL += self.s*self.fwd.Md*(self.us + self.ub) # bL += self.X + self.Z # U = np.zeros(n,dtype='complex128') # B = np.zeros(n,dtype='complex128') # # U = comm.allreduce(uL,U,op=MPI.SUM) # B = comm.allreduce(bL,B,op=MPI.SUM) # # num = self.rho*(U.real*B.real + U.imag*B.imag) # den = self.rho*(U.conj()*U) + self.lmb # # P = (num/den) # self.pL.append((uL.real*bL.real + uL.imag*bL.imag)/(uL.conj()*uL)) ''' finish off ''' P = P.real P = np.maximum(P,0) P = np.minimum(P,self.upperBound) return P
def PrecByB2(qqpq): qq = MLumpI*qqpq[:Nv,] p = qqpq[Nv:-(Np-1),] p = spsla.spsolve(B2Sme, p) p = MLump2*np.atleast_2d(p).T p = spsla.spsolve(B2Sme.T,p) p = np.atleast_2d(p).T q2 = qqpq[-(Np-1):,] q2 = spsla.spsolve(B2Sme,q2) q2 = np.atleast_2d(q2).T return np.vstack([np.vstack([qq, -p]), q2])
def solve_sym_gauss_seidel(A, b, x0=None, maxiter=100): N = len(b) L, D, U = lower_diag_upper(A) E = -L F = -U x = parse_initial_cond(x0, N) residual = 1 for _ in xrange(maxiter): x = spsolve(D - E, (b + F * x)) x = spsolve(D - F, (b + E * x)) residual = compute_normalized_linf_residual(A, x, b) return x, residual
def _solve_P_Q(U, V, structure=None): """ A helper function for expm_2009. Parameters ---------- U : ndarray Pade numerator. V : ndarray Pade denominator. structure : str, optional A string describing the structure of both matrices `U` and `V`. Only `upper_triangular` is currently supported. Notes ----- The `structure` argument is inspired by similar args for theano and cvxopt functions. """ P = U + V Q = -U + V if isspmatrix(U): return spsolve(Q, P) elif structure is None: return solve(Q, P) elif structure == UPPER_TRIANGULAR: return solve_triangular(Q, P) else: raise ValueError('unsupported matrix structure: ' + str(structure))
def ASD2(Ybus, S0, V0, I0, pv, pq, vd, tol, max_it=15, gamma=0.1): """ Alternate Search Directions Power Flow As defined in the paper: Unified formulation of a family of iterative solvers for power system analysis by Domenico Borzacchiello et. Al. Modifications: - Better reactive power computation :param Ybus: Admittance matrix :param S0: Power injections :param V0: Initial Voltage Vector :param I0: Current injections @V=1.0 p.u. :param pv: Array of PV bus indices :param pq: Array of PQ bus indices :param vd: Array of Slack bus indices :param tol: Tolerance :param max_it: Maximum number of iterations :return: V, converged, normF, Scalc, iterations, elapsed """ start = time.time() # initialize V = V0.copy() Vset_pv = np.abs(V0[pv]) Scalc = S0.copy() Scalc[pv] = Scalc[pv].real + 0j normF = 1e20 iterations = 0 converged = False n = len(V0) npq = len(pq) npv = len(pv) pqpv = np.r_[pq, pv] npqpv = len(pqpv) # kron Y11 = Ybus[pq, :][:, pq] Y12 = Ybus[pq, :][:, pv] Y21 = Ybus[pv, :][:, pq] Y22 = Ybus[pv, :][:, pv] # reduced system Yred = vstack_sp((hstack_sp((Y11, Y12)), hstack_sp((Y21, Y22)))) Sred = S0[pqpv] I0_red = I0[pqpv] Yslack = - Ybus[np.ix_(pqpv, vd)] # yes, it is the negative of this Vslack = V0[vd] # compute alpha Vabs = np.ones(npqpv) alpha = sp.diags(np.conj(Sred) / (Vabs * Vabs)) # compute Y-alpha Y_alpha = (Yred - alpha) # compute beta as a vector B = Y_alpha.diagonal() beta = diags(B) Y_beta = Yred - beta # get the first voltage approximation V0, or simply V(l Ivd = Yslack * Vslack # slack currents V_l = spsolve(Y_alpha, Ivd) # slack voltages influence # V_l = V0[pqpv] while not converged and iterations < max_it: iterations += 1 # Global step rhs_global = np.conj(Sred) / np.conj(V_l) - alpha * V_l + I0_red + Ivd V_l12 = spsolve(Y_alpha, rhs_global) # PV correction (using Lynn's formulation) V_pv = V_l12[npq:] V_l12[npq:] = V_pv * Vset_pv / np.abs(V_pv) V[pq] = V_l12[:npq] V[pv] = V_l12[npq:] Qpv = (V[pv] * np.conj((Ybus[pv, :] * V))).imag Sred[npq:] = Sred[npq:].real + 1j * gamma * Qpv # local step A = (Y_beta * V_l12 - I0_red - Ivd) / B Sigma = - np.conj(Sred) / (A * np.conj(A) * B) U = (-1 - np.sqrt(1 - 4 * (Sigma.imag * Sigma.imag + Sigma.real))) / 2.0 + 1j * Sigma.imag V_l = U * A # Assign the reduced solution V[pq] = V_l[:npq] V[pv] = V_l[npq:] # compute the calculated power injection and the error of the voltage solution Scalc = V * np.conj(Ybus * V - I0) mis = Scalc - S0 # complex power mismatch mismatch = np.r_[mis[pv].real, mis[pq].real, mis[pq].imag] # concatenate again normF = np.linalg.norm(mismatch, np.Inf) converged = normF < tol print(normF) end = time.time() elapsed = end - start return V, converged, normF, Scalc, iterations, elapsed
while (t_D[k] < numerical.PV_final): #non dimensional time marching P_old = np.copy(P) #Placeholdering the old array #Calculating the arrays Tw, To, T, d11, d12, d21, d22, D, G = myarrays(fluid,reservoir,petro,numerical,BC,P,Sw) #updating the wells well, Qw, Qo, Jw, Jo = updatewells(reservoir,fluid,numerical,petro,P,Sw,well) Q = (-d22 @ inv(d12)) @ Qw + Qo J = (-d22 @ inv(d12)) @ Jw + Jo if numerical.method == 'IMPES': IM = T + J + D #implicit part coefficient in Eq. 3.44 EX = D @ P_old + Q + G #explicit part or RHS of Eq. 3.44 P = np.transpose([spsolve(IM,EX)]) #solving IM*P = EX or Ax=B Sw = Sw + inv(d12) @ (-Tw @ P - d11 @ (P - P_old) + Qw) #explicit saturation k = k+1 P_plot[:,k] = P[:,0] Sw_plot[:,k]= np.array(Sw)[:,0] t[k]= t[k-1] + numerical.dt t_D[k]= well.constraint[0][0]*t[k-1]/(reservoir.L*reservoir.W*reservoir.h*reservoir.phi[0,0]) kblock = numerical.N-1 krw,kro = rel_perm(petro,Sw[kblock,0]) M = (kro*fluid.muw[kblock,0])/(krw*fluid.muo[kblock,0]) fw[k] = 1/(1+M) P_plot[np.argwhere(reservoir.permx < 0.01)] = np.nan
def LevenbergMarquardtPF(Ybus, Sbus, V0, Ibus, pv, pq, tol, max_it=50): """ Solves the power flow problem by the Levenberg-Marquardt power flow algorithm. It is usually better than Newton-Raphson, but it takes an order of magnitude more time to converge. Args: Ybus: Admittance matrix Sbus: Array of nodal power injections V0: Array of nodal voltages (initial solution) Ibus: Array of nodal current injections pv: Array with the indices of the PV buses pq: Array with the indices of the PQ buses tol: Tolerance max_it: Maximum number of iterations Returns: Voltage solution, converged?, error, calculated power injections @Author: Santiago Peñate Vera """ start = time.time() # initialize V = V0 Va = angle(V) Vm = abs(V) dVa = zeros_like(Va) dVm = zeros_like(Vm) # set up indexing for updating V pvpq = r_[pv, pq] npv = len(pv) npq = len(pq) if NUMBA_DETECTED: # generate lookup pvpq -> index pvpq (used in createJ) pvpq_lookup = zeros(max(Ybus.indices) + 1, dtype=int) pvpq_lookup[pvpq] = arange(len(pvpq)) # j1:j2 - V angle of pv buses j1 = 0 j2 = npv # j3:j4 - V angle of pq buses j3 = j2 j4 = j2 + npq # j5:j6 - V mag of pq buses j5 = j4 j6 = j4 + npq update_jacobian = True converged = False iter_ = 0 nu = 2.0 lbmda = 0 f_prev = 1e9 # very large number nn = 2 * npq + npv ii = np.linspace(0, nn-1, nn) Idn = sparse((np.ones(nn), (ii, ii)), shape=(nn, nn)) # csr_matrix identity # do Newton iterations while not converged and iter_ < max_it: # evaluate Jacobian if update_jacobian: if NUMBA_DETECTED: H = create_J_with_numba(Ybus, V, pvpq, pq, pvpq_lookup, npv, npq, Ibus=Ibus) else: H = Jacobian(Ybus, V, Ibus, pq, pvpq) # evaluate the solution error F(x0) Scalc = V * conj(Ybus * V - Ibus) mis = Scalc - Sbus # compute the mismatch dz = r_[mis[pv].real, mis[pq].real, mis[pq].imag] # mismatch in the Jacobian order # system matrix # H1 = H^t H1 = H.transpose() # H2 = H1·H H2 = H1.dot(H) # set first value of lmbda if iter_ == 0: lbmda = 1e-3 * H2.diagonal().max() # compute system matrix A = H^T·H - lambda·I A = H2 + lbmda * Idn # right hand side # H^t·dz rhs = H1.dot(dz) # Solve the increment dx = spsolve(A, rhs) # objective function to minimize f = 0.5 * dz.dot(dz) # decision function rho = (f_prev - f) / (0.5 * dx.dot(lbmda * dx + rhs)) # lambda update if rho > 0: update_jacobian = True lbmda *= max([1.0 / 3.0, 1 - (2 * rho - 1) ** 3]) nu = 2.0 # reassign the solution vector if npv: dVa[pv] = dx[j1:j2] if npq: dVa[pq] = dx[j3:j4] dVm[pq] = dx[j5:j6] Vm -= dVm Va -= dVa # update Vm and Va again in case we wrapped around with a negative Vm V = Vm * exp(1j * Va) Vm = abs(V) Va = angle(V) else: update_jacobian = False lbmda *= nu nu *= 2 # check convergence normF = np.linalg.norm(dx, np.Inf) converged = normF < tol f_prev = f # update iteration counter iter_ += 1 end = time.time() elapsed = end - start return V, converged, normF, Scalc, iter_, elapsed
def solve_hemholtz(f, boundary_func=lambda x,y: x*y, lap_f=lambda x: None, n=20,xint=(0,1), solver='spdiags', scheme='5-point', k=20): h = (xint[1]-xint[0])/float(n+1) if scheme == 'deferred': #Get the second-order approximation u_bar = np.zeros((n+2, n+2)) u_bar[1:-1,1:-1] = solve_hemholtz(f, boundary_func, lap_f, n, xint,k=k).reshape((n,n)) #Fill in the boundary data grid_1d = np.linspace(xint[0], xint[1], n+2) u_bar[0] = boundary_func(xint[0], grid_1d) u_bar[-1] = boundary_func(xint[1], grid_1d) u_bar[:,0] = boundary_func(grid_1d, xint[0]) u_bar[:,-1] = boundary_func(grid_1d, xint[1]) #Compute the xxyy derivative u_xx = (u_bar[:-2]+u_bar[2:]-2*u_bar[1:-1])/h**2 u_xxyy = (u_xx[:,2:]+u_xx[:,:-2]-2*u_xx[:,1:-1])/h**2 #First, construct the diagonals and the RHS #Here we assume that the domain is square b = np.zeros((n,n)) yvals = np.linspace(xint[0], xint[1], n+2)[1:-1] # print h, yvals[1]-yvals[0] for i in xrange(n): xval = yvals[i] b[i] = f(xval, yvals) if scheme == '9-point': b[i] += h**2/12. * (lap_f(xval, yvals) - k**2*f(xval, yvals)) elif scheme == 'deferred': b[i] += h**2/12. * (lap_f(xval, yvals) - k**2*f(xval, yvals) + k**4 * u_bar[i+1,1:-1] - 2*u_xxyy[i] ) if scheme == '5-point' or scheme == 'deferred': b *= h**2 else: b *= 6*h**2 # print b if scheme=='5-point' or scheme == 'deferred': diags = make_5_point_diags(n, h) diags[0] += h**2 * k**2 #Now we need to make use of the boundary conditions b[0] -= boundary_func(xint[0], yvals) b[-1] -= boundary_func(xint[1], yvals) b[:,0] -= boundary_func(yvals, xint[0]) b[:,-1] -= boundary_func(yvals, xint[1]) elif scheme=='9-point': diags = make_9_point_diags(n, h) diags[0] += 6 *((h*k)**2 - 1./12* (h*k)**4) #This is like the 5-point stencil b[0] -= 4*boundary_func(xint[0], yvals) b[-1] -= 4*boundary_func(xint[1], yvals) b[:,0] -= 4*boundary_func(yvals, xint[0]) b[:,-1] -= 4*boundary_func(yvals, xint[1]) #Here we handle the corners of the stencil vals = np.linspace(xint[0], xint[1], n+2) #Take care of effects to the top and bottom boundaries b[0] -= boundary_func(xint[0], vals[:-2]) + boundary_func(xint[0], vals[2:]) b[-1] -= boundary_func(xint[1], vals[:-2]) + boundary_func(xint[1], vals[2:]) #Handle the sides - be careful not to double count the corners b[1:,0] -= boundary_func(vals[1:-2], xint[0]) b[:-1,0] -= boundary_func(vals[2:-1], xint[0]) b[1:,-1] -= boundary_func(vals[1:-2], xint[1]) b[:-1,-1] -= boundary_func(vals[2:-1], xint[1]) else: raise ValueError("Unrecognized scheme {}".format(scheme)) #Next, create the sparse matrix and solve the system # print([(d, sum(diags[d]!=0)) for d in diags if isinstance(diags[d], np.ndarray)]) offsets = sorted(diags.keys()) mat = sparse_diags([diags[d] for d in offsets], offsets, format='csc') # print mat.todense() if solver == 'spdiags': # print b # print mat.shape return spsolve(mat, b.flatten()) elif solver == 'solve_banded': ab, l_and_u = diags_to_banded(diags) # print b.flatten().shape, ab.shape return solve_banded(l_and_u,ab, b.flatten()) else: return solver(mat, b.flatten())
def solve_waveguide_mode_2d(mode_number: int, omega: complex, dxes: dx_lists_t, epsilon: vfield_t, mu: vfield_t = None, wavenumber_correction: bool = True ) -> Dict[str, Union[complex, field_t]]: """ Given a 2d region, attempts to solve for the eigenmode with the specified mode number. :param mode_number: Number of the mode, 0-indexed :param omega: Angular frequency of the simulation :param dxes: Grid parameters [dx_e, dx_h] as described in fdfd_tools.operators header :param epsilon: Dielectric constant :param mu: Magnetic permeability (default 1 everywhere) :param wavenumber_correction: Whether to correct the wavenumber to account for numerical dispersion (default True) :return: {'E': List[np.ndarray], 'H': List[np.ndarray], 'wavenumber': complex} """ ''' Solve for the largest-magnitude eigenvalue of the real operator by using power iteration. ''' # check if eps has a imaginary part if (np.imag(epsilon)!=0).any(): warnings.warn('Epsilon in 2D mode solver has an imaginary part' ) dxes_real = [[np.real(dx) for dx in dxi] for dxi in dxes] A_r = waveguide.operator(np.real(omega), dxes_real, np.real(epsilon), np.real(mu)) # Use power iteration for 20 steps to estimate the dominant eigenvector v = np.random.rand(A_r.shape[0]) for _ in range(20): v = A_r @ v v /= np.linalg.norm(v) lm_eigval = v @ A_r @ v ''' Shift by the absolute value of the largest eigenvalue, then find a few of the largest (shifted) eigenvalues. The shift ensures that we find the largest _positive_ eigenvalues, since any negative eigenvalues will be shifted to the range 0 >= neg_eigval + abs(lm_eigval) > abs(lm_eigval) ''' shifted_A_r = A_r + abs(lm_eigval) * sparse.eye(A_r.shape[0]) eigvals, eigvecs = spalg.eigs(shifted_A_r, which='LM', k=mode_number + 3, ncv=50) # Pick the eigenvalue we want from the few we found k = eigvals.argsort()[-(mode_number+1)] v = eigvecs[:, k] ''' Now solve for the eigenvector of the full operator, using the real operator's eigenvector as an initial guess for Rayleigh quotient iteration. ''' A = waveguide.operator(omega, dxes, epsilon, mu) eigval = None for _ in range(40): eigval = v @ A @ v if np.linalg.norm(A @ v - eigval * v) < 1e-13: break w = spalg.spsolve(A - eigval * sparse.eye(A.shape[0]), v) v = w / np.linalg.norm(w) # Calculate the wave-vector (force the real part to be positive) wavenumber = np.sqrt(eigval) wavenumber *= np.sign(np.real(wavenumber)) e, h = waveguide.normalized_fields(v, wavenumber, omega, dxes, epsilon, mu) ''' Perform correction on wavenumber to account for numerical dispersion. See Numerical Dispersion in Taflove's FDTD book. This correction term reduces the error in emitted power, but additional error is introduced into the E_err and H_err terms. This effect becomes more pronounced as beta increases. ''' if wavenumber_correction: wavenumber -= 2 * np.sin(np.real(wavenumber / 2)) - np.real(wavenumber) shape = [d.size for d in dxes[0]] fields = { 'wavenumber': wavenumber, 'E': unvec(e, shape), 'H': unvec(h, shape), } return fields
def tvdip(y, lambdas, display=1, stoptol=1e-3, maxiter=60): """Performs discrete total variation denoising (TVD) using a primal-dual interior-point solver. It minimizes the following discrete functional: E=(1/2)||y-x||_2^2+lambda*||Dx||_1 over the variable x, given the input signal y, according to each value of the regularization parametero lambda > 0. D is the first difference matrix. Uses hot-restarts from each value of lambda to speed up convergence for subsequent values: best use of the feature is made by ensuring that the chosen lambda values are close to each other. Args: y: Original signal to denoise, size N x 1. lambdas: A vector of positive regularization parameters, size L x 1. TVD will be applied to each value in the vector. display: (Optional) Set to 0 to turn off progress display, 1 to turn on. Defaults to 1. stoptol: (Optional) Precision as determined by duality gap tolerance, if not specified defaults to 1e-3. maxiter: (Optional) Maximum interior-point iterations, if not specified defaults to 60. Returns: x: Denoised output signal for each value of lambda, size N x L. E: Objective functional at minimum for each lamvda, size L x 1. s: Optimization result, 1 = solved, 0 = maximum iterations exceeded before reaching duality gap tolerance, size L x 1. lambdamax: Maximum value of lambda for the given y. If lambda >= lambdamax, the output is the trivial constant solution x = mean(y). """ # Search tuning parameters ALPHA = 0.01 # Backtracking linesearch parameter (0,0.5] BETA = 0.5 # Backtracking linesearch parameter (0,1) MAXLSITER = 20 # Max iterations of backtracking linesearch MU = 2 # t update N = y.size # Length of input signal y M = N - 1 # Size of Dx # Construct sparse operator matrices I1 = sparse.eye(M) O1 = sparse.dia_matrix((M, 1)) D = sparse.hstack([I1, O1]) - sparse.hstack([O1, I1]) DDT = D.dot(D.conj().T) Dy = D.dot(y) # Find max value of lambda lambdamax = (np.absolute(linalg.spsolve(DDT, Dy))).max(0) if display: print("lambda_max=%5.2e" % lambdamax) L = lambdas.size x = np.zeros((N, L)) s = np.zeros((L, 1)) E = np.zeros((L, 1)) # Optimization variables set up once at the start z = np.zeros((M, 1)) mu1 = np.ones((M, 1)) mu2 = np.ones((M, 1)) # Work through each value of lambda, with hot-restart on optimization # variables for idx, l in enumerate(lambdas): t = 1e-10 step = np.inf f1 = z - l f2 = -z - l # Main optimization loop s[idx] = 1 if display: print("Solving for lambda={0:5.2e}, lambda/lambda_max={1:5.2e}". format(l, l / lambdamax)) print("Iter# primal Dual Gap") for iters in range(maxiter): DTz = (z.conj().T * D).conj().T DDTz = D.dot(DTz) w = Dy - (mu1 - mu2) # Calculate objectives and primal-dual gap pobj1 = 0.5 * w.conj().T.dot(linalg.spsolve( DDT, w)) + l * (np.sum(mu1 + mu2)) pobj2 = 0.5 * DTz.conj().T.dot(DTz) + l * np.sum( np.absolute(Dy - DDTz)) pobj = np.minimum(pobj1, pobj2) dobj = -0.5 * DTz.conj().T.dot(DTz) + Dy.conj().T.dot(z) gap = pobj - dobj if display: print("{:5d} {:7.2e} {:7.2e} {:7.2e}".format( iters, pobj[0, 0], dobj[0, 0], gap[0, 0])) # Test duality gap stopping criterion if np.all(gap <= stoptol): # **** s[idx] = 1 break if step >= 0.2: t = np.maximum(2 * M * MU / gap, 1.2 * t) # Do Newton step rz = DDTz - w Sdata = (mu1 / f1 + mu2 / f2) S = DDT - sparse.csc_matrix( (Sdata.reshape(Sdata.size), (np.arange(M), np.arange(M)))) r = -DDTz + Dy + (1 / t) / f1 - (1 / t) / f2 dz = linalg.spsolve(S, r).reshape(r.size, 1) dmu1 = -(mu1 + ((1 / t) + dz * mu1) / f1) dmu2 = -(mu2 + ((1 / t) - dz * mu2) / f2) resDual = rz.copy() resCent = np.vstack((-mu1 * f1 - 1 / t, -mu2 * f2 - 1 / t)) residual = np.vstack((resDual, resCent)) # Perform backtracking linesearch negIdx1 = dmu1 < 0 negIdx2 = dmu2 < 0 step = 1 if np.any(negIdx1): step = np.minimum( step, 0.99 * (-mu1[negIdx1] / dmu1[negIdx1]).min(0)) if np.any(negIdx2): step = np.minimum( step, 0.99 * (-mu2[negIdx2] / dmu2[negIdx2]).min(0)) for _ in range(MAXLSITER): newz = z + step * dz newmu1 = mu1 + step * dmu1 newmu2 = mu2 + step * dmu2 newf1 = newz - l newf2 = -newz - l # Update residuals newResDual = DDT.dot(newz) - Dy + newmu1 - newmu2 newResCent = np.vstack( (-newmu1 * newf1 - 1 / t, -newmu2 * newf2 - 1 / t)) newResidual = np.vstack((newResDual, newResCent)) if (np.maximum(newf1.max(0), newf2.max(0)) < 0 and (scp.linalg.norm(newResidual) <= (1 - ALPHA * step) * scp.linalg.norm(residual))): break step = BETA * step # Update primal and dual optimization parameters z = newz mu1 = newmu1 mu2 = newmu2 f1 = newf1 f2 = newf2 x[:, idx] = (y - D.conj().T.dot(z)).reshape(x.shape[0]) xval = x[:, idx].reshape(x.shape[0], 1) E[idx] = 0.5 * np.sum( (y - xval)**2) + l * np.sum(np.absolute(D.dot(xval))) # We may have a close solution that does not satisfy the duality gap if iters >= maxiter: s[idx] = 0 if display: if s[idx]: print("Solved to precision of duality gap %5.2e") % gap else: print("Max iterations exceeded - solution may be inaccurate") return x, E, s, lambdamax
def update_fund_state_vec(J, x, f): """ perform Newton-Raphson iteration """ # TODO: try other solvers x_new = x - spsolve(J, f.T) return x_new
start_run_time = time.time() t = 0 RHS = model.RHS_system.coeffs X = model.state_system.coeffs for i in range(n_iterations): # Timestep model.compute_RHS() for dm, m in enumerate(simplesphere.local_m): # Forward Euler for RHS RHS[dm] = model.M[dm].dot(X[dm]) + dt * (RHS[dm]) if STORE_LU: X[dm] = A[dm].solve(RHS[dm]) else: X[dm] = spla.spsolve(A[dm], RHS[dm]) t += dt # Imagination cleaning if i % n_clean == 0: # Zero imaginary part by performing full transform loop state_system.unpack_coeffs() state_system.backward_theta() state_system.backward_phi() state_system.forward_phi() state_system.forward_theta() state_system.pack_coeffs() # Output if i % n_output == 0: # Gather full data to output
def _solve_S_from_DC(self, C_dataFrame, tee=False, with_bounds=False, max_iter=200): """Solves a basic least squares problems with SVD. Args: C_dataFrame (DataFrame) data frame with concentration values Returns: DataFrame with estimated S_values """ D_data = self.model.D if self._n_meas_lambdas: # build Dij vector D_vector = np.zeros(self._n_meas_times * self._n_meas_lambdas) row = [] col = [] data = [] for i, t in enumerate(self._meas_times): for j, l in enumerate(self._meas_lambdas): for k, c in enumerate(self._mixture_components): row.append(i * self._n_meas_lambdas + j) col.append(j * self._n_components + k) data.append(C_dataFrame[c][t]) D_vector[i * self._n_meas_lambdas + j] = D_data[t, l] Bd = coo_matrix((data, (row, col)), shape=(self._n_meas_times * self._n_meas_lambdas, self._n_components * self._n_meas_lambdas)) if not with_bounds: if self._n_meas_times == self._n_components: s_array = spsolve(Bd, D_vector) elif self._n_meas_times > self._n_components: result_ls = lsqr(Bd, D_vector, show=tee) s_array = result_ls[0] else: raise RuntimeError('Need n_t_meas >= self._n_components') else: nl = self._n_meas_lambdas nt = self._n_meas_times nc = self._n_components x0 = np.zeros(nl * nc) + 1e-2 M = Bd.tocsr() def F(x, M, rhs): return rhs - M.dot(x) def JF(x, M, rhs): return -M if tee == True: verbose = 2 else: verbose = 0 res_lsq = least_squares(F, x0, JF, bounds=(0.0, np.inf), max_nfev=max_iter, verbose=verbose, args=(M, D_vector)) s_array = res_lsq.x s_shaped = s_array.reshape( (self._n_meas_lambdas, self._n_components)) else: s_shaped = np.empty((self._n_meas_lambdas, self._n_components)) return s_shaped
def full(self,v): v = sp_la.spsolve(self.A,v) self.n_iter +=1 print('iter #' +str(self.n_iter)) return v
def fit(self, X_train, y_train, sample_weight=None): """Form K and solve (K + lambda * I)x = y in a block-wise fashion.""" np.random.seed(self.random_state) self.X_train = X_train n_features = X_train.shape[1] y = self.encode_y(y_train) if self.gamma is None: self.gamma = 1. / n_features K = metrics.pairwise.pairwise_kernels(X_train, metric=self.kernel, gamma=self.gamma) if self.verbose: print('Finished forming kernel matrix.') # compute some constants num_classes = len(list(set(y))) num_samples = K.shape[0] num_blocks = math.ceil(num_samples * 1.0 / self.block_size) x = np.zeros((K.shape[0], num_classes)) y_hat = np.zeros((K.shape[0], num_classes)) onehot = lambda x: np.eye(num_classes)[x] y_onehot = np.array(list(map(onehot, y))) idxes = np.diag_indices(num_samples) if sample_weight is not None: weights = np.sqrt(sample_weight) weights = weights[:, np.newaxis] y_onehot = weights * y_onehot K *= np.outer(weights, weights) if num_blocks == 1: epochs = 1 else: epochs = self.epochs for e in range(epochs): shuffled_coords = np.random.choice(num_samples, num_samples, replace=False) for b in range(int(num_blocks)): residuals = y_onehot - y_hat # Form a block of K. K[idxes] += (self.C * num_samples) block = shuffled_coords[b * self.block_size:min( (b + 1) * self.block_size, num_samples)] K_block = K[:, block] # Dim should be block size x block size KbTKb = K_block.T.dot(K_block) if self.verbose: print('solving block {0}'.format(b)) # Try linalg solve then sparse solve for handling of sparse input. try: x_block = linalg.solve(KbTKb, K_block.T.dot(residuals)) except: try: x_block = spsolve(KbTKb, K_block.T.dot(residuals)) except: return None # update model x[block] = x[block] + x_block K[idxes] = K[idxes] - (self.C * num_samples) y_hat = K.dot(x) y_pred = np.argmax(y_hat, axis=1) train_acc = metrics.accuracy_score(y, y_pred) if self.verbose: print('Epoch: {0}, Block: {1}, Train Accuracy: {2}'.format( e, b, train_acc)) self.coef_ = x
def mult(self,v): v = sp_la.spsolve(self.A,v) return v
def uzawa3(KKK,G,Nfem,nel,rhs_f,rhs_h): Vsol = numpy.zeros((Nfem),dtype=float) Psol = numpy.zeros((nel),dtype=float) Vsolmem = numpy.zeros((Nfem),dtype=float) Psolmem = numpy.zeros((nel),dtype=float) KKKmem = numpy.zeros((Nfem,Nfem),dtype=float) phi = numpy.zeros((Nfem),dtype=float) h = numpy.copy(phi) q = numpy.zeros((nel),dtype=float) d = numpy.copy(q) qkp1 = numpy.zeros((nel),dtype=float) dkp1 = numpy.copy(q) tol=1e-6 niter=250 KKKmem=KKK V_diff = [] P_diff = [] #compute u1 B=rhs_f-numpy.matmul(G,Psol) B=spsolve(KKK,B) Vsol=B q=rhs_h-numpy.matmul(G.transpose(),Vsol) d=-q file1=open('VP_diff_uzawa3.dat','w') for iter in range(0,niter): #compute pk phi=numpy.matmul(G,d) #compute hk=A^-1 pk B=phi B=spsolve(KKK,B) h=B #compute alpha alpha=numpy.dot(q,q)/numpy.dot(phi,h) #update pressure Psol=Psol+alpha*d #update velocity Vsol=Vsol-alpha*h #compute qk+1 qkp1=rhs_h-numpy.matmul(G.transpose(),Vsol) #compute beta beta=numpy.dot(qkp1,qkp1)/numpy.dot(q,q) #compute dkp1 dkp1=-qkp1+beta*d #check for convergence V_diff.append(numpy.max(abs(Vsol-Vsolmem))/numpy.max(abs(Vsol))) P_diff.append(numpy.max(abs(Psol-Psolmem))/numpy.max(abs(Psol))) print('\r','iteration:',iter,'V_diff:',V_diff[iter],'P_diff',P_diff[iter],'max(Psol)',numpy.max(Psol),end='') Psolmem=Psol Vsolmem=Vsol d=dkp1 q=qkp1 file1.write(str(iter+1) + ' ' + str(V_diff[iter]) + ' ' + str(P_diff[iter]) + '\n') if max(V_diff[iter],P_diff[iter]) < tol or iter == niter-1 : print('') file1.close() return (Vsol,Psol,V_diff,P_diff)
def ASD4(Ybus, S0, V0, I0, pv, pq, vd, tol, max_it=15, gamma=0.1): """ Alternate Search Directions Power Flow As defined in the paper: Unified formulation of a family of iterative solvers for power system analysis by Domenico Borzacchiello et. Al. Modifications: - Better reactive power computation - No need to partition the buses in PQ|PV - No need to perform the partitioning of Y, nor the Kron reduction for the PV buses correction - Automatic finding of gamma :param Ybus: Admittance matrix :param S0: Power injections :param V0: Initial Voltage Vector :param I0: Current injections @V=1.0 p.u. :param pv: Array of PV bus indices :param pq: Array of PQ bus indices :param vd: Array of Slack bus indices :param tol: Tolerance :param max_it: Maximum number of iterations :return: V, converged, normF, Scalc, iterations, elapsed """ start = time.time() # initialize V = V0.copy() Vset_pv = np.abs(V0[pv]) Scalc = S0.copy() normF = 1e20 iterations = 0 converged = False n = len(V0) pqpv = np.r_[pq, pv] pqpv.sort() # Create the zero-based indices in the internal reduced scheme pq_, pv_ = convert_to_reduced(pq, pv, vd, n) # reduced system Yred = Ybus[np.ix_(pqpv, pqpv)] Sred = S0[pqpv] I0_red = I0[pqpv] Yslack = - Ybus[np.ix_(pqpv, vd)] # yes, it is the negative of this Vslack = V0[vd] # compute alpha # Vabs = np.abs(Vslack) # alpha = sp.diags(np.conj(Sred) / (Vabs * Vabs)) alpha = -sp.linalg.inv(sp.diags(Yred.diagonal()).tocsc()) # compute Y-alpha Y_alpha = (Yred - alpha).tocsc() # compute beta as a vector B = Yred.diagonal() beta = diags(B) Y_beta = Yred - beta # get the first voltage approximation V0, or simply V(l Ivd = Yslack * Vslack # slack currents V_l = spsolve(Y_alpha, Ivd) # slack voltages influence while not converged and iterations < max_it: # Global step rhs_global = np.conj(Sred) / np.conj(V_l) - alpha * V_l + I0_red + Ivd V_l12 = spsolve(Y_alpha, rhs_global) # Better PV correction than the paper, using Lynn's formulation V_pv = V_l12[pv_] V_l12[pv_] = V_pv * Vset_pv / np.abs(V_pv) # compute the corrected bus voltage V[pqpv] = V_l12 # Assign the reduced solution # compute the reactive power at the PV nodes (actual scheme) Qpv = (V[pv] * np.conj((Ybus[pv, :] * V - I0[pv]))).imag # Find gamma the first time # if iterations == 0: N = 1 a = 1.0 b = 0 found = False c = (a + b) / 2 while not found or N <= max_it: # limit iterations to prevent infinite loop c = (a + b) / 2 # new midpoint f_c = func(Sred.copy(), pv_, c, Qpv, Y_beta, V_l12, I0_red, Ivd, B, V.copy(), pqpv, Ybus, I0, S0, pv, pq) f_a = func(Sred.copy(), pv_, a, Qpv, Y_beta, V_l12, I0_red, Ivd, B, V.copy(), pqpv, Ybus, I0, S0, pv, pq) sign_fa = f_a < 0 sign_fc = f_c < 0 if f_c <= tol or (a - b) / 2 < tol: # solution found found = True N += 1 # increment step counter if f_a > f_c: b = c else: a = c # new interval gamma = c # compute the reactive power at the PV nodes (actual scheme) Sred[pv_] = Sred[pv_].real + 1j * gamma * Qpv # assign the PV reactive power in the reduced scheme # local step A = (Y_beta * V_l12 - I0_red - Ivd) / B Sigma = - np.conj(Sred) / (A * np.conj(A) * B) U = (-1.0 - np.sqrt(1.0 - 4.0 * (Sigma.imag * Sigma.imag + Sigma.real))) / 2.0 + 1.0j * Sigma.imag V_l = U * A # Assign the reduced solution V[pqpv] = V_l # compute the calculated power injection and the error of the voltage solution Scalc = V * np.conj(Ybus * V - I0) mis = Scalc - S0 # complex power mismatch mismatch = np.r_[mis[pv].real, mis[pq].real, mis[pq].imag] # concatenate again normF = 0.5 * np.dot(mismatch, mismatch) # np.linalg.norm(mismatch, np.Inf) converged = normF < tol print(normF) iterations += 1 end = time.time() elapsed = end - start return V, converged, normF, Scalc, iterations, elapsed
def helm_coefficients_josep(Ybus, Yseries, V0, S0, Ysh0, pq, pv, sl, pqpv, tolerance=1e-6, max_coeff=30, verbose=False): """ Holomorphic Embedding LoadFlow Method as formulated by Josep Fanals Batllori in 2020 THis function just returns the coefficients for further usage in other routines :param Yseries: Admittance matrix of the series elements :param V0: vector of specified voltages :param S0: vector of specified power :param Ysh0: vector of shunt admittances (including the shunts of the branches) :param pq: list of pq nodes :param pv: list of pv nodes :param sl: list of slack nodes :param pqpv: sorted list of pq and pv nodes :param tolerance: target error (or tolerance) :param max_coeff: maximum number of coefficients :param verbose: print intermediate information :return: U, X, Q, iterations """ npqpv = len(pqpv) npv = len(pv) nsl = len(sl) n = Yseries.shape[0] # --------------------------- PREPARING IMPLEMENTATION ------------------------------------------------------------- U = np.zeros((max_coeff, npqpv), dtype=complex) # voltages W = np.zeros((max_coeff, npqpv), dtype=complex) # compute X=1/conj(U) Q = np.zeros((max_coeff, npqpv), dtype=complex) # unknown reactive powers Vm0 = np.abs(V0) Vm2 = Vm0 * Vm0 if n < 2: return U, W, Q, 0 if verbose: print('Yseries') print(Yseries.toarray()) df = pd.DataFrame(data=np.c_[Ysh0.imag, S0.real, S0.imag, Vm0], columns=['Ysh', 'P0', 'Q0', 'V0']) print(df) Yred = Yseries[np.ix_(pqpv, pqpv)] # admittance matrix without slack buses Yslack = -Yseries[np.ix_(pqpv, sl)] # yes, it is the negative of this Yslack_vec = Yslack.sum(axis=1).A1 G = np.real(Yred) # real parts of Yij B = np.imag(Yred) # imaginary parts of Yij P_red = S0.real[pqpv] Q_red = S0.imag[pqpv] Vslack = V0[sl] Ysh_red = Ysh0[pqpv] # indices 0 based in the internal scheme nsl_counted = np.zeros(n, dtype=int) compt = 0 for i in range(n): if i in sl: compt += 1 nsl_counted[i] = compt pq_ = pq - nsl_counted[pq] pv_ = pv - nsl_counted[pv] # .......................CALCULATION OF TERMS [0] ------------------------------------------------------------------ U[0, :] = spsolve(Yred, Yslack_vec) W[0, :] = 1 / np.conj(U[0, :]) # .......................CALCULATION OF TERMS [1] ------------------------------------------------------------------ valor = np.zeros(npqpv, dtype=complex) # get the current injections that appear due to the slack buses reduction I_inj_slack = Yslack * Vslack valor[pq_] = I_inj_slack[pq_] - Yslack_vec[pq_] + ( P_red[pq_] - Q_red[pq_] * 1j) * W[0, pq_] - U[0, pq_] * Ysh_red[pq_] valor[pv_] = I_inj_slack[pv_] - Yslack_vec[pv_] + P_red[pv_] * W[ 0, pv_] - U[0, pv_] * Ysh_red[pv_] # compose the right-hand side vector RHS = np.r_[valor.real, valor.imag, Vm2[pv] - (U[0, pv_] * U[0, pv_]).real] # Form the system matrix (MAT) Upv = U[0, pv_] Xpv = W[0, pv_] VRE = coo_matrix((2 * Upv.real, (np.arange(npv), pv_)), shape=(npv, npqpv)).tocsc() VIM = coo_matrix((2 * Upv.imag, (np.arange(npv), pv_)), shape=(npv, npqpv)).tocsc() XIM = coo_matrix((-Xpv.imag, (pv_, np.arange(npv))), shape=(npqpv, npv)).tocsc() XRE = coo_matrix((Xpv.real, (pv_, np.arange(npv))), shape=(npqpv, npv)).tocsc() EMPTY = csc_matrix((npv, npv)) MAT = vs((hs((G, -B, XIM)), hs((B, G, XRE)), hs((VRE, VIM, EMPTY))), format='csc') if verbose: print('MAT') print(MAT.toarray()) # factorize (only once) MAT_LU = factorized(MAT.tocsc()) # solve LHS = MAT_LU(RHS) # update coefficients U[1, :] = LHS[:npqpv] + 1j * LHS[npqpv:2 * npqpv] Q[0, pv_] = LHS[2 * npqpv:] W[1, :] = -W[0, :] * np.conj(U[1, :]) / np.conj(U[0, :]) # .......................CALCULATION OF TERMS [>=2] ---------------------------------------------------------------- iter_ = 1 range_pqpv = np.arange(npqpv, dtype=np.int64) V = V0.copy() c = 2 converged = False norm_f = tolerance + 1.0 # any number that violates the convergence while c < max_coeff and not converged: # c defines the current depth valor[pq_] = (P_red[pq_] - Q_red[pq_] * 1j) * W[c - 1, pq_] - U[c - 1, pq_] * Ysh_red[pq_] valor[pv_] = -1j * conv2(W, Q, c, pv_) - U[ c - 1, pv_] * Ysh_red[pv_] + W[c - 1, pv_] * P_red[pv_] RHS = np.r_[valor.real, valor.imag, -conv3(U, U, c, pv_).real] LHS = MAT_LU(RHS) # update voltage coefficients U[c, :] = LHS[:npqpv] + 1j * LHS[npqpv:2 * npqpv] # update reactive power Q[c - 1, pv_] = LHS[2 * npqpv:] # update voltage inverse coefficients W[c, range_pqpv] = -conv1(U, W, c, range_pqpv) / np.conj(U[0, range_pqpv]) # compute power mismatch if not np.mod(c, 2): # check the mismatch every 4 iterations V[pqpv] = U.sum(axis=0) Scalc = V * np.conj(Ybus * V) dP = np.abs(S0[pqpv].real - Scalc[pqpv].real) dQ = np.abs(S0[pq].imag - Scalc[pq].imag) norm_f = np.linalg.norm(np.r_[dP, dQ], np.inf) # same as max(abs()) # check convergence converged = norm_f < tolerance print('mismatch check at c=', c) c += 1 iter_ += 1 return U, W, Q, iter_, norm_f
def solve(self, A, b): return slin.spsolve(A, b)
def f_solve(self, b, alpha): L = sp.eye(self.Ndof) - alpha * self.M return LA.spsolve(L, b)
# plt.imshow(colorized) color_copy_for_nonzero = isColored.reshape(image_size, order='F').copy( ) # We have to reshape and make a copy of the view of an array for the nonzero() to work like in MATLAB colored_inds = np.nonzero(color_copy_for_nonzero) # print colored_inds # colored_inds as lblInds # print color_copy_for_nonzero.shape for t in [1, 2]: curIm = YUV[:, :, t].reshape(image_size, order='F').copy() # print curIm.shape b[colored_inds] = curIm[colored_inds] # print b[colored_inds] new_vals = linalg.spsolve( A, b ) # new_vals = linalg.lsqr(A, b)[0] # least-squares solution (much slower), slightly different solutions # lsqr returns unexpectedly (ndarray,ndarray) tuple, first is correct so: # use new_vals[0] for reshape if you use lsqr colorized[:, :, t] = new_vals.reshape(n, m, order='F') # ---------------------------------------------------------------------------- # # ------------------------------ Back to RGB --------------------------------- # # ---------------------------------------------------------------------------- # (R, G, B) = yiq_to_rgb(colorized[:, :, 0], colorized[:, :, 1], colorized[:, :, 2]) colorizedRGB = np.zeros(colorized.shape) colorizedRGB[:, :, 0] = R # colorizedRGB as colorizedIm colorizedRGB[:, :, 1] = G colorizedRGB[:, :, 2] = B
def update_harmonic_state_vec(J, x, f): """ perform Newton-Raphson iteration """ x_new = x - spsolve(J, f) return x_new
def _make_spline(self): pcount = self._xdata.size dx = np.diff(self._xdata) if not all(dx > 0): raise ValueError( 'Items of xdata vector must satisfy the condition: x1 < x2 < ... < xN' ) dy = np.diff(self._ydata, axis=self._axis) divdydx = dy / dx if pcount > 2: diags_r = np.vstack((dx[1:], 2 * (dx[1:] + dx[:-1]), dx[:-1])) r = sp.spdiags(diags_r, [-1, 0, 1], pcount - 2, pcount - 2) odx = 1. / dx diags_qt = np.vstack((odx[:-1], -(odx[1:] + odx[:-1]), odx[1:])) qt = sp.diags(diags_qt, [0, 1, 2], (pcount - 2, pcount)) ow = 1. / self._weights osqw = 1. / np.sqrt(self._weights) # type: np.ndarray w = sp.diags(ow, 0, (pcount, pcount)) qtw = qt @ sp.diags(osqw, 0, (pcount, pcount)) qtwq = qtw @ qtw.T if self._smooth: p = self._smooth else: p = self._compute_smooth(r, qtwq) a = (6. * (1. - p)) * qtwq + p * r b = np.diff(divdydx, axis=self._axis).T u = np.array(la.spsolve(a, b), ndmin=2) if self._ydim == 1: u = u.T dx = np.array(dx, ndmin=2).T d_pad = np.zeros((1, self._ydim)) d1 = np.diff(np.vstack((d_pad, u, d_pad)), axis=0) / dx d2 = np.diff(np.vstack((d_pad, d1, d_pad)), axis=0) yi = np.array(self._ydata, ndmin=2).T yi = yi - ((6. * (1. - p)) * w) @ d2 c3 = np.vstack((d_pad, p * u, d_pad)) c2 = np.diff(yi, axis=0) / dx - dx * (2. * c3[:-1, :] + c3[1:, :]) coeffs = np.hstack(((np.diff(c3, axis=0) / dx).T, 3. * c3[:-1, :].T, c2.T, yi[:-1, :].T)) c_shape = ((pcount - 1) * self._ydim, 4) coeffs = coeffs.reshape(c_shape, order='F') else: p = 1. coeffs = np.array(np.hstack( (divdydx, np.array(self._ydata[:, 0], ndmin=2).T)), ndmin=2) self._smooth = p self._spline = SplinePPForm(self._xdata, coeffs, self._ydim)
def fill_depth_colorization(imgRgb=None, imgDepthInput=None, alpha=1): imgIsNoise = imgDepthInput == 0 maxImgAbsDepth = np.max(imgDepthInput) imgDepth = imgDepthInput / maxImgAbsDepth imgDepth[imgDepth > 1] = 1 (H, W) = imgDepth.shape numPix = H * W indsM = np.arange(numPix).reshape((W, H)).transpose() knownValMask = (imgIsNoise == False).astype(int) grayImg = skimage.color.rgb2gray(imgRgb) winRad = 1 len_ = 0 absImgNdx = 0 len_window = (2 * winRad + 1)**2 len_zeros = numPix * len_window cols = np.zeros(len_zeros) - 1 rows = np.zeros(len_zeros) - 1 vals = np.zeros(len_zeros) - 1 gvals = np.zeros(len_window) - 1 for j in range(W): for i in range(H): nWin = 0 for ii in range(max(0, i - winRad), min(i + winRad + 1, H)): for jj in range(max(0, j - winRad), min(j + winRad + 1, W)): if ii == i and jj == j: continue rows[len_] = absImgNdx cols[len_] = indsM[ii, jj] gvals[nWin] = grayImg[ii, jj] len_ = len_ + 1 nWin = nWin + 1 curVal = grayImg[i, j] gvals[nWin] = curVal c_var = np.mean((gvals[:nWin + 1] - np.mean(gvals[:nWin + 1]))**2) csig = c_var * 0.6 mgv = np.min((gvals[:nWin] - curVal)**2) if csig < -mgv / np.log(0.01): csig = -mgv / np.log(0.01) if csig < 2e-06: csig = 2e-06 gvals[:nWin] = np.exp(-(gvals[:nWin] - curVal)**2 / csig) gvals[:nWin] = gvals[:nWin] / sum(gvals[:nWin]) vals[len_ - nWin:len_] = -gvals[:nWin] # Now the self-reference (along the diagonal). rows[len_] = absImgNdx cols[len_] = absImgNdx vals[len_] = 1 # sum(gvals(1:nWin)) len_ = len_ + 1 absImgNdx = absImgNdx + 1 vals = vals[:len_] cols = cols[:len_] rows = rows[:len_] A = scipy.sparse.csr_matrix((vals, (rows, cols)), (numPix, numPix)) rows = np.arange(0, numPix) cols = np.arange(0, numPix) vals = (knownValMask * alpha).transpose().reshape(numPix) G = scipy.sparse.csr_matrix((vals, (rows, cols)), (numPix, numPix)) A = A + G b = np.multiply(vals.reshape(numPix), imgDepth.flatten('F')) #print ('Solving system..') new_vals = spsolve(A, b) new_vals = np.reshape(new_vals, (H, W), 'F') #print ('Done.') denoisedDepthImg = new_vals * maxImgAbsDepth output = denoisedDepthImg.reshape((H, W)).astype('float32') output = np.multiply(output, (1 - knownValMask)) + imgDepthInput return output
c1 = (1j*(hbarc*c)/(2*mc_2)) data = np.ones((3, int(Nx))) data[1,:] = -2 diags = [-1, 0, 1] D = c1*sparse.spdiags(data, diags, Nx, Nx)/(dx**2) c2 =-1j*c/hbarc M = c2*sparse.spdiags(V(x), [0], Nx, Nx) Psi = np.zeros((Nt, Nx), dtype = complex) Psi[0] = psi(x) for n,i in enumerate(t[1:]): A = (I - 0.5*dt*(D + M)) b = (I + 0.5*dt*(D + M))*Psi[n] Psi[n+1] = linalg.spsolve(A, b) Psi[n+1] = Psi[n+1]/sp.integrate.simps(abs(Psi[n+1])**2, dx=dx) psi = np.absolute(Psi) psi[:,i_x2:] *= 1e59 animate(x, psi) """ t0 = 1e-18 i = np.abs(t-t0).argmin() plt.title("t = %1.1g. For $x > x_2$, is $|\psi(x,t)|$ scaled up by factor $10^{59}$" % t0) plt.plot([x1, x1], [0,1],'k--') plt.plot([x2, x2], [0,1],'k--', label="potensial barrier, $\Delta x$ = %2.f fm" % delta_x) plt.plot(x,psi[i],'y-',label="|$\psi(x,%1.1g)$|" % t0) plt.xlabel("x [fm]") plt.ylabel("|$\psi(x,%1.1g)$|" % t0) plt.legend(loc=2)
def fin_vol(x_nodes, y_nodes, inflation=compute_inflation, inflation_factor=inf_fact): # bring in global variables global gamma global phi_ext global phi_xl global phi_x0 global hf global CV_h global CV_l dx = CV_l / x_nodes # distance between nodes in the x direction dy = CV_h / y_nodes # distance between nodes in the y direction total_nodes = y_nodes * x_nodes # total number of nodes x_index = np.zeros(x_nodes) # initialize x nodes matrix to zero y_index = np.zeros(y_nodes) # initialize y nodes matrix to zero matrix_index = np.arange(total_nodes).reshape( x_nodes, y_nodes) # matrix index to map node position within CV matrix_a = sp.lil_matrix( (total_nodes, total_nodes)) # coefficent matrix of form AX = B, "A" matrix_b = np.zeros(total_nodes) # product matrix of form AX = B, "B" if inflation == "no": for i in range(y_nodes): for j in range(x_nodes): if i == 0: # southern most node a_n = gamma * (dx / dy) a_s = 0 s_p = 0 matrix_a[matrix_index[j, i], matrix_index[ j, i + 1]] = -a_n # updates coef right of ap equal to an # print(matrix_index[i, j], matrix_index[j, i+1]) matrix_b[matrix_index[ j, i]] = a_s # sets product matrix equal to as elif i == y_nodes - 1: # northern most node a_n = 0 a_s = gamma * (dx / dy) s_p = -hf * dx # source term sp s_u = hf * phi_ext * dx # source term su matrix_a[matrix_index[j, i], matrix_index[ j, i - 1]] = -a_s # updates coef left of ap equal to as matrix_b[matrix_index[ j, i]] = a_n + s_u # updates product matrix else: # middle nodes a_n = gamma * (dx / dy) a_s = gamma * (dx / dy) s_p = 0 matrix_a[matrix_index[j, i], matrix_index[ j, i + 1]] = -a_n # updates coeffs to the right matrix_a[matrix_index[j, i], matrix_index[ j, i - 1]] = -a_s # updates coeffs to the left if j == 0: a_w = gamma * ( dy / (dx / 2) ) # divide by 2 because at western most node dx is halved a_e = gamma * (dy / dx) matrix_a[matrix_index[j, i], matrix_index[j + 1, i]] = -a_e # updates row below ap matrix_b[matrix_index[ j, i]] = a_w * phi_x0 # updates product matrix elif j == x_nodes - 1: a_w = gamma * (dy / dx) a_e = gamma * ( dy / (dx / 2) ) # divide by 2 because at eastern most node dx is halved matrix_a[matrix_index[j, i], matrix_index[j - 1, i]] = -a_w # updates row above ap matrix_b[matrix_index[ j, i]] = a_e * phi_xl # updates product matrix else: a_w = gamma * (dy / dx) a_e = gamma * (dy / dx) matrix_a[matrix_index[j, i], matrix_index[j + 1, i]] = -a_e matrix_a[matrix_index[j, i], matrix_index[j - 1, i]] = -a_w a_p = a_n + a_s + a_w + a_e - s_p # updates coefficient at point p (i.e. the investigated node) matrix_a[matrix_index[j, i], matrix_index[ j, i]] = a_p # sets node value at i,j equal to ap # updates x position of node within control volume for i in range(x_nodes): if i == 0: x_index[ i] = dx / 2 # initial node position within control volume else: x_index[i] = x_index[ i - 1] + dx # add dx to the last node to get next node position # updates y position of node within control volume for j in range(y_nodes): if j == 0: y_index[ j] = dy / 2 # initial y node position within control volume else: y_index[j] = y_index[ j - 1] + dy # add dy to last node to get next node position elif inflation == "yes": inflate_x = np.zeros( x_nodes + 1) # initialize new array for inflated x spacing values inflate_y = np.zeros( y_nodes + 1) # initialize new array for inflated y spacing values xmap = 0 # initial position of first node in x ymap = 0 # initial position of first node in y for i in range(x_nodes + 1): if i == 0: inflate_x[i] = ((1 - inflation_factor) / (1 - inflation_factor** (x_nodes / 2))) * CV_l / 2 # first node else: if xmap <= CV_l / 2: inflate_x[i] = inflation_factor * inflate_x[ i - 1] # inflate x according to above if before halfway pt else: inflate_x[i] = inflate_x[ i - 1] / inflation_factor # deflate x after halfway point xmap += inflate_x[i] inflate_x = ( 1 / xmap) * inflate_x # re scales domain according to new spacing for i in range(y_nodes + 1): if i == 0: inflate_y[i] = ((1 - inflation_factor) / (1 - inflation_factor** (y_nodes / 2))) * CV_h / 2 # first y node else: if ymap <= CV_h / 2: inflate_y[i] = inflation_factor * inflate_y[ i - 1] # inflates y node up until halfway point else: inflate_y[i] = inflate_y[ i - 1] / inflation_factor # deflates y node after halfway ymap += inflate_y[i] inflate_y = (1 / ymap) * inflate_y # rescales domain in y direction # same process as no inflation except now we are using inflated x,y and not dx,dy for i in range(y_nodes): for j in range(x_nodes): if i == 0: a_n = gamma * (inflate_x[j] / inflate_y[i + 1]) a_s = 0 s_p = 0 matrix_a[matrix_index[j, i], matrix_index[j, i + 1]] = -a_n matrix_b[matrix_index[j, i]] = a_s elif i == y_nodes - 1: a_n = 0 a_s = gamma * (inflate_x[j] / inflate_y[i]) s_p = -hf * inflate_x[j] s_u = hf * phi_ext * inflate_x[j] matrix_a[matrix_index[j, i], matrix_index[j, i - 1]] = -a_s matrix_b[matrix_index[j, i]] = a_n + s_u else: a_n = gamma * (inflate_x[j] / inflate_y[i + 1]) a_s = gamma * (inflate_x[j] / inflate_y[i]) s_p = 0 matrix_a[matrix_index[j, i], matrix_index[j, i + 1]] = -a_n matrix_a[matrix_index[j, i], matrix_index[j, i - 1]] = -a_s if j == 0: a_w = gamma * (inflate_y[i] / inflate_x[j]) a_e = gamma * (inflate_y[i] / inflate_x[j + 1]) matrix_a[matrix_index[j, i], matrix_index[j + 1, i]] = -a_e matrix_b[matrix_index[j, i]] = a_w * phi_x0 elif j == x_nodes - 1: a_w = gamma * (inflate_y[i] / inflate_x[j]) a_e = gamma * (inflate_y[i] / inflate_x[j + 1]) matrix_a[matrix_index[j, i], matrix_index[j - 1, i]] = -a_w matrix_b[matrix_index[j, i]] = a_e * phi_xl else: a_w = gamma * (inflate_y[i] / inflate_x[j]) a_e = gamma * (inflate_y[i] / inflate_x[j + 1]) matrix_a[matrix_index[j, i], matrix_index[j + 1, i]] = -a_e matrix_a[matrix_index[j, i], matrix_index[j - 1, i]] = -a_w a_p = a_n + a_s + a_w + a_e - s_p matrix_a[matrix_index[j, i], matrix_index[j, i]] = a_p # updates x with inflated nodes for i in range(x_nodes): if i == 0: x_index[i] = inflate_x[i] else: x_index[i] = x_index[i - 1] + inflate_x[i] # updates y with inflated nodes for i in range(y_nodes): if i == 0: y_index[i] = inflate_y[i] else: y_index[i] = y_index[i - 1] + inflate_y[i] else: print("this is not a valid entry, please enter 'yes' or 'no'") # solves sparse matrices a and b phi_p = sparlin.spsolve(sp.csc_matrix(matrix_a), matrix_b) # reshape the solved matrix to match node position within the control volume phi_p = phi_p.reshape(x_nodes, y_nodes) # sets grid spacing for plots according to wether or not there is inflation if inflation == "no": x, y = np.meshgrid(np.linspace(0, CV_l, x_nodes), np.linspace(0, CV_h, y_nodes)) else: x, y = np.meshgrid(x_index, y_index) return phi_p, x_index, y_index, x, y
def ScalarField_InitialData(outputname, Ccodesdir, ID_Family, pulse_amplitude, pulse_center, pulse_width, NR, rmax, lapse_condition="Pre-collapsed", CoordSystem="Spherical", sinhA=None, sinhW=None): if CoordSystem == "Spherical": r = np.linspace(0, rmax, NR + 1) # Set the r array dr = np.zeros(NR) for i in range(NR): dr[i] = r[1] - r[0] r = np.delete( r - dr[0] / 2, 0) # Shift the vector by -dr/2 and remove the negative entry elif CoordSystem == "SinhSpherical": if sinhA is None or sinhW is None: print( "Error: SinhSpherical coordinates require initialization of both sinhA and sinhW" ) sys.exit(1) else: x = np.linspace(0, 1.0, NR + 1) dx = 1.0 / (NR + 1) x = np.delete( x - dx / 2, 0) # Shift the vector by -dx/2 and remove the negative entry r = sinhA * np.sinh(x / sinhW) / np.sinh(1.0 / sinhW) dr = sinhA * np.cosh(x / sinhW) / np.sinh(1.0 / sinhW) * dx else: print("Error: Unknown coordinate system") sys.exit(1) # Set the step size squared dr2 = dr**2 # Let's begin by setting the parameters involved in the initial data phi0, rr, rr0, sigma = sp.symbols("phi0 rr rr0 sigma", real=True) # Now set the initial profile of the scalar field if ID_Family == "Gaussian_pulse": phiID = phi0 * sp.exp(-rr**2 / sigma**2) elif ID_Family == "Gaussian_pulsev2": phiID = phi0 * rr**3 * sp.exp(-(rr - rr0)**2 / sigma**2) elif ID_Family == "Tanh_pulse": phiID = phi0 * (1 - sp.tanh((rr - rr0)**2 / sigma**2)) else: print("Unkown initial data family: ", ID_Family) print( "Available options are: Gaussian_pulse, Gaussian_pulsev2, and Tanh_pulse" ) sys.exit(1) # Now compute Phi := \partial_{r}phi PhiID = sp.diff(phiID, rr) # Now set numpy functions for phi and Phi phi = sp.lambdify((phi0, rr, rr0, sigma), phiID) Phi = sp.lambdify((phi0, rr, rr0, sigma), PhiID) # ## Part A.1c: populating the varphi(0,r) array phi0 = pulse_amplitude r0 = pulse_center sigma = pulse_width ID_sf = phi(phi0, r, r0, sigma) # Set the main diagonal main_diag = np.pi * dr2 * Phi(phi0, r, r0, sigma)**2 - 2 # Update the first element of the main diagonal main_diag[0] += 1 - dr[0] / r[0] # Update the last element of the main diagonal main_diag[NR - 1] += -(2 * dr[NR - 1] / r[NR - 1]) * (1 + dr[NR - 1] / r[NR - 1]) # Set the upper diagonal, ignoring the last point in the r array upper_diag = np.zeros(NR) upper_diag[1:] = 1 + dr[:-1] / r[:-1] # Set the lower diagonal, start counting the r array at the second element lower_diag = np.zeros(NR) lower_diag[:-1] = 1 - dr[1:] / r[1:] # Change the last term in the lower diagonal to its correct value lower_diag[NR - 2] = 2 # Set the sparse matrix A by adding up the three diagonals # https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.spdiags.html A = spdiags([main_diag, upper_diag, lower_diag], [0, 1, -1], NR, NR) # Then compress the sparse matrix A column wise, so that SciPy can invert it later # https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csc_matrix.html A = csc_matrix(A) # Set up the right-hand side of the linear system: s s = np.zeros(NR) # Update the last entry of the vector s s[NR - 1] = -(2 * dr[NR - 1] / r[NR - 1]) * (1 + dr[NR - 1] / r[NR - 1]) # Compress the vector s column-wise # https://docs.scipy.org/doc/scipy/reference/generated/scipy.sparse.csc_matrix.html s = csc_matrix(s) # Solve the sparse linear system using scipy # https://docs.scipy.org/doc/scipy-0.14.0/reference/generated/scipy.sparse.linalg.spsolve.html psi = spsolve(A, s.T) if lapse_condition == "Pre-collapsed": ID_alpha = psi**(-2) if sys.version_info[0] == 3: np.savetxt(outputname, list(zip(r, ID_sf, psi**4, ID_alpha)), fmt="%.15e") elif sys.version_info[0] == 2: np.savetxt(outputname, zip(r, ID_sf, psi**4, ID_alpha), fmt="%.15e") elif lapse_condition == "Unity": ID_alpha = np.ones(NR) if sys.version_info[0] == 3: np.savetxt(outputname, list(zip(r, ID_sf, psi**4, ID_alpha)), fmt="%.15e") elif sys.version_info[0] == 2: np.savetxt(outputname, zip(r, ID_sf, psi**4, ID_alpha), fmt="%.15e") else: print( "Error: unknown lapse condition. Available options are: \"Pre-collapsed\" and \"Unity\"" ) return print("Generated the ADM initial data for the gravitational collapse \n" \ "of a massless scalar field in %s coordinates.\n"%CoordSystem) print("Type of initial condition: Scalar field: \"Gaussian\" Shell\n"\ " ADM quantities: Time-symmetric\n"\ " Lapse condition: "+lapse_condition) print("Parameters: amplitude = "+str(phi0)+",\n" \ " center = "+str(r0)+",\n" \ " width = "+str(sigma)+",\n" \ " domain size = "+str(rmax)+",\n" \ " number of points = "+str(NR)+",\n" " Initial data file = "+str(outputname)+".\n") with open(os.path.join(Ccodesdir, "ID_scalar_field_ADM_quantities.h"), "w") as file: file.write(""" // This function takes as input either (x,y,z) or (r,th,ph) and outputs // all ADM quantities in the Cartesian or Spherical basis, respectively. void ID_scalar_field_ADM_quantities( const REAL xyz_or_rthph[3], const ID_inputs other_inputs, REAL *gammaDD00,REAL *gammaDD01,REAL *gammaDD02,REAL *gammaDD11,REAL *gammaDD12,REAL *gammaDD22, REAL *KDD00,REAL *KDD01,REAL *KDD02,REAL *KDD11,REAL *KDD12,REAL *KDD22, REAL *alpha, REAL *betaU0,REAL *betaU1,REAL *betaU2, REAL *BU0,REAL *BU1,REAL *BU2) { const REAL r = xyz_or_rthph[0]; const REAL th = xyz_or_rthph[1]; const REAL ph = xyz_or_rthph[2]; REAL sf_star,psi4_star,alpha_star; scalar_field_interpolate_1D(r, other_inputs.interp_stencil_size, other_inputs.numlines_in_file, other_inputs.r_arr, other_inputs.sf_arr, other_inputs.psi4_arr, other_inputs.alpha_arr, &sf_star,&psi4_star,&alpha_star); // Update alpha *alpha = alpha_star; // gamma_{rr} = psi^4 *gammaDD00 = psi4_star; // gamma_{thth} = psi^4 r^2 *gammaDD11 = psi4_star*r*r; // gamma_{phph} = psi^4 r^2 sin^2(th) *gammaDD22 = psi4_star*r*r*sin(th)*sin(th); // All other quantities ARE ZERO: *gammaDD01 = 0.0; *gammaDD02 = 0.0; /**/ *gammaDD12 = 0.0; *KDD00 = 0.0; *KDD01 = 0.0; *KDD02 = 0.0; /**/ *KDD11 = 0.0; *KDD12 = 0.0; /**/ *KDD22 = 0.0; *betaU0 = 0.0; *betaU1 = 0.0; *betaU2 = 0.0; *BU0 = 0.0; *BU1 = 0.0; *BU2 = 0.0; }\n""") print("Wrote to file " + os.path.join(Ccodesdir, "ID_scalar_field_ADM_quantities.h")) with open(os.path.join(Ccodesdir, "ID_scalar_field_spherical.h"), "w") as file: file.write(""" void ID_scalarfield_spherical( const REAL xyz_or_rthph[3], const ID_inputs other_inputs, REAL *sf, REAL *sfM) { const REAL r = xyz_or_rthph[0]; const REAL th = xyz_or_rthph[1]; const REAL ph = xyz_or_rthph[2]; REAL sf_star,psi4_star,alpha_star; scalar_field_interpolate_1D(r, other_inputs.interp_stencil_size, other_inputs.numlines_in_file, other_inputs.r_arr, other_inputs.sf_arr, other_inputs.psi4_arr, other_inputs.alpha_arr, &sf_star,&psi4_star,&alpha_star); // Update varphi *sf = sf_star; // Update Pi *sfM = 0; }\n""") print("Wrote to file " + os.path.join(Ccodesdir, "ID_scalar_field_spherical.h")) # Make sure that rfm.reference_metric() has been called. # We'll need the variables it defines throughout this module. rfm.reference_metric() CoordType_in = "Spherical" pointer_to_ID_inputs = False sf, sfM = sp.symbols("sfSphorCart sfMSphorCart") r_th_ph_or_Cart_xyz_oID_xx = [] if CoordType_in == "Spherical": r_th_ph_or_Cart_xyz_oID_xx = rfm.xxSph else: print( "Error: Can only convert scalar field Spherical initial data to BSSN Curvilinear coords." ) sys.exit(1) with open( os.path.join(Ccodesdir, "ID_scalarfield_xx0xx1xx2_to_BSSN_xx0xx1xx2.h"), "w") as file: file.write( "void ID_scalarfield_xx0xx1xx2_to_BSSN_xx0xx1xx2(const paramstruct *restrict params,const REAL xx0xx1xx2[3]," ) if pointer_to_ID_inputs == True: file.write("ID_inputs *other_inputs,") else: file.write("ID_inputs other_inputs,") file.write(""" REAL *restrict sf, REAL *restrict sfM ) { #include \"set_Cparameters.h\" REAL sfSphorCart,sfMSphorCart; const REAL xx0 = xx0xx1xx2[0]; const REAL xx1 = xx0xx1xx2[1]; const REAL xx2 = xx0xx1xx2[2]; REAL xyz_or_rthph[3];\n""") outCparams = "preindent=1,outCfileaccess=a,outCverbose=False,includebraces=False" outputC( r_th_ph_or_Cart_xyz_oID_xx[0:3], ["xyz_or_rthph[0]", "xyz_or_rthph[1]", "xyz_or_rthph[2]"], os.path.join(Ccodesdir, "ID_scalarfield_xx0xx1xx2_to_BSSN_xx0xx1xx2.h"), outCparams + ",CSE_enable=False") with open( os.path.join(Ccodesdir, "ID_scalarfield_xx0xx1xx2_to_BSSN_xx0xx1xx2.h"), "a") as file: file.write("""ID_scalarfield_spherical(xyz_or_rthph, other_inputs, &sfSphorCart, &sfMSphorCart); // Next compute all rescaled BSSN curvilinear quantities:\n""") outCparams = "preindent=1,outCfileaccess=a,outCverbose=False,includebraces=False" outputC([sf, sfM], ["*sf", "*sfM"], os.path.join(Ccodesdir, "ID_scalarfield_xx0xx1xx2_to_BSSN_xx0xx1xx2.h"), params=outCparams) with open( os.path.join(Ccodesdir, "ID_scalarfield_xx0xx1xx2_to_BSSN_xx0xx1xx2.h"), "a") as file: file.write("}\n") # Driver with open(os.path.join(Ccodesdir, "ID_scalarfield.h"), "w") as file: file.write( """void ID_scalarfield(const paramstruct *restrict params,REAL *restrict xx[3], ID_inputs other_inputs,REAL *restrict in_gfs) { #include \"set_Cparameters.h\"\n""") file.write( lp.loop(["i2", "i1", "i0"], ["0", "0", "0"], [ "Nxx_plus_2NGHOSTS2", "Nxx_plus_2NGHOSTS1", "Nxx_plus_2NGHOSTS0" ], ["1", "1", "1"], [ "#pragma omp parallel for", " const REAL xx2 = xx[2][i2];", " const REAL xx1 = xx[1][i1];" ], "", """const REAL xx0 = xx[0][i0]; const int idx = IDX3S(i0,i1,i2); const REAL xx0xx1xx2[3] = {xx0,xx1,xx2}; ID_scalarfield_xx0xx1xx2_to_BSSN_xx0xx1xx2(params,xx0xx1xx2,other_inputs, &in_gfs[IDX4ptS(SFGF,idx)],&in_gfs[IDX4ptS(SFMGF,idx)]);\n}\n""" ))
def colorize(self, imgpath, mark): #path_greyimg="/home/guyuchao/github/src/gycImgProcess/example2.bmp" #path_mask="/home/guyuchao/github/src/testimg.jpg" original = np.array(Image.open(imgpath).resize((400, 400))) neworiginal = np.zeros((original.shape[0], original.shape[1], 3)) if len(original.shape) == 2: #单通道灰度图 neworiginal[:, :, 0] = original neworiginal[:, :, 1] = original neworiginal[:, :, 2] = original original = neworiginal.astype(np.uint8) #original=np.array(Image.open(imgpath)) marked = np.array(mark) isColored = ((marked[:, :, 0] > 20) | (marked[:, :, 1] > 20) | (marked[:, :, 2] > 20)) yuv_origin = self._rgb2yuv(original) yuv_mark = self._rgb2yuv(marked) #isColored = abs(original - marked).sum(2) > 2.55 # isColored as colorIm YUV = np.zeros((original.shape)) YUV[:, :, 0] = yuv_origin[:, :, 0] YUV[:, :, 1] = yuv_mark[:, :, 1] YUV[:, :, 2] = yuv_mark[:, :, 2] h, w, _ = YUV.shape image_size = h * w order = np.arange(image_size).reshape(h, w, order='F').copy() around_num = 9 max_matrix_len = image_size * around_num row_inds = np.zeros(max_matrix_len, dtype=np.int64) col_inds = np.zeros(max_matrix_len, dtype=np.int64) vals = np.zeros(max_matrix_len) inds_length = 0 # 稀疏索引长度 pixel_where = 0 # 像素所在位置 for j in range(w): self.progress = 100 * j / w if 100 * j / w < 95 else 95 for i in range(h): if (not isColored[i, j]): window_index = 0 window_vals = np.zeros(around_num) for ii in range(max(0, i - 1), min(i + 2, h)): for jj in range(max(0, j - 1), min(j + 2, w)): if (ii != i or jj != j): row_inds[inds_length] = pixel_where col_inds[inds_length] = order[ii, jj] window_vals[window_index] = YUV[ii, jj, 0] inds_length += 1 window_index += 1 center = YUV[i, j, 0].copy() # t_val as center window_vals[window_index] = center variance = np.var(window_vals[0:window_index + 1]) sigma = variance * 0.6 mgv = min((window_vals[0:window_index + 1] - center)**2) if (sigma < (-mgv / np.log(0.01))): sigma = -mgv / np.log(0.01) if (sigma < 0.000002): sigma = 0.000002 window_vals[0:window_index] = np.exp( -((window_vals[0:window_index] - center)**2) / (sigma)) window_vals[0:window_index] = window_vals[ 0:window_index] / np.sum(window_vals[0:window_index]) vals[inds_length - window_index: inds_length] = -window_vals[0:window_index] row_inds[inds_length] = pixel_where col_inds[inds_length] = order[i, j] vals[inds_length] = 1 inds_length += 1 pixel_where += 1 vals = vals[0:inds_length] col_inds = col_inds[0:inds_length] row_inds = row_inds[0:inds_length] A = sparse.csr_matrix((vals, (row_inds, col_inds)), (pixel_where, image_size)) b = np.zeros((A.shape[0])) colorized = np.zeros(YUV.shape) colorized[:, :, 0] = YUV[:, :, 0] color_copy_for_nonzero = isColored.reshape(image_size, order='F').copy() colored_inds = np.nonzero(color_copy_for_nonzero) for t in [1, 2]: curIm = YUV[:, :, t].reshape(image_size, order='F').copy() b[colored_inds] = curIm[colored_inds] new_vals = linalg.spsolve(A, b) colorized[:, :, t] = new_vals.reshape(h, w, order='F') self.progress = 100 return Image.fromarray(self._yuv2rgb(colorized.astype(np.uint8)))
def implicit_weighted_ALS(training_set, lambda_val = 0.1, alpha = 40, iterations = 10, rank_size = 20, seed = 0): ''' Implicit weighted ALS taken from Hu, Koren, and Volinsky 2008. Designed for alternating least squares and implicit feedback based collaborative filtering. parameters: training_set - Our matrix of ratings with shape m x n, where m is the number of users and n is the number of items. Should be a sparse csr matrix to save space. lambda_val - Used for regularization during alternating least squares. Increasing this value may increase bias but decrease variance. Default is 0.1. alpha - The parameter associated with the confidence matrix discussed in the paper, where Cui = 1 + alpha*Rui. The paper found a default of 40 most effective. Decreasing this will decrease the variability in confidence between various ratings. iterations - The number of times to alternate between both user feature vector and item feature vector in alternating least squares. More iterations will allow better convergence at the cost of increased computation. The authors found 10 iterations was sufficient, but more may be required to converge. rank_size - The number of latent features in the user/item feature vectors. The paper recommends varying this between 20-200. Increasing the number of features may overfit but could reduce bias. seed - Set the seed for reproducible results returns: The feature vectors for users and items. The dot product of these feature vectors should give you the expected "rating" at each point in your original matrix. ''' # first set up our confidence matrix conf = (alpha*training_set) # To allow the matrix to stay sparse, I will add one later when each row is taken # and converted to dense. num_user = conf.shape[0] num_item = conf.shape[1] # Get the size of our original ratings matrix, m x n # initialize our X/Y feature vectors randomly with a set seed rstate = np.random.RandomState(seed) X = sparse.csr_matrix(rstate.normal(size = (num_user, rank_size))) # Random numbers in a m x rank shape Y = sparse.csr_matrix(rstate.normal(size = (num_item, rank_size))) # Normally this would be rank x n but we can # transpose at the end. Makes calculation more simple. X_eye = sparse.eye(num_user) Y_eye = sparse.eye(num_item) lambda_eye = lambda_val * sparse.eye(rank_size) # Our regularization term lambda*I. # We can compute this before iteration starts. # Begin iterations for iter_step in tqdm(range(iterations)): # Iterate back and forth between solving X given fixed Y and vice versa # Compute yTy and xTx at beginning of each iteration to save computing time yTy = Y.T.dot(Y) xTx = X.T.dot(X) # Being iteration to solve for X based on fixed Y for u in range(num_user): conf_samp = conf[u,:].toarray() # Grab user row from confidence matrix and convert to dense pref = conf_samp.copy() pref[pref != 0] = 1 # Create binarized preference vector CuI = sparse.diags(conf_samp, [0]) # Get Cu - I term, don't need to subtract 1 since we never added it yTCuIY = Y.T.dot(CuI).dot(Y) # This is the yT(Cu-I)Y term yTCupu = Y.T.dot(CuI + Y_eye).dot(pref.T) # This is the yTCuPu term, where we add the eye back in # Cu - I + I = Cu X[u] = spsolve(yTy + yTCuIY + lambda_eye, yTCupu) # Solve for Xu = ((yTy + yT(Cu-I)Y + lambda*I)^-1)yTCuPu, equation 4 from the paper # Begin iteration to solve for Y based on fixed X for i in range(num_item): conf_samp = conf[:,i].T.toarray() # transpose to get it in row format and convert to dense pref = conf_samp.copy() pref[pref != 0] = 1 # Create binarized preference vector CiI = sparse.diags(conf_samp, [0]) # Get Ci - I term, don't need to subtract 1 since we never added it xTCiIX = X.T.dot(CiI).dot(X) # This is the xT(Cu-I)X term xTCiPi = X.T.dot(CiI + X_eye).dot(pref.T) # This is the xTCiPi term Y[i] = spsolve(xTx + xTCiIX + lambda_eye, xTCiPi) # Solve for Yi = ((xTx + xT(Cu-I)X) + lambda*I)^-1)xTCiPi, equation 5 from the paper # End iterations return X, Y.T # Transpose at the end to make up for not being transposed at the beginning.
def solve_Nullspace(A12, A21, A10, A13, h0, eta, n_exp, qk, hk, d, NP, nulldata, auxdata, headloss): '''Based on the work of Edo Abraham, Imperial College London, 2014''' if headloss == 'D-W': Viscos = DW_water_constants() pD = auxdata['D'] # Pipe Diameters pR = auxdata['C'] # Pipe Roughness pL = auxdata['L'] # Pipe Length ResCoeff = auxdata['ResCoeff'] CL = auxdata['closed_pipes'] if len(CL) > 0: CLmask = np.ones(NP, dtype=bool) CLmask[CL] = False A12 = A12[CLmask, :] A21 = A12.T A10 = A10[CLmask, :] NP = NP - len(CL) A13 = A13[CLmask, :] ResCoeff = ResCoeff[CLmask, :] qk = qk[CLmask, :] if headloss == 'D-W': pD = pD[CLmask, :] pR = pR[CLmask, :] pL = pL[CLmask, :] x = nulldata['x'] Z = nulldata['Z'] P_r = nulldata['Pr'] L_A12 = nulldata['L_A12'] CONDS = 1 ERRORS = 1 max_iter = auxdata['max_iter'] tol = auxdata['tol_err'] kappa = auxdata['kappa'] Method = 'standard' if A13.shape[1] == 0: eta = np.zeros((1, 1)) A13 = sp.csc_matrix((NP, 1)) elif len(eta) == 0 and 'TargetNodes' in auxdata: Method = 'fix_headTarget' TargetNodes = auxdata['TargetNodes'] h_target = auxdata['h_target'] valves = auxdata['valves'] eta = np.zeros((len(TargetNodes), 1)) # calculate G (and constants for D-W) if headloss == 'D-W': cc, ResCoeff_LAMIflow, K = DW_constants(Viscos, pL, pD) ResCoeff = np.zeros((NP, 1)) G = np.zeros((NP, 1)) Fdiag = np.ones((NP, 1)) alpha, beta = DW_cubic_spline(pR, pD) # cubic interpolating spline G, Fdiag = DW_flow(pD, pR, Viscos, cc, qk, alpha, beta, ResCoeff_LAMIflow, K, G, Fdiag) elif headloss == 'H-W': G = ResCoeff[:, np.newaxis] * abs(qk) ** (n_exp - 1) # calculate initial error err1 = np.linalg.norm( np.vstack((G * qk + A12 @ hk + A10 @ h0 + A13 @ eta, A21 @ qk - d)), ord=np.inf) nc = Z.shape[1] # nnz_ZZ = (Z.T @ sp.eye(NP) @ Z).count_nonzero() ZT = Z.T # Fdiag_old = sp.csc_matrix((NP, 1)) # X = sp.csc_matrix((nc, nc)) updates = np.arange(NP) n_upd = len(updates) for kk in range(max_iter): if headloss == 'H-W': Fdiag = n_exp * G sigma_max = np.max(Fdiag) t_k = np.maximum((sigma_max / kappa) - Fdiag, 0) Fdiag = Fdiag + t_k X = ZT @ sp.spdiags(Fdiag.T, [0], n_upd, n_upd) @ Z b = ZT @ ((Fdiag - G) * qk - A10 @ h0 - A13 @ eta - Fdiag * x[:, np.newaxis]) v = spla.spsolve(X, b) q = x[:, np.newaxis] + Z @ v[:, np.newaxis] b = A21 @ ((Fdiag - G) * qk - A10 @ h0 - A13 @ eta - Fdiag * q) y = spla.spsolve(L_A12, P_r @ b) h = P_r.T * spla.spsolve(L_A12.T, y) if headloss == 'D-W': G, Fdiag = DW_flow(pD, pR, Viscos, cc, q, alpha, beta, ResCoeff_LAMIflow, K, G, Fdiag) elif headloss == 'H-W': G[updates] = ResCoeff[updates, np.newaxis] * abs(q[updates]) ** (n_exp - 1) if Method == 'fix_headTarget': h_ideal = h h_ideal[TargetNodes] = h_target if headloss == 'H-W': eta = -A12[valves, :] @ h_ideal - A10[valves, :] @ h0 - q[valves] * ResCoeff[valves, :] * abs( q[valves]) ** (n_exp - 1) elif headloss == 'D-W': eta = -A12[valves, :] @ h_ideal - A10[valves, :] @ h0 - G[valves] * q[valves] err1 = np.linalg.norm(np.vstack( (G * q + A12 @ h[:, np.newaxis] + A10 @ h0 + A13 @ eta, A21 @ q - d)),ord=np.inf) ERRORS = err1 if err1 < tol: break else: qk = q if len(CL) > 0: qorig = np.zeros((len(CL) + NP, 1)) s = set(CL) qorig[[x for x in np.arange(len(CL) + NP) if x not in s]] = q q = qorig check = int(ERRORS > tol) return q.flatten(), h, err1, kk, CONDS, check
print 'Solving with:', ksp.getType() # Solve! tic() ksp.solve(bb, x) SolTime[xx - 1] = toc() print "time to solve: ", SolTime[xx - 1] del AA, As if (Solving == 'Iterative'): if (UseExactSchur == 'yes'): Aschur = As[0:Vdim[xx - 1][0], 0:Vdim[xx - 1][0]] Bschur = As[Vdim[xx - 1][0]:, 0:Vdim[xx - 1][0]] Btschur = As[0:Vdim[xx - 1][0], Vdim[xx - 1][0]:] AinvB = slinalg.spsolve(Aschur, Btschur) schur = Bschur * AinvB PP = sps.block_diag((Aschur, schur)) PP = PP.tocsr() P = PETSc.Mat().createAIJ(size=PP.shape, csr=(PP.indptr, PP.indices, PP.data)) ksp = PETSc.KSP().create() pc = PETSc.PC().create() ksp.setFromOptions() ksp.setTolerances(1e-10) print 'Solving with:', ksp.setType('minres') # ksp.setPCSide(2) pc = ksp.getPC() pc.setOperators(P)
def topop_numpy(nelx, nely, loads, supports, volfrac=0.5, penal=3, rmin=1.5, callback=None): """Topology optimisation in 2D. Parameters ---------- nelx : int Number of elements in x. nely : int Number of elements in y. loads : dict {'i-j': [Px, Py]}. supports : dict {'i-j': [Bx, By]} 1=fixed, 0=free. volfrac : float Volume fraction. penal : float Penalisation power. rmin : float Filter radius. Returns ------- array Density array. Examples -------- >>> """ if callback and not callable(callback): raise Exception("The provided callback is not callable.") nx = nelx + 1 ny = nely + 1 nn = nx * ny ne = nelx * nely ndof = 2 * nn dv = ones((nely, nelx)) # Finite element analysis v = 0.3 E = 1. Emin = 10**(-10) A11 = array([[12, +3, -6, -3], [+3, 12, +3, +0], [-6, +3, 12, -3], [-3, +0, -3, 12]]) A12 = array([[-6, -3, +0, +3], [-3, -6, -3, -6], [+0, -3, -6, +3], [+3, -6, +3, -6]]) B11 = array([[-4, +3, -2, +9], [+3, -4, -9, +4], [-2, -9, -4, -3], [+9, +4, -3, -4]]) B12 = array([[+2, -3, +4, -9], [-3, +2, +9, -2], [+4, +9, +2, +3], [-9, -2, +3, +2]]) A21 = A12.transpose() B21 = B12.transpose() A = vstack([hstack([A11, A12]), hstack([A21, A11])]) B = vstack([hstack([B11, B12]), hstack([B21, B11])]) Ke = 1 / (1 - v**2) / 24 * (A + v * B) Ker = ravel(Ke, order='F')[:, newaxis] nodes = reshape(range(1, nn + 1), (ny, nx), order='F') eVec = tile(reshape(2 * nodes[:-1, :-1], (ne, 1), order='F'), (1, 8)) edof = eVec + tile( hstack( [array([0, 1]), 2 * nely + array([2, 3, 0, 1]), array([-2, -1])]), (ne, 1)) iK = reshape(kron(edof, ones((8, 1))).transpose(), (64 * ne), order='F') jK = reshape(kron(edof, ones((1, 8))).transpose(), (64 * ne), order='F') # Supports U = zeros((ndof, 1)) fixed = [] for support, B in supports.items(): jb, ib = [int(i) for i in support.split('-')] Bx, By = B node = int(jb * ny + ib) if Bx: fixed.append(2 * node) if By: fixed.append(2 * node + 1) free = list(set(range(ndof)) - set(fixed)) # Loads data = [] rows = [] cols = [] for load, P in loads.items(): jp, ip = [int(i) for i in load.split('-')] Px, Py = P node = int(jp * ny + ip) data.extend([Px, Py]) rows.extend([2 * node, 2 * node + 1]) cols.extend([0, 0]) F = coo_matrix((data, (rows, cols)), shape=(ndof, 1)) Find = F.tocsr()[free] # Filter iH = zeros(ne * (2 * (int(ceil(rmin)) - 1) + 1)**2, dtype=int64) jH = zeros(iH.shape, dtype=int64) sH = zeros(iH.shape) k = 0 for i1 in range(nelx): max_i = int(max([i1 - (ceil(rmin) - 1), 0])) min_i = int(min([i1 + (ceil(rmin) - 1), nelx - 1])) for j1 in range(nely): max_j = int(max([j1 - (ceil(rmin) - 1), 0])) min_j = int(min([j1 + (ceil(rmin) - 1), nely - 1])) e1 = i1 * nely + j1 for i2 in range(max_i, min_i + 1): for j2 in range(max_j, min_j + 1): k += 1 e2 = i2 * nely + j2 iH[k] = e1 jH[k] = e2 sH[k] = max([0, rmin - sqrt((i1 - i2)**2 + (j1 - j2)**2)]) H = coo_matrix((sH, (iH, jH))) Hs = sum(H.toarray(), 1) # Main loop iteration = 0 change = 1 move = 0.2 x = tile(volfrac, (nely, nelx)) xP = x * 1. nones = ones((ne)) * 0.001 while change > 0.1: # FE xrav = ravel(xP, order='F').transpose() sK = reshape(Ker * (Emin + xrav**penal * (E - Emin)), (64 * ne), order='F') K = coo_matrix( (sK, (asarray(iK, dtype=int64), asarray(jK, dtype=int64)))).tocsr() Kind = (K.tocsc()[:, free]).tocsr()[free, :] U[free] = spsolve(Kind, Find)[:, newaxis] # Objective function ce = reshape(sum(dot(squeeze(U[edof]), Ke) * squeeze(U[edof]), 1), (nely, nelx), order='F') c = sum(sum((Emin + xP**penal * (E - Emin)) * ce)) dc = -penal * (E - Emin) * xP**(penal - 1) * ce xdc = squeeze(H.dot(ravel(x * dc, order='F')[:, newaxis])) dc = reshape(xdc / Hs / maximum(nones, ravel(x, order='F')), (nely, nelx), order='F') # Lagrange mulipliers l1 = 0 l2 = 10**9 while (l2 - l1) / (l1 + l2) > 0.001: lmid = 0.5 * (l2 + l1) sdv = sqrt(-dc / dv / lmid) min1 = minimum(x + move, x * sdv) xn = maximum(0, maximum(x - move, minimum(1, min1))) xP = xn * 1. if sum(xP) > volfrac * ne: l1 = lmid else: l2 = lmid change = max(abs(xn - x)) # Update x = xn * 1. iteration += 1 print('Iteration: {0} Compliance: {1:.4g}'.format(iteration, c)) if callback: callback(x) return x
def run_varsat(L, T, dz, dts, h_init, bc, q, soil_carac, PICmax = 500, CRIT_CONV = 1e-3): # L : column length # T : simulation duration # dz : vertical discretization # dts : time step, which may be constant or variable. In the latter case, we must have : np.cumsum(dts) = T # h_init : initial profile of pressure head, must be of size I = int(round(L/dz)) # bc : dictionary of boundary conditions : e.g. {'top':['fixed_head',[h_top]*N],'bot':['fixed_head',[h_bot]*N]} # allowed bc at the top : 'fixed_head','fixed_flow', # allowed bc at the bottom : 'fixed_head','fixed_flow','free_drainage' # q : source term. May be constant homogeneous (scalar), constant (size I array), variable in space and time (size I*N array) # soil_carac : e.g. soil_carac = {'Ksat':1e-4, 'Ss':0, 'eta':0.368, 'theta_r' : 0.102, 'theta_s' : 0.368, 'n':2, 'alpha':3.35} # PICmax : maximum number of Picard iteration # CRIT_CONV : convergence criteria. # -- model initialization # init vars if hasattr(dts,"__len__") == False: dts = np.array( [dts] * int(round(T/dts)) ) t = np.cumsum(dts) # time array N = len(dts) # number of time steps I = int(round(L/dz)) # number of cells z = np.linspace(0,L,I) # z coordinates of nodes # check h_init if len(h_init) != I: print('ERROR: check dimension of h_init') return(0,0,0) # check q (not fully implemented) if hasattr(q,"__len__") == False: # constant and homogeneous q q = np.array( [ [q] * N] * I ) elif np.array(q).shape == (I,) : # transient homogeneous q q = np.transpose(np.array( [list(q)]*N ) ) # -- check input data # check bc : if bc['top'][0] not in ['fixed_head','fixed_flow','free_drainage'] : print('ERROR: check top boundary condition') if bc['bot'][0] not in ['fixed_head','fixed_flow','free_drainage'] : print('ERROR: check bottom boundary condition') # -- run initization # initialize output matrices S=np.mat(np.zeros(shape=(I,N))) # Store initial condition S[:,0]= np.transpose(np.mat(h_init)) h = h0 = h_init h_list = [] # iterate over time for n in range(1,N): dt = dts[n] theta0 = get_theta(h0,soil_carac) # Picard iteration for m in range(PICmax): M , B = build_system(h0, h, theta0 , bc, q, soil_carac, n) # solver linear system #h1 =np.linalg.solve(M, B)[:,0] h1 = np.transpose(np.matrix(spsolve(csr_matrix(M),B))) #h1 = np.transpose(np.matrix(cg(csr_matrix(M),B)[0])) if np.max(h1-h) < CRIT_CONV: print('PIC iteration = '+ str(m)) h = h1 break h = h1 h0 = h S[:,n] = np.mat(h) print('iteration ' + str(n) + ' terminated.') # return simulation results return(t,z,S)