def align_magnetism(m, vectors): """ Rotates a matrix, to align its components with the direction of the magnetism """ if not len(m) == 2 * len(vectors): # stop if they don't have # compatible dimensions raise # pauli matrices from scipy.sparse import csc_matrix, bmat sx = csc_matrix([[0.0, 1.0], [1.0, 0.0]]) sy = csc_matrix([[0.0, -1j], [1j, 0.0]]) sz = csc_matrix([[1.0, 0.0], [0.0, -1.0]]) n = len(m) / 2 # number of sites R = [[None for i in range(n)] for j in range(n)] # rotation matrix from scipy.linalg import expm # exponenciate matrix for (i, v) in zip(range(n), vectors): # loop over sites vv = np.sqrt(v.dot(v)) # norm of v if vv > 0.000001: # if nonzero scale u = v / vv else: # if zero put to zero u = np.array([0.0, 0.0, 0.0]) # rot = u[0]*sx + u[1]*sy + u[2]*sz uxy = np.sqrt(u[0] ** 2 + u[1] ** 2) # component in xy plane phi = np.arctan2(u[1], u[0]) theta = np.arctan2(uxy, u[2]) r1 = phi * sz / 2.0 # rotate along z r2 = theta * sy / 2.0 # rotate along y # a factor 2 is taken out due to 1/2 of S rot = expm(1j * r2) * expm(1j * r1) R[i][i] = rot # save term R = bmat(R) # convert to full sparse matrix mout = R * csc_matrix(m) * R.H # rotate matrix return mout.todense() # return dense matrix
def PETScAssemble(FS, A, b, opt = 'Matrix'): if str(FS.__class__).find('dict') != -1: if opt == 'Matrix': if A.has_key('C') == True: Aout = PETScMatOps.Scipy2PETSc(bmat([[A['A'],A['B'].T], [A['B'],A['C']]])) common.StoreMatrix(bmat([[A['A'],A['B'].T], [A['B'],A['C']]]),'A') else: Aout = PETScMatOps.Scipy2PETSc(bmat([[A['A'],A['B'].T], [A['B'],None]])) else: for key, value in A.iteritems(): A[key] = PETScMatOps.Scipy2PETSc(value) Aout = PETSc.Mat().createPython([FS.keys()[0] + FS.keys()[1], FS.keys()[0] + FS.keys()[1]]) Aout.setType('python') p = MHDmulti.MHDmat(W,A) Aout.setPythonContext(p) b = PETScMatOps.arrayToVec(b) else: Aout, b = PETScMatOps.Assemble(A,b) print b.array ssss return Aout, b
def add_pairing(deltas=[[0.,0],[0.,0.]],is_sparse=True,r1=[],r2=[]): """ Adds a general pairing in real space""" def get_pmatrix(r1i,r2j): # return the different pairings if callable(deltas): dv = deltas(r1i,r2j) # get the components else: dv = deltas duu = dv[0,1] # delta up up ddd = dv[1,0] # delta dn dn dud = dv[0,0] # delta up dn ddu = dv[1,1] # delta up dn # be aware of the minus signs coming from the definition of the # Nambu spinor!!!!!!!!!!!!!!!!! # c_up d_dn d^\dagger_dn -d^\dagger_up D = csc_matrix([[dud,duu],[ddd,ddu]]) # SC matrix # D = bmat([[None,D],[-D.H,None]]) # the minus sign comes from triplet return D # superconducting coupling n = len(r1) # number of sites pout = [[None for i in range(n)] for j in range(n)] # initialize None matrix # zeros in the diagonal # for i in range(n): bout[i][i] = csc_matrix(np.zeros((4,4),dtype=np.complex)) for i in range(n): # loop over sites for j in range(n): # loop over sites pout[i][j] = get_pmatrix(r1[i],r2[j]) # get this pairing diag = csc_matrix(np.zeros((2*len(r1),2*len(r1)),dtype=np.complex)) # diag pout = bmat(pout) # convert to block matrix # mout = [[diag,pout],[np.conjugate(pout),diag]] # output matrix mout = [[diag,pout],[None,diag]] # output matrix # mout = [[diag,pout],[pout,diag]] # output matrix mout = bmat(mout) # return full matrix mout = reorder(mout) # reorder the entries return mout
def solve_qp_constrained(P,q,nlabel,x0,**kwargs): import solver_qp_constrained as solver reload(solver) ## constrained solver nvar = q.size npixel = nvar/nlabel F = sparse.bmat([ [sparse.bmat([[-sparse.eye(npixel,npixel) for i in range(nlabel-1)]])], [sparse.eye(npixel*(nlabel-1),npixel*(nlabel-1))], ]) ## quadratic objective objective = solver.ObjectiveAPI(P, q, G=1, h=0, F=F,**kwargs) ## log barrier solver t0 = kwargs.pop('logbarrier_initial_t',1.0) mu = kwargs.pop('logbarrier_mu',20.0) epsilon = kwargs.pop('logbarrier_epsilon',1e-3) solver = solver.ConstrainedSolver( objective, t0=t0, mu=mu, epsilon=epsilon, ) ## remove zero entries in initial guess xinit = x0.reshape((-1,nlabel),order='F') xinit[xinit<1e-10] = 1e-3 xinit = (xinit/np.c_[np.sum(xinit, axis=1)]).reshape((-1,1),order='F') x = solver.solve(xinit, **kwargs) return x
def compute_search_direction(self,useH): fdata = self.fdata problem = self.problem barrier = self.barrier sigma = self.sigma theta = self.theta problem.combine_H(-sigma*self.nu+problem.f,not useH) self.code[0] = 'h' if useH else 'g' Hfsigma = problem.H_combined/sigma Hphi = fdata.Hphi HphiB = fdata.HphiB G = coo_matrix((np.concatenate((Hphi.data,theta*HphiB.data,Hfsigma.data)), (np.concatenate((Hphi.row,HphiB.row,Hfsigma.row)), np.concatenate((Hphi.col,HphiB.col,Hfsigma.col))))) if problem.A.size: W = bmat([[G,None,None], [problem.J,-sigma*self.Iff,None], [problem.A,None,-sigma*self.Iaa]]) else: W = bmat([[G,None], [problem.J,-sigma*self.Iff]]) b = np.hstack((-fdata.GradF/sigma, self.of, self.oa)) if not self.linsolver1.is_analyzed(): self.linsolver1.analyze(W) return self.linsolver1.factorize_and_solve(W,b)[:self.x.size]
def honeycomb2squareMoS2(h,check=True): """Transforms a honeycomb lattice into a square lattice""" ho = deepcopy(h) # output geometry g = h.geometry # geometry go = deepcopy(g) # output geometry go.a1 = g.a1 + g.a2 go.a2 = g.a1 - g.a2 # now put the first vector along the x axis go.r = np.concatenate([g.r,g.r + g.a1]) go.r2xyz() go = sculpt.rotate_a2b(go,go.a1,np.array([1.,0.,0.])) # perform a check to see if the supercell is well built a1a2 = go.a1.dot(go.a2) # if a1a2>0.001: if np.abs(go.a1)[1]>0.001 or np.abs(go.a2[0])>0.001: ang = go.a1.dot(go.a2) print("The projection of lattice vectors is",ang) if check: raise go.r2xyz() # update r atribbute zero = csc(h.tx*0.) # define sparse intra = csc(h.intra) tx = csc(h.tx) ty = csc(h.ty) txy = csc(h.txy) txmy = csc(h.txmy) # define new hoppings ho.intra = bmat([[intra,tx],[tx.H,intra]]).todense() ho.tx = bmat([[txy,zero],[ty,txy]]).todense() ho.ty = bmat([[txmy,zero],[ty.H,txmy]]).todense() ho.txy = bmat([[zero,zero],[tx,zero]]).todense() ho.txmy = bmat([[zero,zero],[zero,zero]]).todense() ho.geometry = go return ho
def rashba(r1,r2=None,c=0.,d=[0.,0.,1.],is_sparse=False): """ Add Rashba coupling, returns a spin polarized matrix This will assume only Rashba between first neighbors """ zero = coo_matrix([[0.,0.],[0.,0.]]) if r2 is None: r2 = r1 nat = len(r1) # number of atoms m = [[None for i in range(nat)] for j in range(nat)] # create matrix for i in range(nat): m[i][i] = zero.copy() # initilize neighs = neighbor.connections(r1,r2) # neighbor connections for i in range(nat): # loop over first atoms # for j in range(nat): # loop over second atoms for j in neighs[i]: # loop over second atoms rij = r2[j] - r1[i] # x component dx,dy,dz = rij[0],rij[1],rij[2] # different components rxs = [dy*sz-dz*sy,dz*sx-dx*sz,dx*sy-dy*sx] # cross product ms = 1j*(d[0]*rxs[0] + d[1]*rxs[1] + d[2]*rxs[2]) # E dot r times s s = 0.0*ms if 0.9<(rij.dot(rij))<1.1: # if nearest neighbor if callable(c): s = ms*c((r1[i]+r2[j])/2.) # function else:s = ms*c # multiply m[i][j] = s # rashba term if not is_sparse: m = bmat(m).todense() # to normal matrix else: m = bmat(m) # sparse matrix return m
def block2full(ht,sparse=False): """Convert a heterostructure with block diagonal Hamiltonian into the full form""" if not ht.block_diagonal: return ht # stop ho = ht.copy() ho.block_diagonal = False # set in false from now on nb = len(ht.central_intra) # number of blocks lc = [csc_matrix(ht.central_intra[i][i].shape) for i in range(nb)] rc = [csc_matrix(ht.central_intra[i][i].shape) for i in range(nb)] lc[0] = csc_matrix(ht.left_coupling) rc[nb-1] = csc_matrix(ht.right_coupling) # convert the central to sparse form central = [[None for i in range(nb)] for j in range(nb)] for i in range(nb): for j in range(nb): if ht.central_intra[i][j] is None: continue else: central[i][j] = csc_matrix(ht.central_intra[i][j]) from scipy.sparse import vstack if sparse: ho.left_coupling = vstack(lc) ho.right_coupling = vstack(rc) ho.central_intra = bmat(ht.central_intra) # as sparse matrix else: ho.left_coupling = vstack(lc).todense() ho.right_coupling = vstack(rc).todense() ho.central_intra = bmat(central).todense() # as dense matrix return ho
def compute_search_direction(self,useH): problem = self.problem fdata = self.fdata miu = np.maximum(self.miu,1e-8) if useH: problem.combine_H(-miu*self.nu+problem.f,False) # exact Hessian self.code[0] = 'h' else: problem.combine_H(-miu*self.nu+problem.f,True) # ensure pos semidef self.code[0] = 'g' Hfmiu = problem.H_combined/miu Hphi = problem.Hphi G = coo_matrix((np.concatenate((Hphi.data,Hfmiu.data)), (np.concatenate((Hphi.row,Hfmiu.row)), np.concatenate((Hphi.col,Hfmiu.col))))) if problem.A.size: W = bmat([[G,None,None], [problem.J,-miu*self.Iff,None], [problem.A,None,-miu*self.Iaa]]) else: W = bmat([[G,None], [problem.J,-miu*self.Iff]]) b = np.hstack((-fdata.GradF/self.miu, self.of, self.oa)) if not self.linsolver1.is_analyzed(): self.linsolver1.analyze(W) return self.linsolver1.factorize_and_solve(W,b)[:self.x.size]
def interface_multienergy(h1,h2,k=[0.0,0.,0.],energies=[0.0],delta=0.01, dh1=None,dh2=None): """Get the Green function of an interface""" from scipy.sparse import csc_matrix as csc from scipy.sparse import bmat fun1 = green_kchain_evaluator(h1,k=k,delta=delta,hs=None, only_bulk=False,reverse=True) # surface green function fun2 = green_kchain_evaluator(h2,k=k,delta=delta,hs=None, only_bulk=False,reverse=False) # surface green function out = [] # output for energy in energies: # loop gs1,sf1 = fun1(energy) gs2,sf2 = fun2(energy) ############# ## 1 C 2 ## ############# # Now apply the Dyson equation (ons1,hop1) = get1dhamiltonian(h1,k,reverse=True) # get 1D Hamiltonian (ons2,hop2) = get1dhamiltonian(h2,k,reverse=False) # get 1D Hamiltonian havg = (hop1.H + hop2)/2. # average hopping if dh1 is not None: ons1 = ons1 + dh1 if dh2 is not None: ons2 = ons2 + dh2 ons = bmat([[csc(ons1),csc(havg)],[csc(havg.H),csc(ons2)]]) # onsite self2 = bmat([[csc(ons1)*0.0,None],[None,csc(hop2@[email protected])]]) self1 = bmat([[csc(hop1@[email protected]),None],[None,csc(ons2)*0.0]]) # Dyson equation ez = (energy+1j*delta)*np.identity(ons1.shape[0]+ons2.shape[0]) # energy ginter = (ez - ons - self1 - self2).I # Green function # now return everything, first, second and hybrid out.append([gs1,sf1,gs2,sf2,ginter]) return out # return output
def supercell(h,nsuper,sparse=False): """ Get a supercell of the system, h is the hamiltonian nsuper is the number of replicas """ from scipy.sparse import csc_matrix as csc from scipy.sparse import bmat from copy import deepcopy hout = deepcopy(h) # output hamiltonian intra = csc(h.intra) # intracell matrix inter = csc(h.inter) # intercell matrix # crease supercells block matrices intra_super = [[None for i in range(nsuper)] for j in range(nsuper)] inter_super = [[None for i in range(nsuper)] for j in range(nsuper)] for i in range(nsuper): # onsite part intra_super[i][i] = intra inter_super[i][i] = 0.0*intra for i in range(nsuper-1): # inter minicell part intra_super[i][i+1] = inter intra_super[i+1][i] = inter.H inter_super[nsuper-1][0] = inter # inter supercell part inter_super[0][nsuper-1] = inter.H # inter supercell part # create dense matrices if not sparse: intra_super = bmat(intra_super).todense() inter_super = bmat(inter_super).todense() # add to the output hamiltonian hout.intra = intra_super hout.inter = inter_super import geometry hout.geometry = h.geometry.supercell(nsuper) return hout
def __mul__(u, v): """Hadamard product u*v.""" if isinstance(v, ADI): if len(u.val) == len(v.val): # Note: scipy.sparse.diags has changed parameters between # versions 0.16x and 0.17x. This code is only tested on 0.16x. # TODO test code in SciPy 0.17x uJv = [sps.diags([u.val.flat],[0])*jv for jv in v.jac] # MATRIX multiplication vJu = [sps.diags([v.val.flat],[0])*ju for ju in u.jac] # MATRIX multiplication jac = [a+b for (a,b) in zip(uJv, vJu)] return ADI(u.val*v.val, jac) if len(v.val) == 1: # Fix dimensions and recurse vval = np.tile(v.val, (u.val.shape[0],1) ) vjac = [sps.bmat([[j]]*len(u.val)) for j in v.jac] return u.__mul__(ADI(vval, vjac)) if len(u.val) == 1: # Fix dimensions and recurse uval = np.tile(u.val, (v.val.shape[0],1) ) ujac = [sps.bmat([[j]]*len(v.val)) for j in u.jac] return ADI(uval, ujac).__mul__(v) raise ValueError("Dimension mismatch") else: v = np.atleast_2d(v) if len(u.val) == 1: val = u.val * v jac = [sps.diags(v.flat,0)*sps.bmat([[j]]*len(v)) for j in u.jac] return ADI(val, jac) if len(v) == 1: return ADI(u.val*v, [v.flat[0]*ju for ju in u.jac]) if len(u.val) == len(v): vJu = [sps.diags(v.flat, 0)*ju for ju in u.jac] # MATRIX multiplication return ADI(u.val*v, vJu) raise ValueError("Dimension mismatch")
def get_problem_for_Q(self,p,r): """ Constructs second-stage quadratic problem in the form minimize(x) (1/2)x^THx + g^Tx subject to Ax = b l <= x <= u, where x = (q,w,s,z). Parameters ---------- p : generator powers r : renewable powers Returns ------- problem : QuadProblem """ # Constatns num_p = self.num_p num_w = self.num_w num_r = self.num_r num_bus = self.num_bus num_br = self.num_br Ow = coo_matrix((num_w,num_w)) Os = coo_matrix((num_r,num_r)) Oz = coo_matrix((num_br,num_br)) Iz = eye(num_br,format='coo') ow = np.zeros(num_w) os = np.zeros(num_r) oz = np.zeros(num_br) cost_factor = self.parameters['cost_factor'] H1 = self.H1/cost_factor g1 = self.g1/cost_factor # Form QP problem H = bmat([[H1,None,None,None], # q: gen power adjustments [None,Ow,None,None], # w: bus voltage angles [None,None,Os,None], # s: curtailed renewable powers [None,None,None,Oz]], # z: slack variables for thermal limits format='coo') g = np.hstack((g1,ow,os,oz)) A = bmat([[self.G,-self.A,self.R,None], [None,self.J,None,-Iz]],format='coo') b = np.hstack((self.b-self.G*p,oz)) l = np.hstack((self.p_min-p, self.w_min, os, self.z_min)) u = np.hstack((self.p_max-p, self.w_max, r, self.z_max)) # Return return QuadProblem(H,g,A,b,l,u)
def add_zeeman(h,zeeman=[0.0,0.0,0.0]): """ Add Zeeman to the hamiltonian """ from scipy.sparse import coo_matrix as coo from scipy.sparse import bmat if h.has_spin: # only if the system has spin sx = coo([[0.0,1.0],[1.0,0.0]]) # sigma x sy = coo([[0.0,-1j],[1j,0.0]]) # sigma y sz = coo([[1.0,0.0],[0.0,-1.0]]) # sigma z no = h.num_orbitals # number of orbitals (without spin) # create matrix to add to the hamiltonian bzee = [[None for i in range(no)] for j in range(no)] # assign diagonal terms if not callable(zeeman): # if it is a number for i in range(no): bzee[i][i] = zeeman[0]*sx+zeeman[1]*sy+zeeman[2]*sz elif callable(zeeman): # if it is a function x = h.geometry.x # x position y = h.geometry.y # y position for i in range(no): z = zeeman(x[i],y[i]) # get the value of the zeeman bzee[i][i] = z[0]*sx+z[1]*sy+z[2]*sz else: raise bzee = bmat(bzee) # create matrix if h.has_eh: # if electron hole, double the dimension bzee = bmat([[bzee,None],[None,-bzee]]) bzee = bzee.todense() # create dense matrix h.intra = h.intra + bzee if not h.has_spin: # still have to implement this... raise
def bulk2ribbon(h,n=10): """Converts a hexagonal bulk hamiltonian into a ribbon hamiltonian""" go = h.geometry.copy() # copy geometry ho = h.copy() # copy hamiltonian ho.dimensionality = 1 # reduce dimensionality ho.geometry.dimensionality = 1 # reduce dimensionality intra = [[None for i in range(n)] for j in range(n)] inter = [[None for i in range(n)] for j in range(n)] for i in range(n): # to the the sam index intra[i][i] = csc(h.intra) inter[i][i] = csc(h.tx) for i in range(n-1): # one more or less intra[i][i+1] = csc(h.ty) intra[i+1][i] = csc(h.ty.H) inter[i+1][i] = csc(h.txmy) inter[i][i+1] = csc(h.txy) ho.intra = bmat(intra).todense() ho.inter = bmat(inter).todense() # calculate the angle import sculpt go = sculpt.rotate_a2b(go,go.a1,np.array([1.,0.,0.])) ho.geometry.celldis = go.a1[0] # first eigenvector r = [] for i in range(n): for ri in go.r: r.append(ri+i*go.a2) ho.geometry.r = np.array(r) ho.geometry.r2xyz() # get r positions return ho
def honeycomb2square(h): """Transforms a honeycomb lattice into a square lattice""" ho = deepcopy(h) # output geometry g = h.geometry # geometry go = deepcopy(g) # output geometry go.a1 = - g.a1 - g.a2 go.a2 = g.a1 - g.a2 go.x = np.concatenate([g.x,g.x-g.a1[0]]) go.y = np.concatenate([g.y,g.y-g.a1[1]]) go.z = np.concatenate([g.z,g.z]) go.xyz2r() # update r atribbute zero = csc(h.tx*0.) # define sparse intra = csc(h.intra) tx = csc(h.tx) ty = csc(h.ty) txy = csc(h.txy) txmy = csc(h.txmy) # define new hoppings ho.intra = bmat([[intra,tx.H],[tx,intra]]).todense() ho.tx = bmat([[txy.H,zero],[ty.H,txy.H]]).todense() ho.ty = bmat([[txmy,ty.H],[txmy,zero]]).todense() ho.txy = bmat([[zero,None],[None,zero]]).todense() ho.txmy = bmat([[zero,zero],[tx.H,zero]]).todense() ho.geometry = go return ho
def __init__(self, U, Y, statedim, reg=None): if size(shape(U)) == 1: U = reshape(U, (-1,1)) if size(shape(Y)) == 1: Y = reshape(Y, (-1,1)) if reg is None: reg = 0 yDim = size(Y,1) uDim = size(U,1) self.output_size = size(Y,1) # placeholder # number of samples of past/future we'll mash together into a 'state' width = 1 # total number of past/future pairings we get as a result K = size(U,0) - 2 * width + 1 # build hankel matrices containing pasts and futures U_p = array([ravel(U[t : t + width]) for t in range(K)]).T U_f = array([ravel(U[t + width : t + 2 * width]) for t in range(K)]).T Y_p = array([ravel(Y[t : t + width]) for t in range(K)]).T Y_f = array([ravel(Y[t + width : t + 2 * width]) for t in range(K)]).T # solve the eigenvalue problem YfUfT = dot(Y_f, U_f.T) YfUpT = dot(Y_f, U_p.T) YfYpT = dot(Y_f, Y_p.T) UfUpT = dot(U_f, U_p.T) UfYpT = dot(U_f, Y_p.T) UpYpT = dot(U_p, Y_p.T) F = bmat([[None, YfUfT, YfUpT, YfYpT], [YfUfT.T, None, UfUpT, UfYpT], [YfUpT.T, UfUpT.T, None, UpYpT], [YfYpT.T, UfYpT.T, UpYpT.T, None]]) Ginv = bmat([[pinv(dot(Y_f,Y_f.T)), None, None, None], [None, pinv(dot(U_f,U_f.T)), None, None], [None, None, pinv(dot(U_p,U_p.T)), None], [None, None, None, pinv(dot(Y_p,Y_p.T))]]) F = F - eye(size(F, 0)) * reg # Take smallest eigenvalues _, W = eigs(Ginv.dot(F), k=statedim, which='SR') # State sequence is a weighted combination of the past W_U_p = W[ width * (yDim + uDim) : width * (yDim + uDim + uDim), :] W_Y_p = W[ width * (yDim + uDim + uDim):, :] X_hist = dot(W_U_p.T, U_p) + dot(W_Y_p.T, Y_p) # Regress; trim inputs to match the states we retrieved R = concatenate((X_hist[:, :-1], U[width:-width].T), 0) L = concatenate((X_hist[:, 1: ], Y[width:-width].T), 0) RRi = pinv(dot(R, R.T)) RL = dot(R, L.T) Sys = dot(RRi, RL).T self.A = Sys[:statedim, :statedim] self.B = Sys[:statedim, statedim:] self.C = Sys[statedim:, :statedim] self.D = Sys[statedim:, statedim:]
def eval_jac_g(x,flag): if flag: J = bmat([[problem.A],[problem.J]],format='coo') return J.row,J.col else: problem.eval(x) J = bmat([[problem.A],[problem.J]],format='coo') return J.data
def augment_plcp(plcp,scale,**kwargs): P = plcp.Phi U = plcp.U q = plcp.q (N,K) = P.shape assert((K,N) == U.shape) x = kwargs.get('x0',np.ones(N)) y = kwargs.get('y0',np.ones(N)) d = x - y proj_d = P.dot(P.T.dot(d)) err = np.linalg.norm(d - proj_d) print 'Projection residual in x-y',err #assert(err < 1e-12) assert(np.all(x > 0)) assert(np.all(y > 0)) x0 = 1 y0 = scale # b = y - Mx - q # = y - (PUx + x - PPtx) - q # = y - PUx - x + PPtx - PPtq # = PPt(y-x) + P(-Ux + Pt(x-q)) # Assuming q and y-u in the span of P d = P.T.dot(y - x) b = d + -U.dot(x) + P.T.dot(x - q) assert((K,) == b.shape) # [P 0] # [0 1] new_P = sps.bmat([[P,None], [None,np.ones((1,1))]]) # [U b] # [0 s] new_U = sps.bmat([[U,b[:,np.newaxis]], [None,scale*np.ones((1,1))]]) new_q = np.hstack([q,0]) # Pw = u - u + q = q; w = Ptq # Pw0 = x0 - y0 = 1 - scale w = np.hstack([P.T.dot(q), 1.0 - scale]) x = np.hstack([x,x0]) y = np.hstack([y,y0]) # w doesn't have to be +ve assert (N+1,K+1) == new_P.shape assert (K+1,N+1) == new_U.shape assert (N+1,) == new_q.shape assert (N+1,) == x.shape assert (N+1,) == y.shape assert (K+1,) == w.shape return ProjectiveLCPObj(new_P,new_U,new_q),x,y,w
def get_smatrix(ht,energy=0.0,delta=0.000001,as_matrix=False,check=True): """Calculate the S-matrix of an heterostructure""" # now do the Fisher Lee trick smatrix = [[None,None],[None,None]] # smatrix in list form from .green import gauss_inverse # calculate the desired green functions # get the selfenergies, using the same coupling as the lead selfl = ht.get_selfenergy(energy,delta=delta,lead=0,pristine=True) selfr = ht.get_selfenergy(energy,delta=delta,lead=1,pristine=True) if ht.block_diagonal: ht2 = enlarge_hlist(ht) # get the enlaged hlist with the leads # selfenergy of the leads (coupled to another cell of the lead) gmatrix = effective_tridiagonal_hamiltonian(ht2.central_intra,selfl,selfr, energy=energy,delta=delta) test_gauss = False # do the tridiagonal inversion # print(selfr) else: # not block diagonal gmatrix = build_effective_hlist(ht,energy=energy,delta=delta,selfl=selfl, selfr=selfr) test_gauss = True # gauss only works with square matrices # print(selfr) # gamma functions gammar = 1j*(selfr-selfr.H) gammal = 1j*(selfl-selfl.H) # calculate the relevant terms of the Green function g11 = gauss_inverse(gmatrix,0,0,test=test_gauss) g12 = gauss_inverse(gmatrix,0,-1,test=test_gauss) g21 = gauss_inverse(gmatrix,-1,0,test=test_gauss) g22 = gauss_inverse(gmatrix,-1,-1,test=test_gauss) # print("NAN",np.sum(np.isnan(g12))) # print (gammal*g12*gammar*g21).trace() ######## now build up the s matrix with the fisher trick # the identity can have different dimension ignore for now.... iden = np.matrix(np.identity(g11.shape[0],dtype=complex)) # create identity iden11 = np.matrix(np.identity(g11.shape[0],dtype=complex)) # create identity iden22 = np.matrix(np.identity(g22.shape[0],dtype=complex)) # create identity smatrix[0][0] = -iden + 1j*sqrtm(gammal)*g11*sqrtm(gammal) # matrix smatrix[0][1] = 1j*sqrtm(gammal)*g12*sqrtm(gammar) # transmission matrix smatrix[1][0] = 1j*sqrtm(gammar)*g21*sqrtm(gammal) # transmission matrix smatrix[1][1] = -iden + 1j*sqrtm(gammar)*g22*sqrtm(gammar) # matrix if check: # check whether the matrix is unitary from scipy.sparse import bmat,csc_matrix smatrix2 = [[csc_matrix(smatrix[i][j]) for j in range(2)] for i in range(2)] smatrix2 = bmat(smatrix2).todense() # print("Determinant",np.abs(np.linalg.det(smatrix2))) error = np.max(np.abs(smatrix2.I -smatrix2.H)) # check unitarity if error> 100*delta: print("S-matrix is not unitary",error) # raise if as_matrix: from scipy.sparse import bmat,csc_matrix smatrix2 = [[csc_matrix(smatrix[i][j]) for j in range(2)] for i in range(2)] smatrix = bmat(smatrix2).todense() return smatrix
def test_multiply(self): # check scalar multiplication block = self.block_m m = self.basic_m * 5.0 scipy_mat = bmat([[block, block], [None, block]], format='coo') mulscipy_mat = scipy_mat * 5.0 dinopy_mat = m.tocoo() drow = np.sort(dinopy_mat.row) dcol = np.sort(dinopy_mat.col) ddata = np.sort(dinopy_mat.data) srow = np.sort(mulscipy_mat.row) scol = np.sort(mulscipy_mat.col) sdata = np.sort(mulscipy_mat.data) self.assertListEqual(drow.tolist(), srow.tolist()) self.assertListEqual(dcol.tolist(), scol.tolist()) self.assertListEqual(ddata.tolist(), sdata.tolist()) m = 5.0 * self.basic_m dinopy_mat = m.tocoo() drow = np.sort(dinopy_mat.row) dcol = np.sort(dinopy_mat.col) ddata = np.sort(dinopy_mat.data) self.assertListEqual(drow.tolist(), srow.tolist()) self.assertListEqual(dcol.tolist(), scol.tolist()) self.assertListEqual(ddata.tolist(), sdata.tolist()) # check dot product with block vector block = self.block_m m = self.basic_m scipy_mat = bmat([[block, block], [None, block]], format='coo') x = BlockVector(2) x[0] = np.ones(block.shape[1], dtype=np.float64) x[1] = np.ones(block.shape[1], dtype=np.float64) res_scipy = scipy_mat.dot(x.flatten()) res_dinopy = m * x res_dinopy_flat = m * x.flatten() self.assertListEqual(res_dinopy.tolist(), res_scipy.tolist()) self.assertListEqual(res_dinopy_flat.tolist(), res_scipy.tolist()) dense_mat = dinopy_mat.todense() self.basic_m *= 5.0 self.assertTrue(np.allclose(dense_mat, self.basic_m.todense())) flat_mat = self.basic_m.tocoo() result = flat_mat * flat_mat dense_result = result.toarray() mat = self.basic_m * self.basic_m.tocoo() dense_mat = mat.toarray() self.assertTrue(np.allclose(dense_mat, dense_result))
def _rebuild_operators(self): ConstantDensityAcousticTimeScalar_1D._rebuild_operators(self) dof = self.mesh.dof(include_bc=True) oc = self.operator_components built = oc.get('_numpy_components_built', False) # build the static components if not built: # build laplacian oc.L = build_derivative_matrix(self.mesh, 2, self.spatial_accuracy_order) # build sigmaz sz = build_sigma(self.mesh, self.mesh.z) oc.sigmaz = make_diag_mtx(sz) # build Dz oc.Dz = build_derivative_matrix(self.mesh, 1, self.spatial_accuracy_order, dimension='z') # build other useful things oc.I = spsp.eye(dof, dof) oc.empty = spsp.csr_matrix((dof, dof)) # Stiffness matrix K doesn't change oc.K = spsp.bmat([[-oc.L, -oc.Dz], [oc.sigmaz*oc.Dz, oc.sigmaz]]) oc._numpy_components_built = True C = self.model_parameters.C oc.m = make_diag_mtx((C**-2).reshape(-1,)) C = spsp.bmat([[oc.sigmaz*oc.m, None], [None, oc.I]]) / self.dt M = spsp.bmat([[oc.m, None], [None, oc.empty]]) / self.dt**2 Stilde_inv = M+C Stilde_inv.data = 1./Stilde_inv.data self.A_k = Stilde_inv*(2*M - oc.K + C) self.A_km1 = -1*Stilde_inv*(M) self.A_f = Stilde_inv
def mat_h2_plus_old(bond_length, bspline_set, l_list): """ gives hamiltonian matrix and overlap matrix of hydrogem molecule ion Parameters ---------- bond_length : Double bond length of hydrogen molecular ion bspline_set : BSplineSet l_list: list of non negative integer list of angular quauntum number to use Returns ------- h_mat : numpy.ndarray hamiltonian matrix s_mat : numpy.ndarray overlap pmatrix """ # compute r1 matrix (B_i|O|B_j) # (-1/2 d^2/dr^2, 1, 1/r^2, {s^L/g^{L+1} | L<-l_list}) rs = bspline_set.xs d2_rmat = bspline_set.d2_mat() r2_rmat = bspline_set.v_mat(1.0/(rs*rs)) s_rmat = bspline_set.s_mat() tmp_L_list = uniq(flatten([ls_non_zero_YYY(L1, L2) for L1 in l_list for L2 in l_list])) en_r1mat_L = {} for L in tmp_L_list: en_r1mat_L[L] = bspline_set.en_mat(L, bond_length/2.0) # compute r1Y matrix (B_iY_L1M1|O|B_jY_L2M2) def one_block(L1, L2): v = -2.0*sum([sqrt(4.0*pi/(2*L+1)) * y1mat_Yqk((L1, 0), (L, 0), (L2, 0)) * en_r1mat_L[L] for L in ls_non_zero_YYY(L1, L2)]) if L1 == L2: L = L1 t = -0.5 * d2_rmat + L*(L+1)*0.5*r2_rmat return t+v else: return v H_mat = bmat([[one_block(L1, L2) for L1 in l_list] for L2 in l_list]) S_mat = bmat([[s_rmat if L1 == L2 else None for L1 in l_list] for L2 in l_list]) return (H_mat, S_mat)
def _rebuild_operators(self): dof = self.mesh.dof(include_bc=True) oc = self.operator_components built = oc.get('_numpy_components_built', False) oc.I = spsp.eye(dof, dof) # build the static components if not built: # build laplacian oc.L = build_derivative_matrix(self.mesh, 2, self.spatial_accuracy_order, use_shifted_differences=self.spatial_shifted_differences) # build sigmaz sz = build_sigma(self.mesh, self.mesh.z) oc.sigmaz = make_diag_mtx(sz) # build Dz oc.Dz = build_derivative_matrix(self.mesh, 1, self.spatial_accuracy_order, dimension='z', use_shifted_differences=self.spatial_shifted_differences) # build other useful things oc.empty = spsp.csr_matrix((dof, dof)) # Stiffness matrix K doesn't change self.K = spsp.bmat([[-oc.L, -oc.Dz], [oc.sigmaz*oc.Dz, oc.sigmaz]]) oc._numpy_components_built = True C = self.model_parameters.C oc.m = make_diag_mtx((C**-2).reshape(-1,)) self.C = spsp.bmat([[oc.sigmaz*oc.m, None], [None, oc.I]]) self.M = spsp.bmat([[oc.m, None], [None, oc.empty]]) self.dM = oc.I self.dC = oc.sigmaz self.dK = 0
def generate_prefix_dyn_cstr(G, T, init): """Generate equalities (47c), (47e) for prefix dynamics""" K = G.K() M = G.M() # variables: u[0], ..., u[T-1], x[1], ..., x[T] # Obtain system matrix B = G.system_matrix() # (47c) # T*K equalities A_eq1_u = sp.block_diag((B,) * T) A_eq1_x = sp.block_diag((sp.identity(K),) * T) b_eq1 = np.zeros(T * K) # (47e) # T*K equalities A_eq2_u = sp.block_diag((_id_stacked(K, M),) * T) A_eq2_x = sp.bmat([[sp.coo_matrix((K, K * (T - 1))), sp.coo_matrix((K, K))], [sp.block_diag((sp.identity(K),) * (T - 1)), sp.coo_matrix((K * (T - 1), K))] ]) b_eq2 = np.hstack([init, np.zeros((T - 1) * K)]) # Forbid non-existent modes # T * len(ban_idx) equalities ban_idx = [G.order_fcn(v) + m * K for v in G.nodes_iter() for m in range(M) if G.mode(m) not in G.node_modes(v)] A_eq3_u_part = sp.coo_matrix( (np.ones(len(ban_idx)), (range(len(ban_idx)), ban_idx)), shape=(len(ban_idx), K * M) ) A_eq3_u = sp.block_diag((A_eq3_u_part,) * T) A_eq3_x = sp.coo_matrix((T * len(ban_idx), T * K)) b_eq3 = np.zeros(T * len(ban_idx)) # Stack everything A_eq_u = sp.bmat([[A_eq1_u], [A_eq2_u], [A_eq3_u]]) A_eq_x = sp.bmat([[-A_eq1_x], [-A_eq2_x], [A_eq3_x]]) b_eq = np.hstack([b_eq1, b_eq2, b_eq3]) return A_eq_u, A_eq_x, b_eq
def global_spin_rotation(m, vector=np.array([0.0, 0.0, 1.0]), angle=0.0, spiral=False, atoms=None): """ Rotates a matrix along a certain qvector """ # pauli matrices from scipy.sparse import csc_matrix, bmat sx = csc_matrix([[0.0, 1.0], [1.0, 0.0]]) sy = csc_matrix([[0.0, -1j], [1j, 0.0]]) sz = csc_matrix([[1.0, 0.0], [0.0, -1.0]]) iden = csc_matrix([[1.0, 0.0], [0.0, 1.0]]) n = len(m) / 2 # number of sites if atoms == None: atoms = range(n) # all the atoms else: raise R = [[None for i in range(n)] for j in range(n)] # rotation matrix from scipy.linalg import expm # exponenciate matrix for i in range(n): # loop over sites u = np.array(vector) u = u / np.sqrt(u.dot(u)) # unit vector rot = u[0] * sx + u[1] * sy + u[2] * sz # a factor 2 is taken out due to 1/2 of S rot = expm(np.pi * 1j * rot * angle / 2.0) # if i in atoms: R[i][i] = rot # save term # else: # R[i][i] = iden # save term R = bmat(R) # convert to full sparse matrix if spiral: # for spin spiral mout = R * csc_matrix(m) # rotate matrix else: # normal global roration mout = R * csc_matrix(m) * R.H # rotate matrix return mout.todense() # return dense matrix
def intra_super2d(h,n=1,central=None): """ Calculates the intra of a 2d system""" from scipy.sparse import bmat from scipy.sparse import csc_matrix as csc tx = csc(h.tx) ty = csc(h.ty) txy = csc(h.txy) txmy = csc(h.txmy) intra = csc(h.intra) for i in range(n): intrasuper[i][i] = intra # intracell (x1,y1) = inds[i] for j in range(n): (x2,y2) = inds[j] dx = x2-x1 dy = y2-y1 if dx==1 and dy==0: intrasuper[i][j] = tx if dx==-1 and dy==0: intrasuper[i][j] = tx.H if dx==0 and dy==1: intrasuper[i][j] = ty if dx==0 and dy==-1: intrasuper[i][j] = ty.H if dx==1 and dy==1: intrasuper[i][j] = txy if dx==-1 and dy==-1: intrasuper[i][j] = txy.H if dx==1 and dy==-1: intrasuper[i][j] = txmy if dx==-1 and dy==1: intrasuper[i][j] = txmy.H # substitute the central cell if it is the case if central!=None: ic = (n-1)/2 intrasuper[ic][ic] = central # now convert to matrix intrasuper = bmat(intrasuper).todense() # supercell return intrasuper
def _sparse_block_diag(mats, format=None, dtype=None): """An implementation of scipy.sparse.block_diag since old versions of scipy don't have it. Forms a sparse matrix by stacking matrices in block diagonal form. Parameters ---------- mats : list of matrices Input matrices. format : str, optional The sparse format of the result (e.g. "csr"). If not given, the matrix is returned in "coo" format. dtype : dtype specifier, optional The data-type of the output matrix. If not given, the dtype is determined from that of blocks. Returns ------- res : sparse matrix """ nmat = len(mats) rows = [] for ia, a in enumerate(mats): row = [None] * nmat row[ia] = a rows.append(row) return sparse.bmat(rows, format=format, dtype=dtype)
def stokes2(k, meshevents, v, points): vortelts1 = pe.HcurlElements(k) vortelts2 = pe.HcurlElements(k) velelts1 = pe.HdivElements(k) velelts2 = pe.HdivElements(k) pressureelts1 = pe.L2Elements(k) quadrule = pu.pyramidquadrature(k+1) Asys = pa.SymmetricSystem(vortelts1, quadrule, meshevents, []) # Bsys = pa.AsymmetricSystem(velelts1, vortelts2, quadrule, meshevents, [bdytag], []) BsysT = pa.AsymmetricSystem(vortelts2, velelts1, quadrule, meshevents, [], [bdytag]) Csys = pa.AsymmetricSystem(pressureelts1,velelts2, quadrule, meshevents, [], [bdytag]) A = Asys.systemMatrix(False) BT = BsysT.systemMatrix(True, False) C = Csys.systemMatrix(False, True) vv = lambda x: np.tile(v,(len(x), 1))[:,np.newaxis,:] vn = lambda x,n: np.tensordot(n,v,([1],[1])) # vt = lambda x,n: (v - vn(x,n)*n)[:,np.newaxis,:] vc = lambda x,n: np.cross(v, n)[:, np.newaxis, :] BTI, BTE, BTGs = BsysT.processBoundary(BT, {bdytag:vv}) CI, CE, CGs = Csys.processBoundary(C, {bdytag:vv}) P = Csys.loadVector(lambda x: np.ones((len(x),1,1))) # print "P ",P Gt = Asys.boundaryLoad({bdytag: vc}, pu.squarequadrature(k+1), pu.trianglequadrature(k+1), False) # print "Gt ",Gt print A.shape, BT.shape, C.shape, BTI.shape, BTE[bdytag].shape, BTGs[bdytag].shape, CI.shape AL = Gt[bdytag] + BTE[bdytag] * BTGs[bdytag] # print "AL ",AL CL = -CE[bdytag] * CGs[bdytag] nvort = A.get_shape()[0] nvel = BTI.get_shape()[1] # S = ss.bmat([[A, -BTI, None],[-BTI.transpose(), None, CI.transpose()],[None, CI, None]]) # L = np.vstack((AL,np.zeros((nvel,1)), CL)) S = ss.bmat([[A, -BTI, None, None],[-BTI.transpose(), None, CI.transpose(), None],[None, CI, None, P], [None,None,P.transpose(), None]]) L = np.vstack((AL,np.zeros((nvel,1)), CL, np.zeros((1,1)))) print "solving" X = ps.solve(S, L) U = X[nvort:(nvort + nvel)] # print "X",X # print "U", U # print "BTGs", BTGs # u = BsysT.evaluate(points, U, BTGs, False) # uu = Asys.evaluate(points, np.eye(nvort)[-2], {}, False) # uu = BsysT.evaluate(points, U, {}, False) uu = BsysT.evaluate(points, np.zeros_like(U), BTGs, False) # print np.hstack((points, u)) # print u return u, uu
def solve(self, objective, constraints, cached_data, warm_start, verbose, solver_opts): """Returns the result of the call to the solver. Parameters ---------- objective : CVXPY objective object Raw objective passed by CVXPY. Can be convex/concave. constraints : list The list of raw constraints. Returns ------- tuple (status, optimal value, primal, equality dual, inequality dual) """ sym_data = self.get_sym_data(objective, constraints) id_map = sym_data.var_offsets N = sym_data.x_length extractor = QuadCoeffExtractor(id_map, N) # Extract the coefficients (Ps, Q, R) = extractor.get_coeffs(objective.args[0]) P = Ps[0] q = np.asarray(Q.todense()).flatten() r = R[0] # Forming the KKT system if len(constraints) > 0: Cs = [extractor.get_coeffs(c._expr)[1:] for c in constraints] As = sp.vstack([C[0] for C in Cs]) bs = np.array([C[1] for C in Cs]).flatten() lhs = sp.bmat([[2*P, As.transpose()], [As, None]], format='csr') rhs = np.concatenate([-q, -bs]) else: # avoiding calling vstack with empty list lhs = 2*P rhs = -q warnings.filterwarnings('error') # Actually solving the KKT system try: sol = SLA.spsolve(lhs.tocsr(), rhs) x = np.array(sol[:N]) nu = np.array(sol[N:]) p_star = np.dot(x.transpose(), P*x + q) + r except SLA.MatrixRankWarning: x = None nu = None p_star = None warnings.resetwarnings() result_dict = {s.PRIMAL: x, s.EQ_DUAL: nu, s.VALUE: p_star} return self.format_results(result_dict, None, cached_data)
def eigensystem(N, ell, B, alpha_BC, cutoff=1e9, boundary_conditions='no-slip'): if ell == 0: return 0, 0, 0, 0, 0, 0 def D(mu, i, deg): if mu == +1: return B.op('D+', N, i, ell + deg) if mu == -1: return B.op('D-', N, i, ell + deg) def E(i, deg): return B.op('E', N, i, ell + deg) Z = B.op('0', N, 0, ell) xim, xip = B.xi([-1, +1], ell) R00 = E(1, -1).dot(E(0, -1)) R11 = E(1, 0).dot(E(0, 0)) R22 = E(1, +1).dot(E(0, +1)) R = sparse.bmat([[R00, Z, Z, Z], [Z, R11, Z, Z], [Z, Z, R22, Z], [Z, Z, Z, Z]]) R = R.tocsr() L00 = -D(-1, 1, 0).dot(D(+1, 0, -1)) L11 = -D(-1, 1, +1).dot(D(+1, 0, 0)) L22 = -D(+1, 1, 0).dot(D(-1, 0, +1)) L03 = xim * E(+1, -1).dot(D(-1, 0, 0)) L23 = xip * E(+1, +1).dot(D(+1, 0, 0)) L30 = xim * D(+1, 0, -1) L32 = xip * D(-1, 0, +1) L = sparse.bmat([[L00, Z, Z, L03], [Z, L11, Z, Z], [Z, Z, L22, L23], [L30, Z, L32, Z]]) N0, N1, N2, N3 = BC_rows(N) if boundary_conditions == 'no-slip': row0 = np.concatenate((B.op('r=1', N, 0, ell - 1), np.zeros(N3 - N0))) row1 = np.concatenate((np.zeros(N0 + 1), B.op('r=1', N, 0, ell), np.zeros(N3 - N1))) row2 = np.concatenate( (np.zeros(N1 + 1), B.op('r=1', N, 0, ell + 1), np.zeros(N3 - N2))) if boundary_conditions == 'stress-free': Q = B.Q[(ell, 2)] rDmm = B.xi(-1, ell - 1) * B.op('r=1', N, 1, ell - 2) * D(-1, 0, -1) rDpm = B.xi(+1, ell - 1) * B.op('r=1', N, 1, ell) * D(+1, 0, -1) rDm0 = B.xi(-1, ell) * B.op('r=1', N, 1, ell - 1) * D(-1, 0, 0) rDp0 = B.xi(+1, ell) * B.op('r=1', N, 1, ell + 1) * D(+1, 0, 0) rDmp = B.xi(-1, ell + 1) * B.op('r=1', N, 1, ell) * D(-1, 0, +1) rDpp = B.xi(+1, ell + 1) * B.op('r=1', N, 1, ell + 2) * D(+1, 0, +1) rD = np.array([ rDmm, rDm0, rDmp, 0. * rDmm, 0. * rDm0, 0. * rDmp, rDpm, rDp0, rDpp ]) QSm = Q[:, ::3].dot(rD[::3]) QS0 = Q[:, 1::3].dot(rD[1::3]) QSp = Q[:, 2::3].dot(rD[2::3]) u0m = B.op('r=1', N, 0, ell - 1) * B.Q[(ell, 1)][1, 0] u0p = B.op('r=1', N, 0, ell + 1) * B.Q[(ell, 1)][1, 2] row0 = np.concatenate( (QSm[1] + QSm[3], QS0[1] + QS0[3], QSp[1] + QSp[3], np.zeros(N3 - N2))) row1 = np.concatenate((u0m, np.zeros(N0 + 1), u0p, np.zeros(N3 - N2))) row2 = np.concatenate( (QSm[5] + QSm[7], QS0[5] + QS0[7], QSp[5] + QSp[7], np.zeros(N3 - N2))) if boundary_conditions == 'potential-field': row0 = np.concatenate((B.op('r=1', N, 0, ell - 1), np.zeros(N3 - N0))) #L[N0]=np.concatenate(( B.op('r=1',N,1,ell )*D(+1,0,-1),np.zeros(N3-N0))) row1 = np.concatenate( (np.zeros(N0 + 1), B.op('r=1', N, 1, ell - 1) * D(-1, 0, 0), np.zeros(N3 - N1))) row2 = np.concatenate( (np.zeros(N1 + 1), B.op('r=1', N, 1, ell) * D(-1, 0, +1), np.zeros(N3 - N2))) if boundary_conditions == 'pseudo-vacuum': row0 = np.concatenate((B.op('r=1', N, 0, ell - 1), np.zeros(N3 - N0))) #L[N0]=np.concatenate(( B.op('r=1',N,1,ell )*D(+1,0,-1),np.zeros(N3-N0))) row1 = np.concatenate( (np.zeros(N0 + 1), B.op('r=1', N, 1, ell - 1) * D(-1, 0, 0) - ell * B.op('r=1', N, 0, ell), np.zeros(N3 - N1))) row2 = np.concatenate( (np.zeros(N1 + 1), B.op('r=1', N, 1, ell) * D(-1, 0, +1), np.zeros(N3 - N2))) if boundary_conditions == 'perfectly-conducting': row0 = np.concatenate((np.zeros(N2 + 1), B.op('r=1', N, 0, ell))) row1 = np.concatenate((np.zeros(N0 + 1), B.op('r=1', N, 0, ell), np.zeros(N3 - N1))) row2 = np.concatenate( (B.xi(+1, ell) * B.op('r=1', N, 0, ell - 1), np.zeros(N0 + 1), -B.xi(-1, ell) * B.op('r=1', N, 0, ell + 1), np.zeros(N3 - N2))) C0 = connection(N, ell - 1, alpha_BC, 2) C1 = connection(N, ell, alpha_BC, 2) C2 = connection(N, ell + 1, alpha_BC, 2) R00 = E(1, -1).dot(E(0, -1)) R11 = E(1, 0).dot(E(0, 0)) R22 = E(1, +1).dot(E(0, +1)) tau0 = C0[:, -1] tau0 = tau0.reshape((len(tau0), 1)) tau1 = C1[:, -1] tau1 = tau1.reshape((len(tau1), 1)) tau2 = C2[:, -1] tau2 = tau2.reshape((len(tau2), 1)) col0 = np.concatenate((tau0, np.zeros((N3 - N0, 1)))) col1 = np.concatenate((np.zeros((N0 + 1, 1)), tau1, np.zeros( (N3 - N1, 1)))) col2 = np.concatenate((np.zeros((N1 + 1, 1)), tau2, np.zeros( (N3 - N2, 1)))) L = sparse.bmat([[L, col0, col1, col2], [row0, 0, 0, 0], [row1, 0, 0, 0], [row2, 0, 0, 0]]) R = sparse.bmat([[R, 0 * col0, 0 * col1, 0 * col2], [0 * row0, 0, 0, 0], [0 * row1, 0, 0, 0], [0 * row2, 0, 0, 0]]) # The rate-limiting step vals, vecs = eig(L.todense(), b=R.todense()) bad = (np.abs(vals) > cutoff) vals[bad] = np.inf good = np.isfinite(vals) vals, vecs = vals[good], vecs[:, good] i = np.argsort(vals.real) vals, vecs = vals[i], vecs.transpose()[i] return vals, vecs
element = {'u': ElementLineP2(), 'p': ElementLineP1()} basis = {v: InteriorBasis(mesh, e, intorder=4) for v, e in element.items()} L = asm(laplace, basis['u']) M = asm(mass, basis['u']) P = asm(mass, basis['u'], basis['p']) B = -asm(divergence, basis['u'], basis['p']) V = asm(base_velocity, basis['u']) W = asm(base_shear, basis['u']) re = 1e4 # Reynolds number alpha = 1. # longitudinal wavenumber jare = 1j * alpha * re Kuu = jare * V + alpha**2 * M + L stiffness = bmat([[Kuu, re * W, jare * P.T], [None, Kuu, re * B.T], [-jare * P, re * B, None]], 'csc') mass_matrix = block_diag([M, M, csr_matrix((basis['p'].N,)*2)], 'csr') # Seek only 'even' modes, 'even' in terms of conventional # stream-function formulation, so that the longitudinal component u of # the perturbation to the velocity vanishes on the centre-line z = 0, # z here being the sole coordinate. u_boundaries = basis['u'].get_dofs().all() walls = np.concatenate([u_boundaries, u_boundaries[1:] + basis['u'].N]) pencil = condense(stiffness, mass_matrix, D=walls, expand=False) c = {'Criminale et al': np.loadtxt(Path(__file__).with_suffix('.csv'), dtype=complex)}
def merge_files(data_paths, gene_paths, dataset_names, output_path, keep_genes=True, use_batch_correction=False): """ Merges multiple files into a single file... Args: data_paths (list of paths to data files - mtx or txt files, in genes x cells order) gene_paths (list of paths to gene txt files) dataset_names (names of each dataset) output_path (directory to write to) keep_genes (bool): whether or not to include genes that only occur in some data files (values will be set to zero). use_batch_correction (bool): whether or not to use batch effect correction (with the MNN method) This saves an output file as 'data.mtx.gz' in output_path, and a genes file as 'gene_names.txt', and returns two files: a sparse It also deletes all the temporary files. """ if len(data_paths) == 1 and len(gene_paths) == 1: data_output_path = data_paths[0].replace('_1', '') os.rename(data_paths[0], data_output_path) if gene_paths[0] is not None: gene_output_path = gene_paths[0].replace('_1', '') os.rename(gene_paths[0], gene_output_path) return data_output_path, gene_output_path all_data = [] all_genes = [] genes_set = set() data_array = [] for data_path, gene_path, dataset_name in zip(data_paths, gene_paths, dataset_names): # TODO: if gene_path is None... what do we do? if gene_path is not None: genes = np.loadtxt(gene_path, dtype=str) if data_path.endswith('mtx.gz') or data_path.endswith('mtx'): data = scipy.io.mmread(data_path) else: data = np.loadtxt(data_path) # TODO: infer gene shape/data n_genes = genes.shape[0] if n_genes == data.shape[1]: data = data.T data_array += [dataset_name] * data.shape[1] all_genes.append(genes) if keep_genes or len(genes_set) == 0: genes_set.update(genes) else: genes_set = genes_set.intersection(genes) all_data.append(data) np.savetxt(os.path.join(output_path, 'samples.txt'), data_array, fmt='%s') # combine gene lists # decide whether any of the genes are different all_genes_same = True for g1 in all_genes: for g2 in all_genes: if len(g1) != len(g2) or (g1 != g2).any(): all_genes_same = False break data_output_path = os.path.join(output_path, 'data.mtx') genes_output_path = os.path.join(output_path, 'gene_names.txt') if all_genes_same: combined_genes = all_genes[0] # combine matrices... # TODO: make sure that transposing the matrices is done before... # we assume that all input matrices are of shape (gene, cell) if use_batch_correction: from .batch_correction import batch_correct_mnn # use batch effect correction output_matrix = batch_correct_mnn(all_data) else: output_matrix = sparse.hstack(all_data) # save output matrix as mtx.gz scipy.io.mmwrite(data_output_path, output_matrix) import subprocess subprocess.call(['gzip', data_output_path]) data_output_path += '.gz' # save gene path os.rename(gene_paths[0], genes_output_path) else: # TODO: what if multiple genes have the same name? # then we just take the max value combined_genes = np.array(list(genes_set)) modified_matrices = [] # do the mapping... # TODO: add an option to remove genes that only occur in one file for genes, data in zip(all_genes, all_data): data = sparse.csr_matrix(data) # use bmat - concatenate by rows gene_to_index = {g: i for i, g in enumerate(genes)} #for i, g in enumerate(genes): # if g in gene_to_index: # gene_to_index[g].append(i) # else: # gene_to_index[g] = [i] sub_blocks = [] for gene in combined_genes: if gene not in gene_to_index: if keep_genes: sub_blocks.append( [sparse.csr_matrix(np.zeros(data.shape[1]))]) else: continue else: sub_blocks.append([data[gene_to_index[gene], :]]) #sub_blocks.append([data[gene_to_index[gene], :].max(0)]) data_new = sparse.bmat(sub_blocks) modified_matrices.append(data_new) if use_batch_correction: from .batch_correction import batch_correct_mnn output_matrix = batch_correct_mnn(modified_matrices) else: output_matrix = sparse.hstack(modified_matrices) scipy.io.mmwrite(data_output_path, output_matrix) import subprocess subprocess.call(['gzip', data_output_path]) data_output_path += '.gz' # save gene path np.savetxt(genes_output_path, combined_genes, fmt='%s') # remove uploaded files for path in gene_paths: try: os.remove(path) except: pass for path in data_paths: try: os.remove(path) except: pass return data_output_path, genes_output_path
def solve(self, objective, constraints, cached_data, warm_start, verbose, solver_opts): """Returns the result of the call to the solver. Parameters ---------- objective : LinOp The canonicalized objective. constraints : list The list of canonicalized cosntraints. cached_data : dict A map of solver name to cached problem data. warm_start : bool Not used. verbose : bool Should the solver print output? solver_opts : dict Additional arguments for the solver. Returns ------- tuple (status, optimal value, primal, equality dual, inequality dual) """ import mosek with mosek.Env() as env: with env.Task(0, 0) as task: kwargs = sorted(solver_opts.keys()) if "mosek_params" in kwargs: self._handle_mosek_params(task, solver_opts["mosek_params"]) kwargs.remove("mosek_params") if kwargs: raise ValueError("Invalid keyword-argument '%s'" % kwargs[0]) if verbose: # Define a stream printer to grab output from MOSEK def streamprinter(text): import sys sys.stdout.write(text) sys.stdout.flush() env.set_Stream(mosek.streamtype.log, streamprinter) task.set_Stream(mosek.streamtype.log, streamprinter) data = self.get_problem_data(objective, constraints, cached_data) A = data[s.A] b = data[s.B] G = data[s.G] h = data[s.H] c = data[s.C] dims = data[s.DIMS] # size of problem numvar = len(c) + sum(dims[s.SOC_DIM]) numcon = len(b) + dims[s.LEQ_DIM] + sum(dims[s.SOC_DIM]) + \ sum([el**2 for el in dims[s.SDP_DIM]]) # otherwise it crashes on empty probl. if numvar == 0: result_dict = {s.STATUS: s.OPTIMAL} result_dict[s.PRIMAL] = [] result_dict[s.VALUE] = 0. + data[s.OFFSET] result_dict[s.EQ_DUAL] = [] result_dict[s.INEQ_DUAL] = [] return result_dict # objective task.appendvars(numvar) task.putclist(np.arange(len(c)), c) task.putvarboundlist(np.arange(numvar, dtype=int), [mosek.boundkey.fr]*numvar, np.zeros(numvar), np.zeros(numvar)) # SDP variables if sum(dims[s.SDP_DIM]) > 0: task.appendbarvars(dims[s.SDP_DIM]) # linear equality and linear inequality constraints task.appendcons(numcon) if A.shape[0] and G.shape[0]: constraints_matrix = sp.bmat([[A], [G]]) else: constraints_matrix = A if A.shape[0] else G coefficients = np.concatenate([b, h]) row, col, el = sp.find(constraints_matrix) task.putaijlist(row, col, el) type_constraint = [mosek.boundkey.fx] * len(b) type_constraint += [mosek.boundkey.up] * dims[s.LEQ_DIM] sdp_total_dims = sum([cdim**2 for cdim in dims[s.SDP_DIM]]) type_constraint += [mosek.boundkey.fx] * \ (sum(dims[s.SOC_DIM]) + sdp_total_dims) task.putconboundlist(np.arange(numcon, dtype=int), type_constraint, coefficients, coefficients) # cones current_var_index = len(c) current_con_index = len(b) + dims[s.LEQ_DIM] for size_cone in dims[s.SOC_DIM]: row, col, el = sp.find(sp.eye(size_cone)) row += current_con_index col += current_var_index task.putaijlist(row, col, el) # add a identity for each cone # add a cone constraint task.appendcone(mosek.conetype.quad, 0.0, # unused np.arange(current_var_index, current_var_index + size_cone)) current_con_index += size_cone current_var_index += size_cone # SDP for num_sdp_var, size_matrix in enumerate(dims[s.SDP_DIM]): for i_sdp_matrix in range(size_matrix): for j_sdp_matrix in range(size_matrix): coeff = 1. if i_sdp_matrix == j_sdp_matrix else .5 task.putbaraij(current_con_index, num_sdp_var, [task.appendsparsesymmat(size_matrix, [max(i_sdp_matrix, j_sdp_matrix)], [min(i_sdp_matrix, j_sdp_matrix)], [coeff])], [1.0]) current_con_index += 1 # solve task.putobjsense(mosek.objsense.minimize) task.optimize() if verbose: task.solutionsummary(mosek.streamtype.msg) return self.format_results(task, data, cached_data)
def symmetrize_hamiltonian(orb_file="orbitals.wan", ham_file="hamiltonian.wan", cell_file="geometry.wan", nlook=[4, 4, 1], sym_file="symmetry.wan"): """Write in a file the new Hamiltonian, symmetrized""" (inds, atoms, orbs, rs) = read_orbitals(input_file=orb_file) # read the orbitals anames = get_atom_names(atoms) # different atom names # function to get hoppings to arbitrary cells get_hopping = multicell.read_from_file(input_file=ham_file) # get the dictionaries idict = index_dictionary(inds, atoms, orbs) odict = orbital_dictionary(inds, atoms, orbs) rdict = position_dictionary(atoms, rs) # matrix that will reorder the orbitals T = reorder_basis(anames, odict, idict) # read unit cell vectors (a1, a2, a3) = read_unit_cell() # generate the symmetrizer matrices h0 = get_hopping(0, 0, 0) # onsite matrix ons = [extract_matrix(a, a, odict, idict, h0) for a in anames] # in each atom sdict = local_symmetrizer(anames, ons, odict, sym_file=sym_file) # matrices # now look into neighbors to get matrices stored_rs = [] # distances between atoms stored stored_atoms = [] # distances between atoms stored stored_matrix = [] # distances between atoms stored stored_vectors = [] # vectors between atoms for ia in anames: # loop over atoms for ja in anames: # loop over atoms ri = rdict[ia] # position of iesim atom ri = ri[0] * a1 + ri[1] * a2 + ri[ 2] * a3 # position in real coordinates for n1 in range(-nlook[0], nlook[0] + 1): for n2 in range(-nlook[1], nlook[1] + 1): for n3 in range(-nlook[2], nlook[2] + 1): rj = rdict[ja] # position of iesim atom # position in real coordinates rj = (rj[0] + n1) * a1 + (rj[1] + n2) * a2 + (rj[2] + n3) * a3 dr = rj - ri # vector between this two atoms drr = np.sqrt(dr.dot(dr)) # distance between atoms m = get_hopping(n1, n2, n3) # hopping in this direction tij = extract_matrix(ia, ja, odict, idict, m) # hopping between atoms # special case of onsite matrices if ia == ja and n1 == n2 == n3 == 0: tij = sdict[ ia] # get the symmetrized onsite matrix Ri = rotation_operator(odict[ia], dr) # rotate basis i Rj = rotation_operator(odict[ja], dr) # rotate basis j Rtij = Ri.H * tij * Rj # hopping matrix in the new frame # now store the different things needed stored_rs.append(drr) # store the distance stored_vectors.append(dr) # store the vector stored_atoms.append((ia, ja)) # store the atom pairs stored_matrix.append(Rtij) # store the rotated matrix # get the function that generated symmetric hoppings hop_gen = symmetric_hopping_generator(stored_rs, stored_vectors, stored_atoms, stored_matrix) # now create hoppings of the symmetric Hamiltonian rmax = np.sqrt(a1.dot(a1)) * (nlook[0] + 1) / 2. # maximum distance print("Cutoff distance is", rmax) ns_list = [] # list with ns hops_list = [] # list with ns for n1 in range(-nlook[0], nlook[0] + 1): for n2 in range(-nlook[1], nlook[1] + 1): for n3 in range(-nlook[2], nlook[2] + 1): hop = [[None for i in range(len(anames))] for j in range(len(anames))] for i in range(len(anames)): # loop over atoms for j in range(len(anames)): # loop over atoms ia = anames[i] # name of the atom ja = anames[j] # name of the atom ri = rdict[ia] # position of iesim atom rj = rdict[ja] # position of jesim atom ri = ri[0] * a1 + ri[1] * a2 + ri[ 2] * a3 # position in real coordinates rj = (rj[0] + n1) * a1 + (rj[1] + n2) * a2 + (rj[2] + n3) * a3 dr = rj - ri # vector between this two atoms drr = np.sqrt(dr.dot(dr)) # distance between atoms m = hop_gen(ia, ja, dr) # get the symmetric hopping Ri = rotation_operator(odict[ia], dr) # rotate basis i Rj = rotation_operator(odict[ja], dr) # rotate basis j if m is not None: m = Ri * m * Rj.H # hopping matrix in the new frame, opposite rot if drr > rmax: m *= 0. # reached maximum distance hop[i][j] = csc_matrix(m) # store the matrix hop = bmat(hop).todense() # create dense matrix hop = T.H * hop * T # convert to the original order hops_list.append(hop) # store hopping ns_list.append([n1, n2, n3]) # store indexes multicell.save_multicell(ns_list, hops_list)
def intersect_sparse(h1, h2): if h1.ambiant_dimension != h2.ambiant_dimension: raise ValueError("Different ambiant\ spaces dimensions ({}!={})".format(len(w1), len(w2))) # elif pl.allclose(w1,w2) and pl.allclose(b1,b2): # print("return same object") # return copy(h1) # elif pl.allclose(w1,w2) and not pl.allclose(b1,b2): # print("return empty set") # return None #Now that the trivial cases have been removed there exists an #intersection of the two hyperplanes to obtain the new form of #the hyperplane we perform the following 3 steps: # (1)consider the intersection of two affine spaces as the intersection # of a linear space and an affine space with modified bias # (2)express the bias of the affine space in the linear space, # this gives us the bias that will be for the new affine space # (3)compute the basis of the intersection of the two linear spaces # this gives us the span of the linear space, jointly with the above # bias corresponding to the affine space from the intersection #(1) bp = h2.bias - h1.bias #(2) A = sp.hstack([h1.basis, h2.basis]) output = sparse_lsqr(A, bp) alpha_beta_star, istop, itn = output[:3] if (istop == 2): warnings.warn("In Intersection of {} with {},\ least square solution is approximate".format(h1.name, h2.name)) bpp = h2.basis.dot(alpha_beta_star[h1.dim:]) print("New bias is {}".format(bpp)) # (3) --------- Implement the Zassenhaus algorithm ------------- # assumes each space basis is in the same basis # first need to create the original matrix print(h1.basis.todense(), '\n\n') print(h2.basis.todense(), '\n\n') matrix = sp.bmat([[h1.basis, h2.basis], [h1.basis, None]]).T # Now we need to put the top left half in row echelon form # loop over the columns of the left half for column in range(h1.ambiant_dimension - 1): print('start column:{}\nmatrix:\n{}\n\n'.format( column, matrix.todense())) # compute current index and value of pivot A_{column,column} pivot_index = pl.flatnonzero((matrix.col == column) & (matrix.row == column)) pivot = pl.squeeze(matrix.data[pivot_index]) # compute indices to act upon current_indices = pl.flatnonzero((matrix.col == column) & (matrix.row > column)) current_data = matrix.data[current_indices] # check for active pivoting to switch current row # with the one with maximum value maximum_index = current_indices[current_data.argmax()] maximum_value = matrix.data[maximum_index] print('maximum value', maximum_value, 'pivot', pivot) if abs(maximum_value) > abs(pivot): print('needs preventive pivoting') row_w_maximum = matrix.row[maximum_index] matrix.row[matrix.row == row_w_maximum] = column matrix.row[matrix.row == column] = row_w_maximum pivot = pl.squeeze(maximum_value) print('\tstart column:{}\n\tmatrix:\n\t{}\n\n'.format( column, matrix.todense())) # create a buffer to add new values to_add = {'row': [], 'col': [], 'data': []} considered_column_indices = pl.flatnonzero((matrix.col >= column) & (matrix.row == column)) # Loop over the rows for row, value in zip(matrix.row[current_indices], matrix.data[current_indices]): multiplicator = value / pivot print('Multiplicator={}'.format(multiplicator)) # Compute which column of the current row are nonzeros pivot_nonzero_indices = pl.flatnonzero((matrix.col >= column) & (matrix.row == row)) # Find the columns that are both nonzeros at row column and row row both_nonzero = pl.array([ i for i in pivot_nonzero_indices if i in considered_column_indices ]) print(both_nonzero) # Find here zero but pivot row nonzero, this corresponds to the column that will # need to have new values in it hereonly_nonzero = pl.array([ i for i in considered_column_indices if i not in pivot_nonzero_indices ]) # Loop over the columns which are both nonzeros if (len(both_nonzero) > 0): for pos, val in zip( both_nonzero, pl.nditer(matrix.data[both_nonzero], op_flags=['readwrite'])): val -= multiplicator * value print('New Value', val) # Loop over column that are here zero and thus need a new placeholder if (len(hereonly_nonzero) > 0): for pos in hereonly_nonzero: to_add['row'].append(row) to_add['data'].append(-value) to_add['col'].append(pos) print(matrix.todense()) # add the newly introduces nonzero values ot the sparse matrix matrix.row = pl.concatenate([matrix.row, to_add['row']]) matrix.col = pl.concatenate([matrix.col, to_add['col']]) matrix.data = pl.concatenate([matrix.data, to_add['data']]) print(matrix.todense()) matrix.eliminate_zeros() # # now need to remove the entries that are now 0 # # first from the ones explicitly reduces # to_delete = pl.flatnonzero((matrix.col==column) & (matrix.row > column)) # # now form the possible ones that became 0 during row operations # indices = pl.flatnonzero(matrix.row<column) # data = matrix.data[indices] # extras_to_delete = pl.flatnonzero(pl.isclose(data,0)) # # merge both lists # to_delete = pl.concatenate([to_delete,extras_to_delete]) # # delete the corresponding indices alternative: matrix.eliminate_zeros() # matrix.col = pl.delete(matrix.col,to_delete, None) # matrix.row = pl.delete(matrix.row,to_delete, None) # matrix.data = pl.delete(matrix.data,to_delete, None) # # end of this procedure, move over to the next column # # check if completed block_indices = pl.flatnonzero((matrix.col < h1.ambiant_dimension) & (matrix.row > column)) if (len(current_indices) == 0): return matrix.to_dense()
def densebmat(m): """Turn a block matrix dense""" ms = [[todense(mi) for mi in mij] for mij in m] return todense(bmat(ms)) # return block matrix
basis = { variable: InteriorBasis(mesh, e, intorder=3) for variable, e in element.items() } @linear_form def body_force(v, dv, w): return w.x[0] * v[1] A = asm(vector_laplace, basis['u']) B = asm(divergence, basis['u'], basis['p']) C = asm(mass, basis['p']) K = bmat([[A, -B.T], [-B, 1e-6 * C]]).tocsr() f = np.concatenate([asm(body_force, basis['u']), np.zeros(B.shape[0])]) D = basis['u'].get_dofs().all() uvp = np.zeros(K.shape[0]) uvp[np.setdiff1d(np.arange(K.shape[0]), D)] = solve(*condense(K, f, D=D)) velocity, pressure = np.split(uvp, [A.shape[0]]) @linear_form def rot(v, dv, w): return dv[1] * w.w[0] - dv[0] * w.w[1]
def to_V(upsilon): bot = np.zeros((Xp, Lp)) for row, (i, j) in enumerate(slices(bs.pos_groups)): bot[row, i:j] = upsilon.flat[i:j] return sp.bmat([[sp.eye(Ln, Ln), None], [None, sp.coo_matrix(bot)]])
def convergence_test(N, gb_ref, solver, solver_fct): f = open(solver + "_error.txt", "w") for i in np.arange(N): cells_2d = 200 * 4 ** i alpha_1d = None alpha_mortar = 0.75 gb = example_1_data.create_gb(cells_2d, alpha_1d, alpha_mortar) example_1_data.add_data(gb, solver) folder = "example_1_" + solver + "_" + str(i) solver_fct(gb, folder) error_0d = 0 ref_0d = 0 error_1d = 0 ref_1d = 0 for e_ref, d_ref in gb_ref.edges(): for e, d in gb.edges(): if d_ref["edge_number"] == d["edge_number"]: break mg_ref = d_ref["mortar_grid"] mg = d["mortar_grid"] m_ref = d_ref["mortar_solution"] m = d["mortar_solution"] num_cells = int(mg.num_cells / 2) m_switched = np.hstack((m[num_cells:], m[:num_cells])) if mg_ref.dim == 0: error_0d += np.power(m - m_ref, 2)[0] ref_0d += np.power(m_ref, 2)[0] if mg_ref.dim == 1: Pi_ref = np.empty((mg.num_sides(), mg.num_sides()), dtype=np.object) for idx, (side, g_ref) in enumerate(mg_ref.side_grids.items()): g = mg.side_grids[side] Pi_ref[idx, idx] = mortars.split_matrix_1d( g, g_ref, example_1_data.tol() ) Pi_ref = sps.bmat(Pi_ref, format="csc") inv_k = 1.0 / (2.0 * d_ref["kn"]) M = sps.diags(inv_k / mg_ref.cell_volumes) delta = m_ref - Pi_ref * m delta_switched = m_ref - Pi_ref * m_switched error_1d_loc = np.dot(delta, M * delta) error_1d_loc_switched = np.dot(delta_switched, M * delta_switched) error_1d += min(error_1d_loc, error_1d_loc_switched) ref_1d += np.dot(m_ref, M * m_ref) error_0d = "%1.2e" % np.sqrt(error_0d / ref_0d) error_1d = "%1.2e" % np.sqrt(error_1d / ref_1d) def cond(g): return not (isinstance(g, Grid)) diam_mg = "%1.2e" % gb.diameter(cond) def cond(g): return isinstance(g, Grid) diam_g = "%1.2e" % gb.diameter(cond) f.write( str(i) + " \t" + diam_g + " \t" + diam_mg + " \t" + error_0d + " \t" + error_1d + "\n" ) f.close()
mesh = from_file( Path(__file__).parent / 'meshes' / 'backward-facing_step.json') element = {'u': ElementVectorH1(ElementTriP2()), 'p': ElementTriP1()} basis = { variable: InteriorBasis(mesh, e, intorder=3) for variable, e in element.items() } D = np.concatenate([b.all() for b in basis['u'].find_dofs().values()]) A = asm(vector_laplace, basis['u']) B = -asm(divergence, basis['u'], basis['p']) K = bmat([[A, B.T], [B, None]], 'csr') uvp = np.zeros(K.shape[0]) inlet_basis = FacetBasis(mesh, element['u'], facets=mesh.boundaries['inlet']) inlet_dofs = inlet_basis.find_dofs()['inlet'].all() def parabolic(x): """return the plane Poiseuille parabolic inlet profile""" return np.stack([4 * x[1] * (1. - x[1]), np.zeros_like(x[0])]) uvp[inlet_dofs] = project(parabolic, basis_to=inlet_basis, I=inlet_dofs) uvp = solve(*condense(K, np.zeros_like(uvp), uvp, D=D)) velocity, pressure = np.split(uvp, [A.shape[0]])
def mono2tri(m): """Increase the size of the matrices""" mo = [[None for i in range(3)] for j in range(3)] for i in range(3): mo[i][i] = csc(m) return bmat(mo).todense()
def __init__(self, info, dataset, raw_graph, device, pretrain=None): super().__init__(info, dataset, create_embeddings=True) self.items_feature = nn.Parameter( torch.FloatTensor(self.num_items, self.embedding_size)) nn.init.xavier_normal_(self.items_feature) self.epison = 1e-8 assert isinstance(raw_graph, list) ub_graph, ui_graph, bi_graph = raw_graph bb_graph = bi_graph @ bi_graph.T # deal with weights bundle_size = bi_graph.sum(axis=1) + 1e-8 bb_graph @= sp.diags(1 / bundle_size.A.ravel()) # pooling graph bi_graph = sp.diags(1 / bundle_size.A.ravel()) @ bi_graph print_graph_density(bb_graph, 'bb graph') print_graph_density(ub_graph, 'ub graph') if ui_graph.shape == (self.num_users, self.num_items): # add self-loop atom_graph = sp.bmat([[sp.identity(ui_graph.shape[0]), ui_graph], [ui_graph.T, sp.identity(ui_graph.shape[1])]]) else: raise ValueError(r"raw_graph's shape is wrong") self.atom_graph = to_tensor(laplace_transform(atom_graph)).to(device) print('finish generating atom graph') if ub_graph.shape == (self.num_users, self.num_bundles) \ and bb_graph.shape == (self.num_bundles, self.num_bundles): # add self-loop non_atom_graph = sp.bmat( [[sp.identity(ub_graph.shape[0]), ub_graph], [ub_graph.T, bb_graph]]) else: raise ValueError(r"raw_graph's shape is wrong") self.non_atom_graph = to_tensor( laplace_transform(non_atom_graph)).to(device) print('finish generating non-atom graph') self.pooling_graph = to_tensor(bi_graph).to(device) print('finish generating pooling graph') # copy from info self.act = self.info.act self.num_layers = self.info.num_layers self.device = device # Dropouts self.mess_dropout = nn.Dropout(self.info.mess_dropout, True) self.node_dropout = nn.Dropout(self.info.node_dropout, True) # Layers self.dnns_atom = nn.ModuleList([ nn.Linear(self.embedding_size, self.embedding_size) for _ in range(self.num_layers) ]) self.dnns_non_atom = nn.ModuleList([ nn.Linear(self.embedding_size, self.embedding_size) for _ in range(self.num_layers) ]) # pretrain if not pretrain is None: self.users_feature.data = F.normalize(pretrain['users_feature']) self.items_feature.data = F.normalize(pretrain['items_feature']) self.bundles_feature.data = F.normalize( pretrain['bundles_feature'])
def read_supercell_hamiltonian(input_file="hr_truncated.dat",is_real=False,nsuper=1): """Reads an output hamiltonian for a supercell from wannier""" mt = np.genfromtxt(input_file) # get file m = mt.transpose() # transpose matrix # read the hamiltonian matrices class Hopping: pass # create empty class tlist = [] def get_t(i,j,k): norb = int(np.max([np.max(np.abs(m[3])),np.max(np.abs(m[4]))])) mo = np.matrix(np.zeros((norb,norb),dtype=np.complex)) for l in mt: # look into the file if i==int(l[0]) and j==int(l[1]) and k==int(l[2]): if is_real: mo[int(l[3])-1,int(l[4])-1] = l[5] # store element else: mo[int(l[3])-1,int(l[4])-1] = l[5] + 1j*l[6] # store element return mo # return the matrix # this function will be called in a loop g = geometry.kagome_lattice() # create geometry h = g.get_hamiltonian() # build hamiltonian h.has_spin = False nstot = nsuper**2 intra = [[None for i in range(nstot)] for j in range(nstot)] tx = [[None for i in range(nstot)] for j in range(nstot)] ty = [[None for i in range(nstot)] for j in range(nstot)] txy = [[None for i in range(nstot)] for j in range(nstot)] txmy = [[None for i in range(nstot)] for j in range(nstot)] from scipy.sparse import csc_matrix as csc vecs = [] # create the identifacion vectors inds = [] acu = 0 try: # read different supercells nsuperx = nsuper[0] nsupery = nsuper[1] nsuperz = nsuper[2] except: # read different supercells nsuperx = nsuper nsupery = nsuper nsuperz = nsuper for i in range(nsuperx): # loop over first replica for j in range(nsupery): # loop over second replica vecs.append(np.array([i,j])) # append vector inds.append(acu) acu += 1 # add one to the accumulator for i in inds: # loop over first vector for j in inds: # loop over second vector v1 = vecs[i] # position of i esim cell v2 = vecs[j] # position of j esim cell dv = v2 - v1 # difference in vector # get the different block elements intra[i][j] = csc(get_t(dv[0],dv[1],0)) tx[i][j] = csc(get_t(dv[0]+nsuper,dv[1],0)) ty[i][j] = csc(get_t(dv[0],dv[1]+nsuper,0)) txy[i][j] = csc(get_t(dv[0]+nsuper,dv[1]+nsuper,0)) txmy[i][j] = csc(get_t(dv[0]+nsuper,dv[1]-nsuper,0)) h.intra = bmat(intra).todense() h.tx = bmat(tx).todense() h.ty = bmat(ty).todense() h.txy = bmat(txy).todense() h.txmy = bmat(txmy).todense() h.geometry = read_geometry() # read the geometry of the system if nsuper>1: h.geometry = h.geometry.supercell(nsuper) # create supercell if len(h.geometry.r)!=len(h.intra): print("Dimensions do not match",len(g.r),len(h.intra)) print(h.geometry.r) # raise # error if dimensions dont match # names of the orbitals h.orbitals = get_all_orbitals()*nsuper**2 return h
def get_left_matrix(self): mesh = self.mesh NE = mesh.number_of_edges() NC = mesh.number_of_cells() hx1 = self.hx1 hy1 = self.hy1 hx3 = self.hx3 hy3 = self.hy3 itype = mesh.itype ftype = mesh.ftype idx = np.arange(NE) isBDEdge = mesh.ds.boundary_edge_flag() isYDEdge = mesh.ds.y_direction_edge_flag() isXDEdge = mesh.ds.x_direction_edge_flag() C = self.get_nonlinear_coef() A11 = spdiags(C, 0, NE, NE) # correct edge2cell = mesh.ds.edge_to_cell() I, = np.nonzero(~isBDEdge & isYDEdge) L = edge2cell[I, 0] R = edge2cell[I, 1] data = np.ones(len(I), dtype=ftype) / hx3 A12 = coo_matrix((data, (I, R)), shape=(NE, NC)) A12 += coo_matrix((-data, (I, L)), shape=(NE, NC)) I, = np.nonzero(~isBDEdge & isXDEdge) L = edge2cell[I, 0] R = edge2cell[I, 1] data = np.ones(len(I), dtype=ftype) / hy3 A12 += coo_matrix((-data, (I, R)), shape=(NE, NC)) A12 += coo_matrix((data, (I, L)), shape=(NE, NC)) A12 = A12.tocsr() cell2edge = mesh.ds.cell_to_edge() I = np.arange(NC, dtype=itype) data = np.ones(NC, dtype=ftype) # A21 = coo_matrix((data/hx1, (I, cell2edge[:, 1])), shape=(NC, NE), dtype=ftype) # A21 += coo_matrix((-data/hx1, (I, cell2edge[:, 3])), shape=(NC, NE), dtype=ftype) # A21 += coo_matrix((data/hy1, (I, cell2edge[:, 2])), shape=(NC, NE), dtype=ftype) # A21 += coo_matrix((-data/hy1, (I, cell2edge[:, 0])), shape=(NC, NE), dtype=ftype) A21 = coo_matrix((hy1 * data, (I, cell2edge[:, 1])), shape=(NC, NE), dtype=ftype) A21 += coo_matrix((-hy1 * data, (I, cell2edge[:, 3])), shape=(NC, NE), dtype=ftype) A21 += coo_matrix((hx1 * data, (I, cell2edge[:, 2])), shape=(NC, NE), dtype=ftype) A21 += coo_matrix((-hx1 * data, (I, cell2edge[:, 0])), shape=(NC, NE), dtype=ftype) A21 = A21.tocsr() A = bmat([(A11, A12), (A21, None)], format='csr', dtype=ftype) return A
mesh = make_mesh(lcar=.5**2) element = {'u': ElementVectorH1(ElementTriP2()), 'p': ElementTriP1()} basis = { variable: InteriorBasis(mesh, e, intorder=3) for variable, e in element.items() } D = np.setdiff1d(basis['u'].get_dofs().all(), basis['u'].get_dofs(mesh.boundaries['outlet']).all()) A = asm(vector_laplace, basis['u']) B = asm(divergence, basis['u'], basis['p']) C = asm(mass, basis['p']) K = bmat([[A, -B.T], [-B, None]], 'csr') uvp = np.zeros(K.shape[0]) inlet_basis = FacetBasis(mesh, element['u'], facets=mesh.boundaries['inlet']) inlet_dofs = inlet_basis.get_dofs(mesh.boundaries['inlet']).all() def parabolic(x, y): """return the plane Poiseuille parabolic inlet profile""" return 4 * y * (1. - y), np.zeros_like(y) uvp[inlet_dofs] = L2_projection(parabolic, inlet_basis, inlet_dofs) I = np.setdiff1d(np.arange(K.shape[0]), D) uvp = solve(*condense(K, 0 * uvp, uvp, I))
def intersect(h1, h2): if h1.ambiant_dimension != h2.ambiant_dimension: raise ValueError("Different ambiant\ spaces dimensions ({}!={})".format(len(w1), len(w2))) # elif pl.allclose(w1,w2) and pl.allclose(b1,b2): # print("return same object") # return copy(h1) # elif pl.allclose(w1,w2) and not pl.allclose(b1,b2): # print("return empty set") # return None #Now that the trivial cases have been removed there exists an #intersection of the two hyperplanes to obtain the new form of #the hyperplane we perform the following 3 steps: # (1)consider the intersection of two affine spaces as the intersection # of a linear space and an affine space with modified bias # (2)express the bias of the affine space in the linear space, # this gives us the bias that will be for the new affine space # (3)compute the basis of the intersection of the two linear spaces # this gives us the span of the linear space, jointly with the above # bias corresponding to the affine space from the intersection #(1) # we set h2 to be without bias and thus we alter h1 bias as follows bp = h1.bias - h2.bias #(2) A = sp.hstack([h1.basis, h2.basis]) output = sparse_lsqr(A, bp) alpha_beta_star, istop, itn = output[:3] if (istop == 2): warnings.warn("In Intersection of {} with {},\ least square solution is approximate".format(h1.name, h2.name)) # since we set h2 to be without bias we need to express the bias vector w.r.t. # the h2 basis as follows bpp = h2.basis.dot(alpha_beta_star[h1.dim:]) print("New bias is {}".format(bpp)) # (3) --------- Implement the Zassenhaus algorithm ------------- # assumes each space basis is in the same basis # first need to create the original matrix print(h1.basis.todense(), '\n\n') print(h2.basis.todense(), '\n\n') matrix = sp.bmat([[h1.basis, h2.basis], [h1.basis, None]]).T.todense() # Now we need to put the top left half in row echelon form # loop over the columns of the left half rows = range(matrix.shape[0]) for column in range(h1.dim + h2.dim): # print('start column:{}\nmatrix:\n{}\n\n'.format(column,matrix)) # compute current index and value of pivot A_{column,column} pivot = matrix[rows[column], column] # check for active pivoting to switch current row # with the one with maximum value maximum_index = matrix[rows[column:], column].argmax() + column if maximum_index > column: print('needs preventive partial pivoting') rows[column] = maximum_index rows[maximum_index] = column pivot = matrix[rows[maximum_index], column] # Loop over the rows multiplicators = matrix[rows[column + 1:], column] / pivot matrix[rows[column + 1:]] -= multiplicators.reshape( (-1, 1)) * matrix[rows[column]].reshape((1, -1)) if (pl.allclose(matrix[rows[column + 1:]], 0)): return matrix
def HBDG(coor, ax, ay, NN, NNb=None, Wj=0, cutxT=0, cutyT=0, cutxB=0, cutyB=0, Vj=0, Vsc=0, mu=0, gamx=0, gamy=0, gamz=0, alpha=0, delta=0, phi=0, meff_normal=0.026, meff_sc=0.026, g_normal=26, g_sc=26, qx=None, qy=None, Tesla=False, diff_g_factors=True, Rfactor=0, diff_alphas=False, diff_meff=False, plot_junction=False): N = coor.shape[0] #number of lattice sites Nx = int((max(coor[:, 0]) - min(coor[:, 0])) + 1) #number of lattice sites in x-direction, parallel to junction Ny = int( (max(coor[:, 1]) - min(coor[:, 1])) + 1) #number of lattice sites in y-direction, perpendicular to junction Wsc = int((Ny - Wj) / 2) #width of single superconductor D = Delta(coor=coor, Wj=Wj, delta=delta, phi=phi, cutxT=cutxT, cutyT=cutyT, cutxB=cutxB, cutyB=cutyB) if plot_junction: V = potentials.Vjj(coor=coor, Wj=Wj, Vsc=Vsc, Vj=Vj, cutxT=cutxT, cutyT=cutyT, cutxB=cutxB, cutyB=cutyB) row = [] col = [] data = [] for i in range(N): row.append(i) col.append(i) inSC, which = check.is_in_SC(i, coor, Wsc, Wj, cutxT=cutxT, cutyT=cutyT, cutxB=cutxB, cutyB=cutyB) if inSC: data.append(Rfactor) if not inSC: data.append(1) R = sparse.csc_matrix((data, (row, col)), shape=(N, N)) plots.Zeeman_profile(coor, R) plots.potential_profile(coor, V) plots.delta_profile(coor, D) QX11 = None QY11 = None if qx is not None: QX11 = -qx if qy is not None: QY11 = -qy H00 = H0(coor, ax, ay, NN, NNb=NNb, Wj=Wj, cutxT=cutxT, cutyT=cutyT, cutxB=cutxB, cutyB=cutyB, Vj=Vj, Vsc=Vsc, mu=mu, gamx=gamx, gamy=gamy, gamz=gamz, alpha=alpha, qx=qx, qy=qy, g_normal=g_normal, g_sc=g_sc, Tesla=Tesla, Rfactor=Rfactor, diff_g_factors=diff_g_factors, diff_alphas=diff_alphas, diff_meff=diff_meff, meff_normal=meff_normal, meff_sc=meff_sc) H11 = -1 * H0(coor, ax, ay, NN, NNb=NNb, Wj=Wj, cutxT=cutxT, cutyT=cutyT, cutxB=cutxB, cutyB=cutyB, Vj=Vj, Vsc=Vsc, mu=mu, gamx=gamx, gamy=gamy, gamz=gamz, alpha=alpha, qx=QX11, qy=QY11, g_normal=g_normal, g_sc=g_sc, Tesla=Tesla, Rfactor=Rfactor, diff_g_factors=diff_g_factors, diff_alphas=diff_alphas, diff_meff=diff_meff, meff_normal=meff_normal, meff_sc=meff_sc).conjugate() H01 = D H10 = -D.conjugate() H = sparse.bmat([[H00, H01], [H10, H11]], format='csc', dtype='complex') return H
tuspace = ReducedDivFreeNonConformingVirtualElementSpace2d(mesh, p, q=6) # 分片常数压力空间 tpspace = ScaledMonomialSpace2d(mesh, 0) isBdDof = tuspace.boundary_dof() tudof = tuspace.number_of_global_dofs() tpdof = tpspace.number_of_global_dofs() tuh = tuspace.function() tph = tpspace.function() A = tuspace.stiff_matrix() P = tuspace.div_matrix() F = tuspace.source_vector(pde.source) AA = bmat([[A, P.T], [P, None]], format='csr') FF = np.block([F, np.zeros(tpdof, dtype=tuspace.ftype)]) tuspace.set_dirichlet_bc(tuh, pde.dirichlet) x = np.block([tuh, tph]) isBdDof = np.block( [isBdDof, isBdDof, np.zeros(NC * idof + tpdof, dtype=np.bool)]) gdof = tudof + tpdof FF -= AA @ x bdIdx = np.zeros(gdof, dtype=np.int) bdIdx[isBdDof] = 1 Tbd = spdiags(bdIdx, 0, gdof, gdof) T = spdiags(1 - bdIdx, 0, gdof, gdof) AA = T @ AA @ T + Tbd
A, b = assemble_system(a, L, bc) A_ = mat_to_csr(A) # B block, one column per point. Represents the action of dela @ point column = assemble(inner(Constant(0), v)*dx) points = [Point(0.44, 0.21), Point(0.12, 0.4)] B_ = np.zeros((A_.shape[0], len(points))) for col, point in enumerate(points): delta = PointSource(V, point) delta.apply(column) B_[:, col] = column.array() column.zero() # The saddle system AA = bmat([[A_, B_], [B_.T, None]]) bb = np.r_[b.array(), np.zeros(len(points))] # Preconditioner diag(ML(A), I) ml = smoothed_aggregation_solver(A_) PA = ml.aspreconditioner() def Pmat_vec(x): yA = PA.matvec(x[:V.dim()]) # Identity on part of x from point sources return np.r_[yA, x[V.dim():]] P = LinearOperator(shape=AA.shape, matvec=Pmat_vec) residuals = [] # Run the iterations
def H0(coor, ax, ay, NN, NNb=None, Wj=0, cutxT=0, cutyT=0, cutxB=0, cutyB=0, Vj=0, Vsc=0, mu=0, meff_normal=0.026, meff_sc=0.026, alpha=0, gamx=0, gamy=0, gamz=0, g_normal=26, g_sc=0, qx=None, qy=None, Tesla=False, diff_g_factors=True, Rfactor=0, diff_alphas=False, diff_meff=False): N = coor.shape[0] #number of lattice sites Nx = int((max(coor[:, 0]) - min(coor[:, 0])) + 1) #number of lattice sites in x-direction, parallel to junction Ny = int( (max(coor[:, 1]) - min(coor[:, 1])) + 1) #number of lattice sites in y-direction, perpendicular to junction I = sparse.identity(N) #identity matrix of size NxN V = potentials.Vjj(coor=coor, Wj=Wj, Vsc=Vsc, Vj=Vj, cutxT=cutxT, cutyT=cutyT, cutxB=cutxB, cutyB=cutyB) #potential matrix NxN Wsc = int((Ny - Wj) / 2) #width of single superconductor k_x = kx(coor, ax, ay, NN, NNb=NNb, qx=qx) k_y = ky(coor, ax, ay, NN, NNb=NNb, qy=qy) k_x2 = kx2(coor, ax, ay, NN, NNb=NNb, qx=qx) k_y2 = ky2(coor, ax, ay, NN, NNb=NNb, qy=qy) if diff_g_factors and Tesla: row = [] col = [] data = [] for i in range(N): row.append(i) col.append(i) inSC, which = check.is_in_SC(i, coor, Wsc, Wj, cutxT=cutxT, cutyT=cutyT, cutxB=cutxB, cutyB=cutyB) if inSC: data.append(g_sc) if not inSC: data.append(g_normal) g_factor = sparse.csc_matrix((data, (row, col)), shape=(N, N)) elif diff_g_factors and not Tesla: row = [] col = [] data = [] for i in range(N): row.append(i) col.append(i) inSC, which = check.is_in_SC(i, coor, Wsc, Wj, cutxT=cutxT, cutyT=cutyT, cutxB=cutxB, cutyB=cutyB) if inSC: data.append(Rfactor) if not inSC: data.append(1) R = sparse.csc_matrix((data, (row, col)), shape=(N, N)) elif not diff_g_factors: g_factor = I * g_normal R = I if diff_meff: row = [] col = [] data = [] for i in range(N): row.append(i) col.append(i) inSC_i = check.is_in_SC(i, coor, Wsc, Wj, cutxT=cutxT, cutyT=cutyT, cutxB=cutxB, cutyB=cutyB)[0] if inSC_i: data.append(const.hbsqr_m0 / (2 * meff_sc)) else: data.append(const.hbsqr_m0 / (2 * meff_normal)) meff = sparse.csc_matrix((data, (row, col)), shape=(N, N)) elif not diff_meff: meff = const.hbsqr_m0 / (2 * meff_normal) if Tesla: H00 = (k_x2 + k_y2).multiply( meff) + V + (1 / 2) * (const.muB * gamz) * g_factor - mu * I H11 = (k_x2 + k_y2).multiply( meff) + V - (1 / 2) * (const.muB * gamz) * g_factor - mu * I H10 = alpha * (1j * k_x - k_y) * I + (1 / 2) * ( const.muB * gamx) * g_factor + 1j * (1 / 2) * (const.muB * gamy) * g_factor H01 = alpha * (-1j * k_x - k_y) * I + (1 / 2) * ( const.muB * gamx) * g_factor - 1j * (1 / 2) * (const.muB * gamy) * g_factor elif not Tesla: #Then gamx is in units of meV and R is "Reduction factor" #R is a matrix multiplying SC sites by a fraction in proportion to #the ratio of g-factors H00 = (k_x2 + k_y2).multiply(meff) - mu * I + V + gamz * R H01 = alpha * (-1j * k_x - k_y) * I + gamx * R - 1j * gamy * R H10 = alpha * (1j * k_x - k_y) * I + gamx * R + 1j * gamy * R H11 = (k_x2 + k_y2).multiply(meff) - mu * I + V - gamz * R H = sparse.bmat([[H00, H01], [H10, H11]], format='csc', dtype='complex') return H
primal_ele = assemble_firedrake(primal_lin, bcs=bcs_primal) stokes = assemble_firedrake(stokes_lin, bcs=bcs) n = H1.dim() m = P1.dim() print(m + n) A = stokes[:n, :][:, :n].toarray() B = stokes[n:n + m, :][:, :n].toarray() L = stokes[n:n + m, :][:, n:n + m].toarray() S_primal = A + np.matmul(B.T, np.linalg.solve(L, B)) S_dual = np.matmul(B, np.linalg.solve(A, B.T)) P_dual = sparse.block_diag([A, dual_ele]).toarray() P_dual_eps = sparse.block_diag([A, dual_ele_eps]).toarray() P_primal = sparse.block_diag([primal_ele, L]).toarray() K = sparse.bmat([[A, B.T], [B, None]]).toarray() fig = plt.figure() e, _ = linalg.eig(K, P_dual) e = np.sort(np.real(e)) plt.plot(e, "o", label="$\\mathcal{A}x = \\lambda \\mathcal{P}_1x$") e, _ = linalg.eig(K, P_dual_eps) e = np.sort(np.real(e)) plt.plot(e, "x", label="$\\mathcal{A}x = \\lambda \\mathcal{P}_2x$") e, _ = linalg.eig(K, P_primal) e = np.sort(np.real(e)) plt.plot(e, "+", label="$\\mathcal{A}x = \\lambda \\mathcal{P}_3x$") plt.legend() fig.savefig("stokes.png") dual_min.append(e_min_dual) dual_max.append(e_max_dual)
def two_cell_test(self, p=2, plot=True): from fealpy.pde.stokes_model_2d import StokesModelData_7 pde = StokesModelData_7() node = np.array([(-1, -1), (1, -1), (1, 1), (-1, 1), (3, -1), (3, 1)], dtype=np.float) cell = np.array([0, 1, 2, 3, 1, 4, 5, 2], dtype=np.int) cellLocation = np.array([0, 4, 8], dtype=np.int) mesh = PolygonMesh(node, cell, cellLocation) uspace = DivFreeNonConformingVirtualElementSpace2d(mesh, p) pspace = ScaledMonomialSpace2d(mesh, p - 1) ldof = pspace.number_of_local_dofs() isBdDof = uspace.boundary_dof() udof = uspace.number_of_global_dofs() pdof = pspace.number_of_global_dofs() uh = uspace.function() ph = pspace.function() uspace.set_dirichlet_bc(uh, pde.dirichlet) A = uspace.matrix_A() P = uspace.matrix_P() C = uspace.CM[:, 0, :ldof].reshape(-1) F = uspace.source_vector(pde.source) AA = bmat([[A, P.T, None], [P, None, C[:, None]], [None, C, None]], format='csr') FF = np.block([F, np.zeros(pdof + 1, dtype=uspace.ftype)]) x = np.block([uh, ph, np.zeros((1, ), dtype=uspace.ftype)]) isBdDof = np.r_['0', isBdDof, np.zeros(pdof + 1, dtype=np.bool)] gdof = udof + pdof + 1 FF -= AA @ x bdIdx = np.zeros(gdof, dtype=np.int) bdIdx[isBdDof] = 1 Tbd = spdiags(bdIdx, 0, gdof, gdof) T = spdiags(1 - bdIdx, 0, gdof, gdof) AA = T @ AA @ T + Tbd FF[isBdDof] = x[isBdDof] x[:] = spsolve(AA, FF) uh[:] = x[:udof] ph[:] = x[udof:-1] print('ph:', ph) print('uh:', uh) up = uspace.project_to_smspace(uh) print('up:', up) integralalg = uspace.integralalg error = integralalg.L2_error(pde.velocity, up) print(error) uv = uspace.project(pde.velocity) print('uproject:', uv) up = uspace.project_to_smspace(uv) print('up', up) error = integralalg.L2_error(pde.velocity, up) print(error) if plot: fig = plt.figure() axes = fig.gca() mesh.add_plot(axes) mesh.find_node(axes, showindex=True) mesh.find_edge(axes, showindex=True) plt.show()
def main(kf, is_coarse=False): mesh_size = 0.045 gb, domain = make_grid_bucket(mesh_size) # Assign parameters add_data(gb, domain, kf) # Choose and define the solvers and coupler solver_flow = pp.DualVEMMixedDim("flow") A, b = solver_flow.matrix_rhs(gb, return_bmat=True) # Select the grid of higher dimension and the position in the matrix A g_h = gb.grids_of_dimension(gb.dim_max())[0] pos_hn = [gb.node_props(g_h, "node_number")] # Determine the number of dofs [u, p] for the higher dimensional grid dof_h = A[pos_hn[0], pos_hn[0]].shape[0] # Select the co-dimensional grid positions pos_ln = [d["node_number"] for g, d in gb if g.dim < g_h.dim] # select the positions of the mortars blocks, for both the high dimensional # and lower dimensional grids num_nodes = gb.num_graph_nodes() pos_he = [] pos_le = [] for e, d in gb.edges(): gl_h = gb.nodes_of_edge(e)[1] if gl_h.dim == g_h.dim: pos_he.append(d["edge_number"] + num_nodes) else: pos_le.append(d["edge_number"] + num_nodes) # extract the blocks for the higher dimension A_h = sps.bmat(A[np.ix_(pos_hn + pos_he, pos_hn + pos_he)]) b_h = np.concatenate(tuple(b[pos_hn + pos_he])) # matrix that couple the 1 co-dimensional pressure to the mortar variables C_h = sps.bmat(A[np.ix_(pos_he, pos_ln)]) # Select the grid that realise the jump operator given the mortar variables C_l = sps.bmat(A[np.ix_(pos_ln, pos_he)]) # construct the rhs with all the active pressure dof in the 1 co-dimension if_p = np.zeros(C_h.shape[1], dtype=np.bool) pos = 0 for g, d in gb: if g.dim != g_h.dim: pos += g.num_faces # only the 1 co-dimensional grids are interesting if g.dim == g_h.dim - 1: if_p[pos:pos + g.num_cells] = True pos += g.num_cells # compute the bases num_bases = np.sum(if_p) dof_bases = C_h.shape[0] bases = np.zeros((C_h.shape[1], C_h.shape[1])) # we solve many times the same problem, better to factorize the matrix LU = sps.linalg.factorized(A_h.tocsc()) # solve to compute the ms bases functions for homogeneous boundary # conditions for dof_basis in np.where(if_p)[0]: rhs = np.zeros(if_p.size) rhs[dof_basis] = 1. # project from the co-dimensional pressure to the Robin boundary # condition rhs = np.concatenate((np.zeros(dof_h), -C_h * rhs)) x = LU(rhs) # compute the jump of the mortars bases[:, dof_basis] = C_l * x[-dof_bases:] # save = pp.Exporter(g_h, "vem"+str(dof_basis), folder="vem_ms") # save.write_vtk({'pressure': x[g_h.num_faces:dof_h]}) # solve for non-zero boundary conditions x_h = LU(b_h) # construct the problem in the fracture network A_l = np.empty((2, 2), dtype=np.object) b_l = np.empty(2, dtype=np.object) # the multiscale bases are thus inserted in the right block of the lower # dimensional problem A_l[0, 0] = sps.bmat(A[np.ix_(pos_ln, pos_ln)]) + sps.csr_matrix(bases) dof_l = A_l[0, 0].shape[0] # add to the righ-hand side the non-homogenous solution from the higher # dimensional problem b_l[0] = np.concatenate(tuple(b[pos_ln])) - C_l * x_h[-dof_bases:] # in the case of > 1 co-dimensional problems if len(pos_le) > 0: A_l[0, 1] = sps.bmat(A[np.ix_(pos_ln, pos_le)]) A_l[1, 0] = sps.bmat(A[np.ix_(pos_le, pos_ln)]) A_l[1, 1] = sps.bmat(A[np.ix_(pos_le, pos_le)]) b_l[1] = np.concatenate(tuple(b[pos_le])) # assemble and solve for the network A_l = sps.bmat(A_l, "csr") b_l = np.concatenate(tuple(b_l)) x_l = sps.linalg.spsolve(A_l, b_l) # compute the higher dimensional solution rhs = x_l[:if_p.size] rhs = np.concatenate((np.zeros(dof_h), -C_h * rhs)) x_h = LU(b_h + rhs) # save and export using standard algorithm x = np.zeros(x_h.size + x_l.size) x[:dof_h] = x_h[:dof_h] x[dof_h:(dof_h + dof_l)] = x_l[:dof_l] solver_flow.split(gb, "up", x) gb.add_node_props(["discharge", "pressure", "P0u"]) solver_flow.extract_u(gb, "up", "discharge") solver_flow.extract_p(gb, "up", "pressure") solver_flow.project_u(gb, "discharge", "P0u") save = pp.Exporter(gb, "vem", folder="vem") save.write_vtk(["pressure", "P0u"])
from scipy.sparse import bmat, identity from scipy.sparse.linalg import splu from skfem import * from skfem.models import laplace, mass m = MeshLine().refined(6) basis = Basis(m, ElementLineP1()) N = basis.N L = laplace.assemble(basis) M = mass.assemble(basis) I = identity(N) c = 1. # reduction to first order system in time A0 = bmat([[I, None], [None, M]], "csc") B0 = bmat([[None, I], [-c**2 * L, None]], "csc") # Crank-Nicolson dt = .01 theta = .5 A = A0 + theta * B0 * dt B = A0 - (1. - theta) * B0 * dt backsolve = splu(A).solve # timestepping def evolve(t, u): while t < 1: t = t + dt
def solve_problem3(m, element_type='P1', solver_type='pcg', tol=1e-8): ''' separated without BTMB ''' # equation 1 if element_type == 'P1': element1 = ElementTriP1() elif element_type == 'P2': element1 = ElementTriP2() else: raise Exception("Element not supported") basis1 = InteriorBasis(m, element1, intorder=intorder) K1 = asm(laplace, basis1) f1 = asm(f_load, basis1) wh = solve(*condense(K1, f1, D=basis1.find_dofs()), solver=solver_iter_mgcg_iter(tol=tol)) # equation 2 element2 = ElementTriMorley() basis2 = InteriorBasis(m, element2, intorder=intorder) K2 = asm(zv_load, basis2) f2 = asm(laplace, basis1, basis2) * wh zh = solve(*condense(K2, f2, D=easy_boundary(basis2)), solver=solver_iter_mgcg_iter(tol=tol)) # equation 3 element3 = {'phi': ElementVectorH1(ElementTriCR()), 'p': ElementTriP0()} basis3 = { variable: InteriorBasis(m, e, intorder=intorder) for variable, e in element3.items() } A = asm(phipsi_load1, basis3['phi']) + epsilon**2 * asm(phipsi_load2, basis3['phi']) B = asm(phiq_load, basis3['phi'], basis3['p']) C = asm(mass, basis3['p']) / alpha F1 = asm(zpsi_load, basis2, basis3['phi']) * zh f3 = np.concatenate([F1, np.zeros(B.shape[0])]) K3 = bmat([[A, -B.T], [-B, C * 0]], 'csr') K, f, _, I_withp = condense(K3, f3, D=basis3['phi'].find_dofs()) len_condensed = K.shape[0] - C.shape[0] invC = sparse.eye(C.shape[0]) * C.shape[0] * alpha I = I_withp[:-C.shape[0]] B_reshaped = B.T[I].T # multilevel_solver = pyamg.ruge_stuben_solver(K[:len_condensed, :len_condensed]) multilevel_solver = pyamg.ruge_stuben_solver( K[:len_condensed, :len_condensed]) M11_op = multilevel_solver.aspreconditioner() def matvec(b): u2 = invC * b[len_condensed:] u1 = M11_op.matvec(b[:len_condensed] - B_reshaped.T * u2) return np.append(u1, -invC * B_reshaped * u1 - u2) M = LinearOperator(K.shape, matvec) gmres_time_start = time.time() phip_minres_full_gmres = solve(K, f, solver=solver_iter_krylov_iter( spl.gmres, M=M, tol=gmres_tol)) gmres_time_end = time.time() out_phip = np.zeros(K3.shape[0]) out_phip[I_withp] = phip_minres_full_gmres phih, ph3 = np.split(out_phip, [A.shape[0]]) # equation 4 element4 = ElementTriMorley() basis4 = InteriorBasis(m, element4, intorder=intorder) K4 = asm(uchi_load, basis4) f4 = asm(phichi_load, basis3['phi'], basis4) * phih uh0 = solve(*condense(K4, f4, D=easy_boundary(basis4)), solver=solver_iter_mgcg_iter(tol=tol)) print('GMRES Time Cost {:.3e} s'.format(gmres_time_end - gmres_time_start)) print('dofs:', K.shape[0]) return uh0, {'u': basis4}
def solve_poisson_2d(self, n=3, p=0, plot=True): pde = CosCosData() mesh = pde.init_mesh(n=n, meshtype='tri') space = RaviartThomasFiniteElementSpace2d(mesh, p=p) udof = space.number_of_global_dofs() pdof = space.smspace.number_of_global_dofs() gdof = udof + pdof uh = space.function() ph = space.smspace.function() A = space.stiff_matrix() B = space.div_matrix() F1 = space.source_vector(pde.source) AA = bmat([[A, -B], [-B.T, None]], format='csr') if True: F0 = space.neumann_boundary_vector(pde.dirichlet) FF = np.r_['0', F0, F1] x = spsolve(AA, FF).reshape(-1) uh[:] = x[:udof] ph[:] = x[udof:] error0 = space.integralalg.L2_error(pde.flux, uh) def f(bc): xx = mesh.bc_to_point(bc) return (pde.solution(xx) - ph(xx))**2 error1 = space.integralalg.integral(f) print(error0, error1) else: isBdDof = space.set_dirichlet_bc(uh, pde.neumann) x = np.r_['0', uh, ph] isBdDof = np.r_['0', isBdDof, np.zeros(pdof, dtype=np.bool_)] FF = np.r_['0', np.zeros(udof, dtype=np.float64), F1] FF -= AA @ x bdIdx = np.zeros(gdof, dtype=np.int) bdIdx[isBdDof] = 1 Tbd = spdiags(bdIdx, 0, gdof, gdof) T = spdiags(1 - bdIdx, 0, gdof, gdof) AA = T @ AA @ T + Tbd FF[isBdDof] = x[isBdDof] x[:] = spsolve(AA, FF) uh[:] = x[:udof] ph[:] = x[udof:] error0 = space.integralalg.L2_error(pde.flux, uh) def f(bc): xx = mesh.bc_to_point(bc) return (pde.solution(xx) - ph(xx))**2 error1 = space.integralalg.integral(f) print(error0, error1) if plot: box = [-0.5, 1.5, -0.5, 1.5] fig = plt.figure() axes = fig.gca() mesh.add_plot(axes, box=box) #mesh.find_node(axes, showindex=True) #mesh.find_edge(axes, showindex=True) #mesh.find_cell(axes, showindex=True) #node = ps.reshape(-1, 2) #uv = phi.reshape(-1, 2) #axes.quiver(node[:, 0], node[:, 1], uv[:, 0], uv[:, 1]) plt.show()
def filter_ppi_patients(ppi_total, mut_total, ppi_filt, final_influence, ngh_max, keep_singletons=False, min_mutation=10, max_mutation=2000): """Keeping only the connections with the best influencers and Filtering some patients based on mutation number 'the 11 most influential neighbors of each gene in the network as determined by network influence distance were used' 'Only mutation data generated using the Illumina GAIIx platform were retained for subsequent analy- sis, and patients with fewer than 10 mutations were discarded.' Parameters ---------- ppi_total : sparse matrix Built from all sparse sub-matrices (AA, ... , CC). mut_total : sparse matrix Patients' mutation profiles of all genes (rows: patients, columns: genes of AA, BB and CC). ppi_filt : sparse matrix Filtration from ppi_total : only genes in PPI are considered. final_influence : Smoothed PPI influence matrices based on minimum or maximum weight. ngh_max : int Number of best influencers in PPI. keep_singletons : boolean, default: False If True, proteins not annotated in PPI (genes founded only in patients' mutation profiles) will be also considered. If False, only annotated proteins in PPI will be considered. min_mutation, max_mutation : int Numbers of lowest mutations and highest mutations per patient. Returns ------- ppi_final, mut_final : sparse matrix PPI and mutation profiles after filtering. """ # n = final_influence.shape[0] # final_influence = index_to_sym_matrix(n, final_influence) ppi_ngh = best_neighboors(ppi_filt, final_influence, ngh_max) # print('ppi_ngh ', ppi_ngh.dtype) deg0 = Ppi(ppi_total).deg == 0 # True if protein degree = 0 if keep_singletons: ppi_final = sp.bmat( [[ppi_ngh, sp.csc_matrix((ppi_ngh.shape[0], sum(deg0)))], [ sp.csc_matrix((sum(deg0), ppi_ngh.shape[0])), sp.csc_matrix((sum(deg0), sum(deg0))) ]]) # -> COO matrix # mut_final=sp.bmat([[mut_total[:,deg0==False],mut_total[:,deg0==True]]]) mut_final = mut_total else: ppi_final = ppi_ngh mut_final = mut_total[:, Ppi(ppi_total).deg > 0] # filtered_patients = np.array([k < min_mutation or k > max_mutation for k in Patient(mut_final).mut_per_patient]) # mut_final = mut_final[filtered_patients == False, :] # to avoid worse comparison '== False' mut_final = mut_final[np.array([ min_mutation < k < max_mutation for k in Patient(mut_final).mut_per_patient ])] print( " Removing %i patients with less than %i or more than %i mutations" % (mut_total.shape[0] - mut_final.shape[0], min_mutation, max_mutation)) # print("New adjacency matrix:", ppi_final.shape) # print("New mutation profile matrix:", mut_final.shape) return ppi_final, mut_final
def mono2bi(m): """Increase the size of the matrices""" return bmat([[csc(m), None], [None, csc(m)]]).todense()
def mkbigD(m, track_flows=False, use_correction=False): '''with Q correction''' matlist_flow = mkflowmat(m) matlist_proc = mkprocmat(m) if use_correction == True: matlist_flow_Q = mkflowmatQ(m) matlist_proc_Q = mkprocmatQ(m) # check for same shape of all matrices matshp = matlist_flow[0].shape for m in matlist_flow + matlist_proc: if m.shape != matshp: print("mkbigD: inconsistent matrix dimensions. Aborting!\n") sys.exit(1) # add matrices for intercell transport and intracell processes matlist = [] outbigD = [] if use_correction == True: matlist_Q = [] for ts in arange(0, len(matlist_flow)): matlist.append(matlist_flow[ts] + matlist_proc[ts]) outbigD.append(matlist_flow[ts] + matlist_proc[ts]) if use_correction == True: matlist_Q.append(matlist_flow_Q[ts] + matlist_proc_Q[ts]) # construct proper diagonals for ts in arange(0, len(matlist)): # seperate matrices from their diagonals # define todense() since it can not work in high resolution FY array_matlist1 = zeros((matlist[ts].shape[0], matlist[ts].shape[1])) for i in range(matlist[ts].shape[0]): array_matlist1[i, :] = matlist[ts][i, :].todense() #diagonal=diag(matlist[ts].todense()) diagonal = diag(array_matlist1) #FY matlist[ts] = matlist[ts] - sp.spdiags( diagonal, 0, matshp[0], matshp[1], format="csc") if use_correction == True: diagonal_Q = diag(matlist_Q[ts].todense()) matlist_Q[ts] = matlist_Q[ts] - sp.spdiags( diagonal_Q, 0, matshp[0], matshp[1], format="csc") # put losses by transport to other cells on diagonal and # put back intra-cell loss with negative sign #loss=sum(matlist[ts].todense(), axis=0) array_matlist2 = zeros((matlist[ts].shape[0], matlist[ts].shape[1])) for i in range(matlist[ts].shape[0]): array_matlist2[i, :] = matlist[ts][i, :].todense() loss = sum(array_matlist2, axis=0) #FY if use_correction == True: outbigD[ts]=matlist_Q[ts]\ -sp.spdiags(loss,0,matshp[0],matshp[1],format="csc")\ -sp.spdiags(diagonal,0,matshp[0],matshp[1],format="csc") else: outbigD[ts]=matlist[ts]\ -sp.spdiags(loss,0,matshp[0],matshp[1],format="csc")\ -sp.spdiags(diagonal,0,matshp[0],matshp[1],format="csc") if track_flows == True: diagonals = -sp.spdiags(loss,0,matshp[0],matshp[1],format="csc")\ -sp.spdiags(diagonal,0,matshp[0],matshp[1],format="csc") outbigD[ts] = sp.bmat([[ outbigD[ts], None],[diagonals,\ sp.csc_matrix(numpy.zeros(matshp))]]) return (outbigD)