def f(x, y, z): # z := - W**-T * z z[:n] = -div( z[:n], d1 ) z[n:2*n] = -div( z[n:2*n], d2 ) z[2*n:] -= 2.0*v*( v[0]*z[2*n] - blas.dot(v[1:], z[2*n+1:]) ) z[2*n+1:] *= -1.0 z[2*n:] /= beta # x := x - G' * W**-1 * z x[:n] -= div(z[:n], d1) - div(z[n:2*n], d2) + As.T * z[-(m+1):] x[n:] += div(z[:n], d1) + div(z[n:2*n], d2) # Solve for x[:n]: # # S*x[:n] = x[:n] - (W1**2 - W2**2)(W1**2 + W2**2)^-1 * x[n:] x[:n] -= mul( div(d1**2 - d2**2, d1**2 + d2**2), x[n:]) lapack.potrs(S, x) # Solve for x[n:]: # # (d1**-2 + d2**-2) * x[n:] = x[n:] + (d1**-2 - d2**-2)*x[:n] x[n:] += mul( d1**-2 - d2**-2, x[:n]) x[n:] = div( x[n:], d1**-2 + d2**-2) # z := z + W^-T * G*x z[:n] += div( x[:n] - x[n:2*n], d1) z[n:2*n] += div( -x[:n] - x[n:2*n], d2) z[2*n:] += As*x[:n]
def g(x, y, z): x[:iC] = 0.5 * ( x[:iC] - mul(d3, x[iC:]) + mul(d1, z[:iC] + mul(d3, z[:iC])) - mul(d2, z[iC:] - mul(d3, z[iC:])) ) x[:iC] = div(x[:iC], ds) # Solve # # S * v = 0.5 * A * D^-1 * ( bx[:n] # - (D2-D1)*(D1+D2)^-1 * bx[n:] # + D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bz[:n] # - D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bz[n:] ) blas.gemv(mmAsc, x, vvV) lapack.potrs(mmS, vvV) # x[:n] = D^-1 * ( rhs - A'*v ). blas.gemv(mmAsc, vvV, x, alpha=-1.0, beta=1.0, trans="T") x[:iC] = div(x[:iC], ds) # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bz[:n] - D2*bz[n:] ) # - (D2-D1)*(D1+D2)^-1 * x[:n] x[iC:] = div(x[iC:] - mul(d1, z[:iC]) - mul(d2, z[iC:]), d1 + d2) - mul(d3, x[:iC]) # z[:n] = D1^1/2 * ( x[:n] - x[n:] - bz[:n] ) # z[n:] = D2^1/2 * ( -x[:n] - x[n:] - bz[n:] ). z[:iC] = mul(W["di"][:iC], x[:iC] - x[iC:] - z[:iC]) z[iC:] = mul(W["di"][iC:], -x[:iC] - x[iC:] - z[iC:])
def g(x, y, z): x[:n] = 0.5 * ( x[:n] - mul(d3, x[n:]) + mul(d1, z[:n] + mul(d3, z[:n])) - mul(d2, z[n:] - mul(d3, z[n:])) ) x[:n] = div( x[:n], ds) # Solve # # S * v = 0.5 * A * D^-1 * ( bx[:n] - # (D2-D1)*(D1+D2)^-1 * bx[n:] + # D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bzl[:n] - # D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bzl[n:] ) blas.gemv(Asc, x, v) lapack.potrs(S, v) # x[:n] = D^-1 * ( rhs - A'*v ). blas.gemv(Asc, v, x, alpha=-1.0, beta=1.0, trans='T') x[:n] = div(x[:n], ds) # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bzl[:n] - D2*bzl[n:] ) # - (D2-D1)*(D1+D2)^-1 * x[:n] x[n:] = div( x[n:] - mul(d1, z[:n]) - mul(d2, z[n:]), d1+d2 )\ - mul( d3, x[:n] ) # zl[:n] = D1^1/2 * ( x[:n] - x[n:] - bzl[:n] ) # zl[n:] = D2^1/2 * ( -x[:n] - x[n:] - bzl[n:] ). z[:n] = mul( W['di'][:n], x[:n] - x[n:] - z[:n] ) z[n:] = mul( W['di'][n:], -x[:n] - x[n:] - z[n:] )
def loglikelyhood_grad_cvxopt(xxf,extra_args,to_CVXOPT=False): # implement BLAS and LAPACK stuff! """ Computes gradient vector """ if not to_CVXOPT: grad= mw.fitter_s.loglikelyhood_grad(np.array(xxf).flatten(),*extra_args) else: case,sin,sout,selfs,M,nvarx,nvary,inds_selfs = extra_args[:8] x = xxf[:nvarx] y = xxf[nvarx:] if case == 'W': aux = 1.-np.einsum('ik,jk',x,y) # lapack! (to do) elif case == 'B': aux = 1.+np.einsum('ik,jk',x,y) # lapack! (to do) else: aux = np.ones((nvarx,nvary,1)) #assert(np.all(aux>epsilon)) aux = 1./aux if not selfs: aa = aux.flatten() aa[inds_selfs] = 0 aux = aa.reshape(nvarx,nvary) g1 = cvxopt.div(sout,(x+epsilon)) - M*np.einsum('jk,ij',y,aux) g2 = cvxopt.div(sin ,(y+epsilon)) - M*np.einsum('ik,ij',x,aux) grad = -np.r_[g1,g2] return cvxopt.matrix(grad,(grad.shape[0],1),'d')
def F(x=None, z=None): if x is None: return 0, matrix(0.0, (2,1)) w = exp(A*x) f = c.T*x + sum(log(1+w)) grad = c + A.T * div(w, 1+w) if z is None: return f, grad.T H = A.T * spdiag(div(w,(1+w)**2)) * A return f, grad.T, z[0]*H
def F(x=None, z=None): if x is None: return 0, matrix(0.0, (n+1,1)) w = exp(A*x) f = dot(c,x) + sum(log(1+w)) grad = c + A.T * div(w, 1+w) if z is None: return matrix(f), grad.T H = A.T * spdiag(div(w,(1+w)**2)) * A return matrix(f), grad.T, z[0]*H
def F(x = None, z = None): if x is None: return 0, matrix(0.0, (3,1)) if max(abs(x)) >= 1.0: return None u = 1 - x**2 val = -sum(log(u)) Df = div(2*x, u).T if z is None: return val, Df H = spdiag(2 * z[0] * div(1 + u**2, u**2)) return val, Df, H
def F(x=None, z=None): if x is None: return 0, matrix(0.0,(n,1)) y = A*x+b if max(abs(y)) >= 1.0: return None f = -sum(log(1.0 - y**2)) gradf = 2.0 * A.T * div(y, 1-y**2) if z is None: return f, gradf.T H = A.T * spdiag(2.0*z[0]*div(1.0+y**2,(1.0-y**2)**2))*A return f,gradf.T,H
def Fkkt(W): # Factor # # S = A*D^-1*A' + I # # where D = 2*D1*D2*(D1+D2)^-1, D1 = d[:n]**2, D2 = d[n:]**2. d1, d2 = W['di'][:n]**2, W['di'][n:]**2 # ds is square root of diagonal of D ds = sqrt(2.0) * div( mul( W['di'][:n], W['di'][n:]), sqrt(d1+d2) ) d3 = div(d2 - d1, d1 + d2) # Asc = A*diag(d)^-1/2 blas.copy(A, Asc) for k in range(m): blas.tbsv(ds, Asc, n=n, k=0, ldA=1, incx=m, offsetx=k) # S = I + A * D^-1 * A' blas.syrk(Asc, S) S[::m+1] += 1.0 lapack.potrf(S) def g(x, y, z): x[:n] = 0.5 * ( x[:n] - mul(d3, x[n:]) + \ mul(d1, z[:n] + mul(d3, z[:n])) - \ mul(d2, z[n:] - mul(d3, z[n:])) ) x[:n] = div( x[:n], ds) # Solve # # S * v = 0.5 * A * D^-1 * ( bx[:n] # - (D2-D1)*(D1+D2)^-1 * bx[n:] # + D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bz[:n] # - D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bz[n:] ) blas.gemv(Asc, x, v) lapack.potrs(S, v) # x[:n] = D^-1 * ( rhs - A'*v ). blas.gemv(Asc, v, x, alpha=-1.0, beta=1.0, trans='T') x[:n] = div(x[:n], ds) # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bz[:n] - D2*bz[n:] ) # - (D2-D1)*(D1+D2)^-1 * x[:n] x[n:] = div( x[n:] - mul(d1, z[:n]) - mul(d2, z[n:]), d1+d2 )\ - mul( d3, x[:n] ) # z[:n] = D1^1/2 * ( x[:n] - x[n:] - bz[:n] ) # z[n:] = D2^1/2 * ( -x[:n] - x[n:] - bz[n:] ). z[:n] = mul( W['di'][:n], x[:n] - x[n:] - z[:n] ) z[n:] = mul( W['di'][n:], -x[:n] - x[n:] - z[n:] ) return g
def Fkkt(W): # Factor # # S = A*D^-1*A' + I # # where D = 2*D1*D2*(D1+D2)^-1, D1 = d[:n]**-2, D2 = d[n:]**-2. d1, d2 = W['di'][:n]**2, W['di'][n:]**2 # ds is square root of diagonal of D ds = math.sqrt(2.0) * div( mul( W['di'][:n], W['di'][n:]), sqrt(d1+d2) ) d3 = div(d2 - d1, d1 + d2) # Asc = A*diag(d)^-1/2 Asc = A * spdiag(ds**-1) # S = I + A * D^-1 * A' blas.syrk(Asc, S) S[::m+1] += 1.0 lapack.potrf(S) def g(x, y, z): x[:n] = 0.5 * ( x[:n] - mul(d3, x[n:]) + mul(d1, z[:n] + mul(d3, z[:n])) - mul(d2, z[n:] - mul(d3, z[n:])) ) x[:n] = div( x[:n], ds) # Solve # # S * v = 0.5 * A * D^-1 * ( bx[:n] - # (D2-D1)*(D1+D2)^-1 * bx[n:] + # D1 * ( I + (D2-D1)*(D1+D2)^-1 ) * bzl[:n] - # D2 * ( I - (D2-D1)*(D1+D2)^-1 ) * bzl[n:] ) blas.gemv(Asc, x, v) lapack.potrs(S, v) # x[:n] = D^-1 * ( rhs - A'*v ). blas.gemv(Asc, v, x, alpha=-1.0, beta=1.0, trans='T') x[:n] = div(x[:n], ds) # x[n:] = (D1+D2)^-1 * ( bx[n:] - D1*bzl[:n] - D2*bzl[n:] ) # - (D2-D1)*(D1+D2)^-1 * x[:n] x[n:] = div( x[n:] - mul(d1, z[:n]) - mul(d2, z[n:]), d1+d2 )\ - mul( d3, x[:n] ) # zl[:n] = D1^1/2 * ( x[:n] - x[n:] - bzl[:n] ) # zl[n:] = D2^1/2 * ( -x[:n] - x[n:] - bzl[n:] ). z[:n] = mul( W['di'][:n], x[:n] - x[n:] - z[:n] ) z[n:] = mul( W['di'][n:], -x[:n] - x[n:] - z[n:] ) return g
def F(x=None, z=None): if x is None: return 5, matrix(17*[0.0] + 5*[1.0]) if min(x[17:]) <= 0.0: return None f = -x[12:17] + div(Amin, x[17:]) Df = matrix(0.0, (5,22)) Df[:,12:17] = spmatrix(-1.0, range(5), range(5)) Df[:,17:] = spmatrix(-div(Amin, x[17:]**2), range(5), range(5)) if z is None: return f, Df H = spmatrix( 2.0* mul(z, div(Amin, x[17::]**3)), range(17,22), range(17,22) ) return f, Df, H
def f(x, y, z): minor = 0 if not helpers.sp_minor_empty(): minor = helpers.sp_minor_top() else: global loopf loopf += 1 minor = loopf helpers.sp_create("00-f", minor) # z := - W**-T * z z[:n] = -div( z[:n], d1 ) z[n:2*n] = -div( z[n:2*n], d2 ) z[2*n:] -= 2.0*v*( v[0]*z[2*n] - blas.dot(v[1:], z[2*n+1:]) ) z[2*n+1:] *= -1.0 z[2*n:] /= beta # x := x - G' * W**-1 * z x[:n] -= div(z[:n], d1) - div(z[n:2*n], d2) + As.T * z[-(m+1):] x[n:] += div(z[:n], d1) + div(z[n:2*n], d2) helpers.sp_create("15-f", minor) # Solve for x[:n]: # # S*x[:n] = x[:n] - (W1**2 - W2**2)(W1**2 + W2**2)^-1 * x[n:] x[:n] -= mul( div(d1**2 - d2**2, d1**2 + d2**2), x[n:]) helpers.sp_create("25-f", minor) lapack.potrs(S, x) helpers.sp_create("30-f", minor) # Solve for x[n:]: # # (d1**-2 + d2**-2) * x[n:] = x[n:] + (d1**-2 - d2**-2)*x[:n] x[n:] += mul( d1**-2 - d2**-2, x[:n]) helpers.sp_create("35-f", minor) x[n:] = div( x[n:], d1**-2 + d2**-2) helpers.sp_create("40-f", minor) # z := z + W^-T * G*x z[:n] += div( x[:n] - x[n:2*n], d1) helpers.sp_create("44-f", minor) z[n:2*n] += div( -x[:n] - x[n:2*n], d2) helpers.sp_create("48-f", minor) z[2*n:] += As*x[:n] helpers.sp_create("50-f", minor)
def g(x, y, z): """ Solve [ I 0 D' -D' ] [x[:n] ] [bx[:n] ] [ 0 0 -I -I ] [x[n:] ] = [bx[n:] ] [ D -I -D1 0 ] [z[:n-1] ] [bz[:n-1] ] [ -D -I 0 -D2 ] [z[n-1:] ] [bz[n-1:] ]. First solve S*x[:n] = bx[:n] + D' * ( (d1-d2) ./ (d1+d2) .* bx[n:] + 2*d1.*d2./(d1+d2) .* (bz[:n-1] - bz[n-1:]) ). Then take x[n:] = (d1+d2)^-1 .* ( bx[n:] - d1.*bz[:n-1] - d2.*bz[n-1:] + (d1-d2) .* D*x[:n] ) z[:n-1] = d1 .* (D*x[:n] - x[n:] - bz[:n-1]) z[n-1:] = d2 .* (-D*x[:n] - x[n:] - bz[n-1:]). """ # y = (d1-d2) ./ (d1+d2) .* bx[n:] + # 2*d1.*d2./(d1+d2) .* (bz[:n-1] - bz[n-1:]) y = mul( div(d1-d2, d1+d2), x[n:]) + \ mul( 0.5*d, z[:n-1]-z[n-1:] ) # x[:n] += D*y x[:n-1] -= y x[1:n] += y # x[:n] := S^-1 * x[:n] lapack.pttrs(Sd, Se, x) # u = D*x[:n] u = x[1:n] - x[0:n-1] # x[n:] = (d1+d2)^-1 .* ( bx[n:] - d1.*bz[:n-1] # - d2.*bz[n-1:] + (d1-d2) .* u) x[n:] = div( x[n:] - mul(d1, z[:n-1]) - mul(d2, z[n-1:]) + mul(d1-d2, u), d1+d2 ) # z[:n-1] = d1 .* (D*x[:n] - x[n:] - bz[:n-1]) # z[n-1:] = d2 .* (-D*x[:n] - x[n:] - bz[n-1:]) z[:n-1] = mul(W['di'][:n-1], u - x[n:] - z[:n-1]) z[n-1:] = mul(W['di'][n-1:], -u - x[n:] - z[n-1:])
def Hf(u, v, alpha = 1.0, beta = 0.0): """ v := alpha * (A'*A*u + 2*((1+w)./(1-w)).*u + beta *v """ v *= beta v += 2.0 * alpha * mul(div(1.0+w, (1.0-w)**2), u) blas.gemv(A, u, r) blas.gemv(A, r, v, alpha = alpha, beta = 1.0, trans = 'T')
def vdf_cost(t0, c, f): ''' t0: nd-array with the free flow travel times c: nd-array with the nominal capacities f: nd-array with the total flows on arcs ''' x = div(f,c) bpr = mul(t0, 1 + 0.15 * (x ** 4)) return bpr.T * f
def F(x=None, z=None): if x is None: return 0, matrix(0.0, (n,1)) y = A*x-b w = sqrt(rho + y**2) f = sum(w) Df = div(y, w).T * A if z is None: return f, Df H = A.T * spdiag(z[0]*rho*(w**-3)) * A return f, Df, H
def vdf_derivative(t0, c, f): ''' t0: nd-array with the free flow travel times c: nd-array with the nominal capacities f: nd-array with the total flows on arcs ''' x = div(f,c) bpr_d = 1 + 0.75 * (x ** 4) return mul(t0, bpr_d)
def normalize_cols(X): """ @param X: the matrix @type X: cvxopt dense matrix @return: the col-normalized matrix @rtype: cvxopt dense matrix """ d = diagonal_vec(X.T*X) N = co.sqrt(ones_vec(X.size[0])*d.T) return co.div(X,N)
def train(self, test_users=None): self.model = self.ratings.T * self.ratings diag = utc.diagonal_vec(self.model) row_mat = diag * utc.ones_vec(self.n_items).T col_mat = utc.ones_vec(self.n_items) * diag.T row_mat **= self.alpha col_mat **= 1 - self.alpha self.model = co.div(self.model, co.mul(row_mat, col_mat)) self.model = self.model**self.locality
def normalize_rows(X): """ @param X: the matrix @type X: cvxopt dense matrix @return: the row-normalized matrix @rtype: cvxopt dense matrix """ d = diagonal_vec(X*X.T) N = co.sqrt(d * ones_vec(X.size[1]).T) return co.div(X,N)
def d2Ibr_dV2(Ybr, V, lam): """ Computes 2nd derivatives of complex branch current w.r.t. voltage. """ nb = len(V) diaginvVm = spdiag(div(matrix(1.0, (nb, 1)), abs(V))) Haa = spdiag(mul(-(Ybr.T * lam), V)) Hva = -1j * Haa * diaginvVm Hav = Hva Hvv = spmatrix([], [], [], (nb, nb)) return Haa, Hav, Hva, Hvv
def compute_delays(l, ffdelays, pm, type='Polynomial'): """Compute delays given linkflows l""" n, d = pm.size delays = matrix(0.0, (n,1)) if type == 'Polynomial': for i in range(n): delays[i] = ffdelays[i] + pm[i,:] * matrix(np.power(l[i],range(1,d+1))) if type == 'Hyperbolic': ks = matrix([[ffdelays-div(pm[:,0],pm[:,1])], [pm]]) for i in range(n): delays[i] = ks[i,0] + ks[i,1]/(ks[i,2]-l[i]) return delays
def Fkkt(W): # Returns a function f(x, y, z) that solves # # [ 0 0 P' -P' ] [ x[:n] ] [ bx[:n] ] # [ 0 0 -I -I ] [ x[n:] ] [ bx[n:] ] # [ P -I -D1^{-1} 0 ] [ z[:m] ] = [ bz[:m] ] # [-P -I 0 -D2^{-1} ] [ z[m:] ] [ bz[m:] ] # # where D1 = diag(di[:m])^2, D2 = diag(di[m:])^2 and di = W['di']. # # On entry bx, bz are stored in x, z. # On exit x, z contain the solution, with z scaled (di .* z is # returned instead of z). # Factor A = 4*P'*D*P where D = d1.*d2 ./(d1+d2) and # d1 = d[:m].^2, d2 = d[m:].^2. di = W['di'] d1, d2 = di[:m]**2, di[m:]**2 D = div( mul(d1,d2), d1+d2 ) Ds = spdiag(2 * sqrt(D)) base.gemm(Ds, P, Ps) blas.syrk(Ps, A, trans = 'T') lapack.potrf(A) def f(x, y, z): # Solve for x[:n]: # # A*x[:n] = bx[:n] + P' * ( ((D1-D2)*(D1+D2)^{-1})*bx[n:] # + (2*D1*D2*(D1+D2)^{-1}) * (bz[:m] - bz[m:]) ). blas.copy(( mul( div(d1-d2, d1+d2), x[n:]) + mul( 2*D, z[:m]-z[m:] ) ), u) blas.gemv(P, u, x, beta = 1.0, trans = 'T') lapack.potrs(A, x) # x[n:] := (D1+D2)^{-1} * (bx[n:] - D1*bz[:m] - D2*bz[m:] # + (D1-D2)*P*x[:n]) base.gemv(P, x, u) x[n:] = div( x[n:] - mul(d1, z[:m]) - mul(d2, z[m:]) + mul(d1-d2, u), d1+d2 ) # z[:m] := d1[:m] .* ( P*x[:n] - x[n:] - bz[:m]) # z[m:] := d2[m:] .* (-P*x[:n] - x[n:] - bz[m:]) z[:m] = mul(di[:m], u-x[n:]-z[:m]) z[m:] = mul(di[m:], -u-x[n:]-z[m:]) return f
def solver(graph, update=False, data=None, SO=False, random=False): """Solve for the UE equilibrium using link-path formulation Parameters ---------- graph: graph object update: if True, update link and path flows in graph data: (P,U,r) P: link-path incidence matrix U,r: simplex constraints SO: if True compute SO random: if True, initialize with a random feasible point """ type = graph.links.values()[0].delayfunc.type if data is None: P = linkpath_incidence(graph) U,r = path_to_OD_simplex(graph) else: P,U,r = data m = graph.numpaths A, b = spmatrix(-1.0, range(m), range(m)), matrix(0.0, (m,1)) ffdelays = graph.get_ffdelays() if type == 'Polynomial': coefs = graph.get_coefs() if not SO: coefs = coefs * spdiag([1.0/(j+2) for j in range(coefs.size[1])]) parameters = matrix([[ffdelays], [coefs]]) G = ue.objective_poly if type == 'Hyperbolic': ks = graph.get_ks() parameters = matrix([[ffdelays-div(ks[:,0],ks[:,1])], [ks]]) G = ue.objective_hyper def F(x=None, z=None): if x is None: return 0, solver_init(U,r,random) if z is None: f, Df = G(P*x, z, parameters, 1) return f, Df*P f, Df, H = G(P*x, z, parameters, 1) return f, Df*P, P.T*H*P failed = True while failed: x = solvers.cp(F, G=A, h=b, A=U, b=r)['x'] l = ue.solver(graph, SO=SO) error = np.linalg.norm(P * x - l,1) / np.linalg.norm(l,1) if error > TOL: print 'error={} > {}, re-compute path_flow'.format(error, TOL) else: failed = False if update: logging.info('Update link flows, delays in Graph.'); graph.update_linkflows_linkdelays(P*x) logging.info('Update path delays in Graph.'); graph.update_pathdelays() logging.info('Update path flows in Graph object.'); graph.update_pathflows(x) # assert if x is a valid UE/SO return x, l
def f(x, y, z): # Solve for x[:n]: # # A*x[:n] = bx[:n] + P' * ( ((D1-D2)*(D1+D2)^{-1})*bx[n:] # + (2*D1*D2*(D1+D2)^{-1}) * (bz[:m] - bz[m:]) ). x[:n] += P.T * ( mul( div(d1-d2, d1+d2), x[n:]) + mul( 2*D, z[:m]-z[m:] ) ) lapack.potrs(A, x) # x[n:] := (D1+D2)^{-1} * (bx[n:] - D1*bz[:m] - D2*bz[m:] # + (D1-D2)*P*x[:n]) u = P*x[:n] x[n:] = div( x[n:] - mul(d1, z[:m]) - mul(d2, z[m:]) + mul(d1-d2, u), d1+d2 ) # z[:m] := d1[:m] .* ( P*x[:n] - x[n:] - bz[:m]) # z[m:] := d2[m:] .* (-P*x[:n] - x[n:] - bz[m:]) z[:m] = mul(di[:m], u-x[n:]-z[:m]) z[m:] = mul(di[m:], -u-x[n:]-z[m:])
def Fkkt(x, z, W): ds = (2.0 * div(1 + x**2, (1 - x**2)**2))**-0.5 Asc = A * spdiag(ds) blas.syrk(Asc, S) S[::m+1] += 1.0 lapack.potrf(S) a = z[0] def g(x, y, z): x[:] = mul(x, ds) / a blas.gemv(Asc, x, v) lapack.potrs(S, v) blas.gemv(Asc, v, x, alpha = -1.0, beta = 1.0, trans = 'T') x[:] = mul(x, ds) return g
def test_basic(self): import cvxopt a = cvxopt.matrix([1.0,2.0,3.0]) b = cvxopt.matrix([3.0,-2.0,-1.0]) c = cvxopt.spmatrix([1.0,-2.0,3.0],[0,2,4],[1,2,4],(6,5)) d = cvxopt.spmatrix([1.0,2.0,5.0],[0,1,2],[0,0,0],(3,1)) self.assertEqualLists(list(cvxopt.mul(a,b)),[3.0,-4.0,-3.0]) self.assertAlmostEqualLists(list(cvxopt.div(a,b)),[1.0/3.0,-1.0,-3.0]) self.assertAlmostEqual(cvxopt.div([1.0,2.0,0.25]),2.0) self.assertEqualLists(list(cvxopt.min(a,b)),[1.0,-2.0,-1.0]) self.assertEqualLists(list(cvxopt.max(a,b)),[3.0,2.0,3.0]) self.assertEqual(cvxopt.max([1.0,2.0]),2.0) self.assertEqual(cvxopt.max(a),3.0) self.assertEqual(cvxopt.max(c),3.0) self.assertEqual(cvxopt.max(d),5.0) self.assertEqual(cvxopt.min([1.0,2.0]),1.0) self.assertEqual(cvxopt.min(a),1.0) self.assertEqual(cvxopt.min(c),-2.0) self.assertEqual(cvxopt.min(d),1.0) with self.assertRaises(OverflowError): cvxopt.matrix(1.0,(32780*4,32780)) with self.assertRaises(OverflowError): cvxopt.spmatrix(1.0,(0,32780*4),(0,32780))+1
def f(x, y, z): # Solve for x[:n]: # # A*x[:n] = bx[:n] + P' * ( ((D1-D2)*(D1+D2)^{-1})*bx[n:] # + (2*D1*D2*(D1+D2)^{-1}) * (bz[:m] - bz[m:]) ). blas.copy(( mul( div(d1-d2, d1+d2), x[n:]) + mul( 2*D, z[:m]-z[m:] ) ), u) blas.gemv(P, u, x, beta = 1.0, trans = 'T') lapack.potrs(A, x) # x[n:] := (D1+D2)^{-1} * (bx[n:] - D1*bz[:m] - D2*bz[m:] # + (D1-D2)*P*x[:n]) base.gemv(P, x, u) x[n:] = div( x[n:] - mul(d1, z[:m]) - mul(d2, z[m:]) + mul(d1-d2, u), d1+d2 ) # z[:m] := d1[:m] .* ( P*x[:n] - x[n:] - bz[:m]) # z[m:] := d2[m:] .* (-P*x[:n] - x[n:] - bz[m:]) z[:m] = mul(di[:m], u-x[n:]-z[:m]) z[m:] = mul(di[m:], -u-x[n:]-z[m:])
def test_basic_complex(self): import cvxopt a = cvxopt.matrix([1,-2,3]) b = cvxopt.matrix([1.0,-2.0,3.0]) c = cvxopt.matrix([1.0+2j,1-2j,0+1j]) d = cvxopt.spmatrix([complex(1.0,0.0), complex(0.0,1.0), complex(2.0,-1.0)],[0,1,3],[0,2,3],(4,4)) e = cvxopt.spmatrix([complex(1.0,0.0), complex(0.0,1.0), complex(2.0,-1.0)],[2,3,3],[1,2,3],(4,4)) self.assertAlmostEqualLists(list(cvxopt.div(b,c)),[0.2-0.4j,-0.4-0.8j,-3j]) self.assertAlmostEqualLists(list(cvxopt.div(b,2.0j)),[-0.5j,1j,-1.5j]) self.assertAlmostEqualLists(list(cvxopt.div(a,c)),[0.2-0.4j,-0.4-0.8j,-3j]) self.assertAlmostEqualLists(list(cvxopt.div(c,a)),[(1+2j),(-0.5+1j),0.3333333333333333j]) self.assertAlmostEqualLists(list(cvxopt.div(c,c)),[1.0,1.0,1.0]) self.assertAlmostEqualLists(list(cvxopt.div(a,2.0j)),[-0.5j,1j,-1.5j]) self.assertAlmostEqualLists(list(cvxopt.div(c,1.0j)),[2-1j,-2-1j,1+0j]) self.assertAlmostEqualLists(list(cvxopt.div(1j,c)),[0.4+0.2j,-0.4+0.2j,1+0j]) self.assertTrue(len(d)+len(e)==len(cvxopt.sparse([d,e]))) self.assertTrue(len(d)+len(e)==len(cvxopt.sparse([[d],[e]])))
def dSbus_dV(Y, V): """ Computes the partial derivative of power injection w.r.t. voltage. References: Ray Zimmerman, "dSbus_dV.m", MATPOWER, version 3.2, PSERC (Cornell), http://www.pserc.cornell.edu/matpower/ """ I = Y * V diagV = spdiag(V) diagIbus = spdiag(I) diagVnorm = spdiag(div(V, abs(V))) # Element-wise division. dS_dVm = diagV * conj(Y * diagVnorm) + conj(diagIbus) * diagVnorm dS_dVa = 1j * diagV * conj(diagIbus - Y * diagV) return dS_dVm, dS_dVa
def fcall(self, dae): dae.f[self.x1] = mul(self.u0, div(1, self.T1), -dae.x[self.x1] + mul(dae.y[self.In1], self.K1)) dae.f[self.x2] = mul(self.u0, div(1, self.T2), -dae.x[self.x2] + mul(dae.y[self.In2], self.K2)) dae.f[self.u3] = mul(self.u0, div(1, self.T4), -dae.x[self.u3] + mul(dae.y[self.In], self.T34)) dae.f[self.u4] = mul( self.u0, self.d1, div(1, self.T6), -dae.x[self.u4] + mul(dae.y[self.x3], 1 - self.T56)) dae.f[self.u5] = mul( self.u0, self.d2, div(1, self.T8), -dae.x[self.u5] + mul(dae.y[self.x4], 1 - self.T78)) dae.f[self.u6] = mul( self.u0, self.d3, div(1, self.T10), -dae.x[self.u6] + mul(dae.y[self.x5], 1 - self.T910))
def jac0(self, dae): dae.add_jac(Gy0, -1, self.isd, self.vsd) dae.add_jac(Gy0, -self.rs, self.isd, self.isd) dae.add_jac(Gy0, self.x0, self.isd, self.isq) dae.add_jac(Gy0, -1, self.isq, self.vsq) dae.add_jac(Gy0, -self.x0, self.isq, self.isd) dae.add_jac(Gy0, -self.rs, self.isq, self.isq) dae.add_jac(Gy0, -1, self.vrd, self.vrd) dae.add_jac(Gy0, -1, self.vrq, self.vrq) dae.add_jac(Gy0, -1, self.vsd, self.vsd) dae.add_jac(Gy0, -1, self.vsq, self.vsq) dae.add_jac(Gy0, -1, self.vref, self.vref) dae.add_jac(Gy0, -1, self.pwa, self.pwa) dae.add_jac(Gy0, -1, self.pw, self.pw) dae.add_jac(Gy0, -1, self.cp, self.cp) dae.add_jac(Gy0, -1, self.lamb, self.lamb) dae.add_jac(Gy0, -1, self.ilamb, self.ilamb) dae.add_jac(Gx0, self.xmu, self.isd, self.irq) dae.add_jac(Gx0, -self.xmu, self.isq, self.ird) dae.add_jac(Gx0, -self.rr, self.vrd, self.ird) dae.add_jac(Gx0, -self.rr, self.vrq, self.irq) dae.add_jac(Gx0, 2, self.pwa, self.omega_m) dae.add_jac(Fx0, -div(1, self.Tp), self.theta_p, self.theta_p) dae.add_jac(Fx0, mul(self.Kp, self.phi, div(1, self.Tp)), self.theta_p, self.omega_m) dae.add_jac(Fx0, -div(1, self.Ts), self.ird, self.ird) dae.add_jac(Fx0, -div(1, self.Te), self.irq, self.irq) dae.add_jac(Fy0, -mul(self.KV, div(1, self.Ts)), self.ird, self.vref) dae.add_jac(Fy0, mul(div(1, self.Ts), self.KV - div(1, self.xmu)), self.ird, self.v) dae.add_jac(Gy0, 1e-6, self.isd, self.isd) dae.add_jac(Gy0, 1e-6, self.isq, self.isq) dae.add_jac(Gy0, 1e-6, self.vrd, self.vrd) dae.add_jac(Gy0, 1e-6, self.vrq, self.vrq) dae.add_jac(Gy0, 1e-6, self.vsd, self.vsd) dae.add_jac(Gy0, 1e-6, self.vsq, self.vsq) dae.add_jac(Gy0, 1e-6, self.vref, self.vref) dae.add_jac(Gy0, 1e-6, self.pwa, self.pwa) dae.add_jac(Gy0, 1e-6, self.pw, self.pw) dae.add_jac(Gy0, 1e-6, self.cp, self.cp) dae.add_jac(Gy0, 1e-6, self.lamb, self.lamb) dae.add_jac(Gy0, 1e-6, self.ilamb, self.ilamb)
def servcall(self, dae): self.copy_data_ext('AVR', 'syn', 'syn', self.avr) self.copy_data_ext('AVR', 'u', 'uavr', self.avr) self.copy_data_ext('Synchronous', 'u', 'usyn', self.syn) self.copy_data_ext('Synchronous', 'bus', 'bus', self.syn) self.copy_data_ext('Synchronous', 'Sn', 'Sg', self.syn) self.copy_data_ext('Synchronous', 'v', 'v', self.syn) self.copy_data_ext('Synchronous', 'vf', 'vf', self.syn) self.copy_data_ext('Synchronous', 'pm', 'pm', self.syn) self.copy_data_ext('Synchronous', 'omega', 'omega', self.syn) self.copy_data_ext('Synchronous', 'p', 'p', self.syn) self.copy_data_ext('BusFreq', 'w', 'w', self.bus) self.T34 = sdiv(self.T3, self.T4) self.T56 = sdiv(self.T5, self.T6) self.T78 = sdiv(self.T7, self.T8) self.T910 = sdiv(self.T9, self.T10) self.set_flag('T6', 'd1', reset_val=True) self.set_flag('T8', 'd2', reset_val=True) self.set_flag('T10', 'd3', reset_val=True) self.toSg = div(self.system.mva, self.Sg) self.v0 = dae.y[self.v] self.update_ctrl()
def d2Sbus_dV2(Ybus, V, lam): """ Computes 2nd derivatives of power injection w.r.t. voltage. """ n = len(V) Ibus = Ybus * V diaglam = spdiag(lam) diagV = spdiag(V) A = spmatrix(mul(lam, V), range(n), range(n)) B = Ybus * diagV C = A * conj(B) D = Ybus.H * diagV E = conj(diagV) * (D * diaglam - spmatrix(D * lam, range(n), range(n))) F = C - A * spmatrix(conj(Ibus), range(n), range(n)) G = spmatrix(div(matrix(1.0, (n, 1)), abs(V)), range(n), range(n)) Gaa = E + F Gva = 1j * G * (E - F) Gav = Gva.T Gvv = G * (C + C.T) * G return Gaa, Gav, Gva, Gvv
def F(x = None, z = None): if x is None: return 0, matrix(0.0, (n,1)) if max(abs(x)) >= 1.0: return None r = - b blas.gemv(A, x, r, beta = -1.0) w = x**2 f = 0.5 * blas.nrm2(r)**2 - sum(log(1-w)) gradf = div(x, 1.0 - w) blas.gemv(A, r, gradf, trans = 'T', beta = 2.0) if z is None: return f, gradf.T else: def Hf(u, v, alpha = 1.0, beta = 0.0): """ v := alpha * (A'*A*u + 2*((1+w)./(1-w)).*u + beta *v """ v *= beta v += 2.0 * alpha * mul(div(1.0+w, (1.0-w)**2), u) blas.gemv(A, u, r) blas.gemv(A, r, v, alpha = alpha, beta = 1.0, trans = 'T') return f, gradf.T, Hf
def init0(self, dae): # behind-transformer AC theta_sh and V_sh - must assign first dae.y[self.ash] = dae.y[self.a] + 1e-6 dae.y[self.vsh] = mul(self.v0, 1 - self.vV) + mul(self.vref0, self.vV) + 1e-6 Vm = polar(dae.y[self.v], dae.y[self.a]) Vsh = polar(dae.y[self.vsh], dae.y[self.ash]) # Initial value for Vsh IshC = conj(div(Vsh - Vm, self.Zsh)) Ssh = mul(Vsh, IshC) # PQ PV and V control initials on converters dae.y[self.psh] = mul(self.pref0, self.PQ + self.PV) dae.y[self.qsh] = mul(self.qref0, self.PQ) dae.y[self.v1] = dae.y[self.v2] + mul(dae.y[self.v1], 1 - self.vV) + mul(self.vdcref0, self.vV) # PV and V control on AC buses dae.y[self.v] = mul(dae.y[self.v], 1 - self.PV - self.vV) + mul(self.vref0, self.PV + self.vV) # Converter current initial dae.y[self.Ish] = abs(IshC) # Converter dc power output dae.y[self.pdc] = mul(Vsh, IshC).real() + \ (self.k0 + mul(self.k1, dae.y[self.Ish]) + mul(self.k2, mul(dae.y[self.Ish], dae.y[self.Ish])))
def gycall(self, dae): dae.add_jac( Gy, mul(0.5, self.ngen, pi, self.rho, (self.R)**2, (self.Vwn)**3, div(1, self.mva_mega), (dae.x[self.vw])**3), self.pw, self.cp) dae.add_jac( Gy, mul(-25.52, (dae.y[self.ilamb])**-2, exp(mul(-12.5, div(1, dae.y[self.ilamb])))) + mul( 12.5, (dae.y[self.ilamb])**-2, -1.1 + mul(25.52, div(1, dae.y[self.ilamb])) + mul(-0.08800000000000001, dae.x[self.theta_p]), exp(mul(-12.5, div(1, dae.y[self.ilamb])))), self.cp, self.ilamb) dae.add_jac( Gy, mul((dae.y[self.lamb] + mul(0.08, dae.x[self.theta_p]))**-2, (div(1, dae.y[self.lamb] + mul(0.08, dae.x[self.theta_p])) + mul(-0.035, div(1, 1 + (dae.x[self.theta_p])**3)))**-2), self.ilamb, self.lamb)
def fxcall(self, dae): dae.add_jac( Gx, mul(1.5, dae.y[self.cp], self.ngen, pi, self.rho, (self.R)**2, (self.Vwn)**3, div(1, self.mva_mega), (dae.x[self.vw])**2), self.pw, self.vw) dae.add_jac(Gx, mul(-0.088, exp(mul(-12.5, dae.y[self.ilamb]))), self.cp, self.theta_p) dae.add_jac( Gx, mul(-4, self.R, self.fn, self.ngb, dae.x[self.omega_m], pi, div(1, self.Vwn), div(1, self.npole), (dae.x[self.vw])**-2), self.lamb, self.vw) dae.add_jac( Gx, mul(4, self.R, self.fn, self.ngb, pi, div(1, self.Vwn), div(1, self.npole), div(1, dae.x[self.vw])), self.lamb, self.omega_m) dae.add_jac( Gx, mul(-0.08, (dae.y[self.lamb] + mul(0.08, dae.x[self.theta_p]))**-2) + mul(0.10500000000000001, (dae.x[self.theta_p])**2, (1 + (dae.x[self.theta_p])**3)**-2), self.ilamb, self.theta_p)
def tanimoto(X, norm=False): d = co.matrix([X[:, i].T * X[:, i] for i in xrange(X.size[1])]) Xp = d * cvx.ones_vec(X.size[1]).T Kl = X.T * X K = co.div(Kl, Xp + Xp.T - Kl) return normalize(K) if norm else K
def build_service(self): """Build service variables""" self.iM = div(1, self.M)
def gcall(self, dae): super(AGCTG, self).gcall(dae) for idx, item in enumerate(self.tg): Ktg = div(self.iR[idx], self.iRtot[idx]) dae.g[self.pin[idx]] += mul(Ktg, dae.x[self.Pagc[idx]])
def servcall(self, dae): self.iT = div(1, self.T) self.t0 = self.system.tds.config.t0 self.tf = self.system.tds.config.tf
def report(self, x_name=None): """ Save eigenvalue analysis reports Returns ------- None """ from andes.variables.report import report_info system = self.system mu = self.mu part_fact = self.part_fact if x_name is None: x_name = self.x_name text = [] header = [] rowname = [] data = [] neig = len(mu) mu_real = mu.real() mu_imag = mu.imag() n_positive = sum(1 for x in mu_real if x > 0) n_zeros = sum(1 for x in mu_real if x == 0) n_negative = sum(1 for x in mu_real if x < 0) numeral = [] for idx, item in enumerate(range(neig)): if mu_real[idx] == 0: marker = '*' elif mu_real[idx] > 0: marker = '**' else: marker = '' numeral.append('#' + str(idx + 1) + marker) # compute frequency, un-damped frequency and damping freq = [0] * neig ufreq = [0] * neig damping = [0] * neig for idx, item in enumerate(mu): if item.imag == 0: freq[idx] = 0 ufreq[idx] = 0 damping[idx] = 0 else: ufreq[idx] = abs(item) / 2 / pi freq[idx] = abs(item.imag / 2 / pi) damping[idx] = -div(item.real, abs(item)) * 100 # obtain most associated variables var_assoc = [] for prow in range(neig): temp_row = part_fact[prow, :] name_idx = list(temp_row).index(max(temp_row)) var_assoc.append(x_name[name_idx]) pf = [] for prow in range(neig): temp_row = [] for pcol in range(neig): temp_row.append(round(part_fact[prow, pcol], 5)) pf.append(temp_row) # opening info section text.append(report_info(self.system)) header.append(None) rowname.append(None) data.append(None) text.append('') header.append(['']) rowname.append(['EIGENVALUE ANALYSIS REPORT']) data.append('') text.append('STATISTICS\n') header.append(['']) rowname.append(['Positives', 'Zeros', 'Negatives']) data.append([n_positive, n_zeros, n_negative]) text.append('EIGENVALUE DATA\n') header.append([ 'Most Associated', 'Real', 'Imag.', 'Damped Freq.', 'Frequency', 'Damping [%]' ]) rowname.append(numeral) data.append( [var_assoc, list(mu_real), list(mu_imag), freq, ufreq, damping]) n_cols = 7 # columns per block n_block = int(ceil(neig / n_cols)) if n_block <= 100: for idx in range(n_block): start = n_cols * idx end = n_cols * (idx + 1) text.append('PARTICIPATION FACTORS [{}/{}]\n'.format( idx + 1, n_block)) header.append(numeral[start:end]) rowname.append(x_name) data.append(pf[start:end]) dump_data(text, header, rowname, data, system.files.eig) logger.info(f'Report saved to "{system.files.eig}".')
def fxcall(self, dae): Turbine.jac0(self, dae) dae.add_jac(Gx, -dae.y[self.vsd], self.isd, self.isq) dae.add_jac(Gx, mul(dae.x[self.isq], self.xq), self.vsd, self.omega_m) dae.add_jac(Gx, mul(dae.x[self.omega_m], self.xq), self.vsd, self.isq) dae.add_jac(Gx, self.psip - mul(dae.y[self.isd], self.xd), self.vsq, self.omega_m) dae.add_jac(Gx, dae.y[self.vsq], self.ps, self.isq) dae.add_jac(Gx, self.psip + mul(dae.y[self.isd], self.xq - self.xd), self.te, self.isq) dae.add_jac( Fx, mul(-0.5, dae.y[self.pw], div(1, self.H), (dae.x[self.omega_m])**-2), self.omega_m, self.omega_m) dae.add_jac( Fx, -mul( div(1, self.Teq), (dae.x[self.omega_m])**-2, div(1, self.psip - mul(dae.y[self.isd], self.xd)), dae.y[self.pwa] - mul(self.Kcoi, dae.y[self.dwdt_coi]) - mul(self.Kdc, dae.y[self.v1] - dae.y[self.v2]) - mul(self.Ki, dae.y[self.dwdt])), self.isq, self.omega_m) dae.add_jac(Fy, mul(0.5, div(1, self.H), div(1, dae.x[self.omega_m])), self.omega_m, self.pw) dae.add_jac( Fy, mul(self.Kdc, div(1, self.Teq), div(1, dae.x[self.omega_m]), div(1, self.psip - mul(dae.y[self.isd], self.xd))), self.isq, self.v2) dae.add_jac( Fy, -mul(self.Ki, div(1, self.Teq), div(1, dae.x[self.omega_m]), div(1, self.psip - mul(dae.y[self.isd], self.xd))), self.isq, self.dwdt) dae.add_jac( Fy, mul(div(1, self.Teq), div(1, dae.x[self.omega_m]), div(1, self.psip - mul(dae.y[self.isd], self.xd))), self.isq, self.pwa) dae.add_jac( Fy, -mul(self.Kdc, div(1, self.Teq), div(1, dae.x[self.omega_m]), div(1, self.psip - mul(dae.y[self.isd], self.xd))), self.isq, self.v1) dae.add_jac( Fy, mul( self.xd, div(1, self.Teq), div(1, dae.x[self.omega_m]), (self.psip - mul(dae.y[self.isd], self.xd))**-2, dae.y[self.pwa] - mul(self.Kcoi, dae.y[self.dwdt_coi]) - mul(self.Kdc, dae.y[self.v1] - dae.y[self.v2]) - mul(self.Ki, dae.y[self.dwdt])), self.isq, self.isd) dae.add_jac( Fy, -mul(self.Kcoi, div(1, self.Teq), div(1, dae.x[self.omega_m]), div(1, self.psip - mul(dae.y[self.isd], self.xd))), self.isq, self.dwdt_coi)
def init1(self, dae): self.servcall(dae) mva = self.system.mva self.p0 = mul(self.p0, 1) self.v120 = self.v12 self.toMb = div(mva, self.Sn) # to machine base self.toSb = self.Sn / mva # to system base rs = matrix(self.rs) xd = matrix(self.xd) xq = matrix(self.xq) psip = matrix(self.psip) Pg = matrix(self.p0) # rotor speed omega = 1 * (ageb(mva * Pg, self.Sn)) + \ mul(0.5 + 0.5 * mul(Pg, self.toMb), aandb(agtb(Pg, 0), altb(mva * Pg, self.Sn))) + \ 0.5 * (aleb(mva * Pg, 0)) theta = mul(self.Kp, mround(1000 * (omega - 1)) / 1000) theta = mmax(theta, 0) # variables to initialize iteratively: vsd, vsq, isd, isq vsd = matrix(0.8, (self.n, 1)) vsq = matrix(0.6, (self.n, 1)) isd = matrix(self.p0 / 2) isq = matrix(self.p0 / 2) for i in range(self.n): # vsd = 0.5 # vsq = self.psip[i] # isd = Pg / 2 # isq = Pg / 2 x = matrix([vsd[i], vsq[i], isd[i], isq[i]]) mis = ones(4, 1) jac = sparse(matrix(0, (4, 4), 'd')) iter = 0 while (max(abs(mis))) > self.system.tds.config.tol: if iter > 40: logger.error( 'Initialization of WTG4DC <{}> failed.'.format( self.name[i])) break mis[0] = x[0] * x[2] + x[1] * x[3] - Pg[i] # mis[1] = omega[i]*x[3] * (psip[i] + (xq[i] - xd[i]) * x[2])\ # - Pg[i] mis[1] = omega[i] * x[3] * (psip[i] - xd[i] * x[2]) - Pg[i] mis[2] = -x[0] - rs[i] * x[2] + omega[i] * xq[i] * x[3] mis[3] = x[1] + rs[i] * x[3] + omega[i] * xd[i] * x[2] - \ omega[i] * psip[i] jac[0, 0] = x[2] jac[0, 1] = x[3] jac[0, 2] = x[0] jac[0, 3] = x[1] jac[1, 2] = omega[i] * x[3] * (-xd[i]) jac[1, 3] = omega[i] * (psip[i] + (-xd[i]) * x[2]) jac[2, 0] = -1 jac[2, 2] = -rs[i] jac[2, 3] = omega[i] * xq[i] jac[3, 1] = 1 jac[3, 2] = omega[i] * xd[i] jac[3, 3] = rs[i] linsolve(jac, mis) x -= mis iter += 1 vsd[i] = x[0] vsq[i] = x[1] isd[i] = x[2] isq[i] = x[3] dae.y[self.isd] = isd dae.y[self.vsd] = vsd dae.y[self.vsq] = vsq dae.x[self.isq] = isq dae.x[self.omega_m] = mul(self.u0, omega) dae.x[self.theta_p] = mul(self.u0, theta) dae.y[self.pwa] = mmax(mmin(2 * dae.x[self.omega_m] - 1, 1), 0) self.ps0 = mul(vsd, isd) + mul(vsq, isq) self.qs0 = mul(vsq, isd) - mul(vsd, isq) self.te0 = mul(isq, psip + mul(xq - xd, isd)) dae.y[self.te] = self.te0 dae.y[self.ps] = self.ps0 MPPT.init1(self, dae) Turbine.init1(self, dae) self.system.rmgen(self.dcgen)
def fcall(self, dae): dae.f[self.theta_p] = mul( div(1, self.Tp), -dae.x[self.theta_p] + mul(self.Kp, self.phi, -1 + dae.x[self.omega_m])) dae.anti_windup(self.theta_p, 0, pi)
def init1(self, dae): super(TG2, self).init1(dae) self.T12 = div(self.T1, self.T2) self.iT2 = div(1, self.T2)
def fxcall(self, dae): omega = not0(dae.x[self.omega_m]) toSb = div(self.Sn, self.system.mva) dae.add_jac(Gx, mul(self.x1, 1 - dae.x[self.omega_m]), self.vrd, self.irq) dae.add_jac( Gx, -mul(dae.x[self.irq], self.x1) - mul(dae.y[self.isq], self.xmu), self.vrd, self.omega_m) dae.add_jac( Gx, mul(dae.x[self.ird], self.x1) + mul(dae.y[self.isd], self.xmu), self.vrq, self.omega_m) dae.add_jac(Gx, -mul(self.x1, 1 - dae.x[self.omega_m]), self.vrq, self.ird) dae.add_jac( Gx, mul(1.5, dae.y[self.cp], self.ngen, pi, self.rho, (self.R)**2, (self.Vwn)**3, div(1, self.mva_mega), (dae.x[self.vw])**2), self.pw, self.vw) dae.add_jac(Gx, mul(-0.088, exp(mul(-12.5, div(1, dae.y[self.ilamb])))), self.cp, self.theta_p) dae.add_jac( Gx, mul(-4, self.R, self.fn, self.ngb, dae.x[self.omega_m], pi, div(1, self.Vwn), div(1, self.npole), (dae.x[self.vw])**-2), self.lamb, self.vw) dae.add_jac( Gx, mul(4, self.R, self.fn, self.ngb, pi, div(1, self.Vwn), div(1, self.npole), div(1, dae.x[self.vw])), self.lamb, self.omega_m) dae.add_jac( Gx, mul((div(1, dae.y[self.lamb] + mul(0.08, dae.x[self.theta_p])) + mul(-0.035, div(1, 1 + (dae.x[self.theta_p])**3)))**-2, mul(0.08, (dae.y[self.lamb] + mul(0.08, dae.x[self.theta_p]))**-2) + mul(-0.105, (dae.x[self.theta_p])**2, (1 + (dae.x[self.theta_p])**3)**-2)), self.ilamb, self.theta_p) dae.add_jac(Gx, -mul(self.u0, dae.y[self.vrq]), self.a, self.irq) dae.add_jac(Gx, -mul(self.u0, dae.y[self.vrd]), self.a, self.ird) dae.add_jac(Gx, mul(self.u0, dae.y[self.v], self.xmu, div(1, self.x0)), self.v, self.ird) dae.add_jac( Fx, mul(dae.y[self.pwa], self.x0, toSb, div(1, self.Te), (dae.x[self.omega_m])**-2, div(1, dae.y[self.v]), div(1, self.xmu)), self.irq, self.omega_m) dae.add_jac( Fy, mul(dae.y[self.pwa], self.x0, toSb, div(1, self.Te), div(1, omega), (dae.y[self.v])**-2, div(1, self.xmu)), self.irq, self.v) dae.add_jac( Fy, -mul(self.x0, toSb, div(1, self.Te), div(1, omega), div(1, dae.y[self.v]), div(1, self.xmu)), self.irq, self.pwa) dae.add_jac(Fx, mul(0.5, dae.y[self.isq], self.xmu, div(1, self.H)), self.omega_m, self.ird) dae.add_jac( Fx, mul(-0.5, dae.y[self.pw], div(1, self.H), (dae.x[self.omega_m])**-2), self.omega_m, self.omega_m) dae.add_jac(Fx, mul(-0.5, dae.y[self.isd], self.xmu, div(1, self.H)), self.omega_m, self.irq) dae.add_jac(Fy, mul(0.5, div(1, self.H), div(1, dae.x[self.omega_m])), self.omega_m, self.pw) dae.add_jac(Fy, mul(-0.5, dae.x[self.irq], self.xmu, div(1, self.H)), self.omega_m, self.isd) dae.add_jac(Fy, mul(0.5, dae.x[self.ird], self.xmu, div(1, self.H)), self.omega_m, self.isq)
def gcall(self, dae): dae.g[self.isd] = -dae.y[self.vsd] + mul( dae.x[self.irq], self.xmu) + mul(dae.y[self.isq], self.x0) - mul( dae.y[self.isd], self.rs) dae.g[self.isq] = -dae.y[self.vsq] - mul( dae.x[self.ird], self.xmu) - mul(dae.y[self.isd], self.x0) - mul( dae.y[self.isq], self.rs) dae.g[self.vrd] = -dae.y[self.vrd] + mul( 1 - dae.x[self.omega_m], mul(dae.x[self.irq], self.x1) + mul(dae.y[self.isq], self.xmu)) - mul(dae.x[self.ird], self.rr) dae.g[self.vrq] = -dae.y[self.vrq] - mul( dae.x[self.irq], self.rr) - mul( 1 - dae.x[self.omega_m], mul(dae.x[self.ird], self.x1) + mul(dae.y[self.isd], self.xmu)) dae.g[self.vsd] = -dae.y[self.vsd] - mul(dae.y[self.v], sin(dae.y[self.a])) dae.g[self.vsq] = -dae.y[self.vsq] + mul(dae.y[self.v], cos(dae.y[self.a])) dae.g[self.vref] = self.vref0 - dae.y[self.vref] dae.g[self.pwa] = mmax(mmin(2 * dae.x[self.omega_m] - 1, 1), 0) - dae.y[self.pwa] dae.hard_limit(self.pwa, 0, 1) dae.g[self.pw] = -dae.y[self.pw] + mul( 0.5, dae.y[self.cp], self.ngen, pi, self.rho, (self.R)**2, (self.Vwn)**3, div(1, self.mva_mega), (dae.x[self.vw])**3) dae.g[self.cp] = -dae.y[self.cp] + mul( -1.1 + mul(25.52, div(1, dae.y[self.ilamb])) + mul(-0.08800000000000001, dae.x[self.theta_p]), exp(mul(-12.5, div(1, dae.y[self.ilamb])))) dae.g[self.lamb] = -dae.y[self.lamb] + mul( 4, self.R, self.fn, self.ngb, dae.x[self.omega_m], pi, div(1, self.Vwn), div(1, self.npole), div(1, dae.x[self.vw])) dae.g[self.ilamb] = div( 1, div(1, dae.y[self.lamb] + mul(0.08, dae.x[self.theta_p])) + mul(-0.035, div(1, 1 + (dae.x[self.theta_p])**3))) - dae.y[self.ilamb] dae.g += spmatrix( mul( self.u0, -mul(dae.x[self.ird], dae.y[self.vrd]) - mul(dae.x[self.irq], dae.y[self.vrq]) - mul(dae.y[self.isd], dae.y[self.vsd]) - mul(dae.y[self.isq], dae.y[self.vsq])), self.a, [0] * self.n, (dae.m, 1), 'd') dae.g += spmatrix( mul( self.u0, mul((dae.y[self.v])**2, div(1, self.x0)) + mul(dae.x[self.ird], dae.y[self.v], self.xmu, div( 1, self.x0))), self.v, [0] * self.n, (dae.m, 1), 'd')
def test_kkt_solver(ntrials=5, tol=1e-6): K = 5 sij = matrix(np.random.rand(K * K), (K, K)) sij = 0.5 * (sij + sij.T) si2 = cvxopt.div(1., sij**2) G, h, A = Aopt_GhA(si2) K = si2.size[0] dims = dict(l=K * (K + 1) / 2, q=[], s=[K + 1] * K) def default_solver(W): return misc.kkt_ldl(G, dims, A)(W) def my_solver(W): return Aopt_KKT_solver(si2, W) success = True for t in xrange(ntrials): x = matrix(1 * (np.random.rand(K * (K + 1) / 2 + K) - 0.5), (K * (K + 1) / 2 + K, 1)) y = matrix(np.random.rand(1), (1, 1)) z = matrix(0.0, (K * (K + 1) / 2 + K * (K + 1) * (K + 1), 1)) z[:K * (K + 1) / 2] = 5. * (np.random.rand(K * (K + 1) / 2) - 0.5) offset = K * (K + 1) / 2 for i in xrange(K): r = 10 * (np.random.rand((K + 1) * (K + 2) / 2) - 0.3) p = 0 for a in xrange(K + 1): for b in xrange(a, K + 1): z[offset + a * (K + 1) + b] = r[p] z[offset + b * (K + 1) + a] = r[p] p += 1 offset += (K + 1) * (K + 1) ds = matrix(10 * np.random.rand(K * (K + 1) / 2), (K * (K + 1) / 2, 1)) rs = [ matrix(np.random.rand((K + 1) * (K + 1)) - 0.3, (K + 1, K + 1)) for i in xrange(K) ] W = dict(d=ds, di=cvxopt.div(1., ds), r=rs, rti=[ matrix(np.linalg.inv(np.array(r)), (K + 1, K + 1)).T for r in rs ], beta=[], v=[]) xp = x[:] yp = y[:] zp = z[:] default_f = default_solver(W) my_f = my_solver(W) default_f(x, y, z) my_f(xp, yp, zp) dx = xp - x dy = yp - y offset = K * (K + 1) / 2 for i in xrange(K): symmetrize_matrix(zp, K + 1, offset) symmetrize_matrix(z, K + 1, offset) offset += (K + 1) * (K + 1) dz = zp - z dx, dy, dz = np.max(np.abs(dx)), np.max(np.abs(dy)), np.max(np.abs(dz)) if tol < np.max([dx, dy, dz]): print 'KKT solver FAILS: max(dx=%g, dy=%g, dz=%g) > tol = %g' % \ (dx, dy, dz, tol) success = False print 'KKT solver succeeds: dx=%g, dy=%g, dz=%g' % (dx, dy, dz) return success
def A_optimize_fast(sij, N=1., nsofar=None, delta=None, only_include_measurements=None, maxiters=100, feastol=1e-6): ''' Find the A-optimal of the difference network that minimizes the trace of the covariance matrix. This corresponds to minimizing the average error. In an iterative optimization of the difference network, the optimal allocation is updated with the estimate of s_{ij}, and we need to allocate the next iteration of sampling based on what has already been sampled for each pair. This implementation uses a customized KKT solver. The time complexity is O(K^5), memory complexity is O(K^4). Args: sij: KxK symmetric matrix, where the measurement variance of the difference between i and j is proportional to s[i][j]^2 = s[j][i]^2, and the measurement variance of i is proportional to s[i][i]^2. nadd: float, Nadd gives the additional number of samples to be collected in the next iteration. nsofar: KxK symmetric matrix, where nsofar[i,j] is the number of samples that has already been collected for (i,j) pair. delta: a length K vector. delta[i] is the measurement uncertainty on the quantity x[i] from an independent experiment; if no independent experiment provides a value for x[i], delta[i] is set to numpy.infty. only_include_measurements: set of pairs, if not None, indicate which pairs should be considered in the optimal network. Any pair (i,j) not in the set will be excluded in the allocation (i.e. dn[i,j] = 0). The pair (i,j) in the set must be ordered so that i<=j. Return: KxK symmetric matrix of float, the (i,j) element of which gives the number of samples to be allocated to the measurement of (i,j) difference in the next iteration. ''' si2 = cvxopt.div(1., sij**2) K = si2.size[0] if delta is not None: di2 = np.array([ 1. / delta[i]**2 if delta[i] is not None else 0. for i in xrange(K) ]) else: di2 = None if only_include_measurements is not None: for i in xrange(K): for j in xrange(i, K): if not (i, j) in only_include_measurements: # Set the s[i,j] to infinity, thus excluding the pair. si2[i, j] = si2[j, i] = 0. Gm, hv, Am = Aopt_GhA(si2, nsofar, di2=di2, G_as_function=True) dims = dict(l=K * (K + 1) / 2, q=[], s=[K + 1] * K) cv = matrix(np.concatenate([np.zeros(K * (K + 1) / 2), np.ones(K)]), (K * (K + 1) / 2 + K, 1)) bv = matrix(float(N), (1, 1)) def default_kkt_solver(W): return misc.kkt_ldl(Gm, dims, Am)(W) sol = solvers.conelp(cv, Gm, hv, dims, Am, bv, options=dict(maxiters=maxiters, feastol=feastol), kktsolver=lambda W: Aopt_KKT_solver(si2, W)) return conelp_solution_to_nij(sol['x'], K)
def init1(self, dae): """New initialization function""" self.servcall(dae) retval = True mva = self.system.mva self.p0 = mul(self.p0, self.gammap) self.q0 = mul(self.q0, self.gammaq) dae.y[self.vsd] = mul(dae.y[self.v], -sin(dae.y[self.a])) dae.y[self.vsq] = mul(dae.y[self.v], cos(dae.y[self.a])) rs = matrix(self.rs) rr = matrix(self.rr) xmu = matrix(self.xmu) x1 = matrix(self.xs) + xmu x2 = matrix(self.xr) + xmu Pg = matrix(self.p0) Qg = matrix(self.q0) Vc = dae.y[self.v] vsq = dae.y[self.vsq] vsd = dae.y[self.vsd] toSn = div(mva, self.Sn) # to machine base toSb = self.Sn / mva # to system base # rotor speed omega = 1 * (ageb(mva * Pg, self.Sn)) + \ mul(0.5 + 0.5 * mul(Pg, toSn), aandb(agtb(Pg, 0), altb(mva * Pg, self.Sn))) + \ 0.5 * (aleb(mva * Pg, 0)) slip = 1 - omega theta = mul(self.Kp, mround(1000 * (omega - 1)) / 1000) theta = mmax(theta, 0) # prepare for the iterations irq = mul(-x1, toSb, (2 * omega - 1), div(1, Vc), div(1, xmu), div(1, omega)) isd = zeros(*irq.size) isq = zeros(*irq.size) # obtain ird isd isq for i in range(self.n): A = sparse([[-rs[i], vsq[i]], [x1[i], -vsd[i]]]) B = matrix([vsd[i] - xmu[i] * irq[i], Qg[i]]) linsolve(A, B) isd[i] = B[0] isq[i] = B[1] ird = -div(vsq + mul(rs, isq) + mul(x1, isd), xmu) vrd = -mul(rr, ird) + mul( slip, mul(x2, irq) + mul(xmu, isq)) # todo: check x1 or x2 vrq = -mul(rr, irq) - mul(slip, mul(x2, ird) + mul(xmu, isd)) # main iterations for i in range(self.n): mis = ones(6, 1) rows = [0, 0, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5] cols = [0, 1, 3, 0, 1, 2, 2, 4, 3, 5, 0, 1, 2] x = matrix([isd[i], isq[i], ird[i], irq[i], vrd[i], vrq[i]]) # vals = [-rs, x1, xmu, -x1, -rs, -xmu, -rr, # -1, -rr, -1, vsd, vsq, -xmu * Vc / x1] vals = [ -rs[i], x1[i], xmu[i], -x1[i], -rs[i], -xmu[i], -rr[i], -1, -rr[i], -1, vsd[i], vsq[i], -xmu[i] * Vc[i] / x1[i] ] jac0 = spmatrix(vals, rows, cols, (6, 6), 'd') niter = 0 while max(abs(mis)) > self.system.tds.config.tol: if niter > 20: logger.error('Initialization of DFIG <{}> failed.'.format( self.name[i])) retval = False break mis[0] = -rs[i] * x[0] + x1[i] * x[1] + xmu[i] * x[3] - vsd[i] mis[1] = -rs[i] * x[1] - x1[i] * x[0] - xmu[i] * x[2] - vsq[i] mis[2] = -rr[i] * x[2] + slip[i] * (x2[i] * x[3] + xmu[i] * x[1]) - x[4] mis[3] = -rr[i] * x[3] - slip[i] * (x2[i] * x[2] + xmu[i] * x[0]) - x[5] mis[4] = vsd[i] * x[0] + vsq[i] * x[1] + x[4] * x[2] + \ x[5] * x[3] - Pg[i] mis[5] = -xmu[i] * Vc[i] * x[2] / x1[i] - \ Vc[i] * Vc[i] / x1[i] - Qg[i] rows = [2, 2, 3, 3, 4, 4, 4, 4] cols = [1, 3, 0, 2, 2, 3, 4, 5] vals = [ slip[i] * xmu[i], slip[i] * x2[i], -slip[i] * xmu[i], -slip[i] * x2[i], x[4], x[5], x[2], x[3] ] jac = jac0 + spmatrix(vals, rows, cols, (6, 6), 'd') linsolve(jac, mis) x -= mis niter += 1 isd[i] = x[0] isq[i] = x[1] ird[i] = x[2] irq[i] = x[3] vrd[i] = x[4] vrq[i] = x[5] dae.x[self.ird] = mul(self.u0, ird) dae.x[self.irq] = mul(self.u0, irq) dae.y[self.isd] = isd dae.y[self.isq] = isq dae.y[self.vrd] = vrd dae.y[self.vrq] = vrq dae.x[self.omega_m] = mul(self.u0, omega) dae.x[self.theta_p] = mul(self.u0, theta) dae.y[self.pwa] = mmax(mmin(2 * dae.x[self.omega_m] - 1, 1), 0) self.vref0 = mul(aneb(self.KV, 0), Vc - div(ird + div(Vc, xmu), self.KV)) dae.y[self.vref] = self.vref0 k = mul(div(x1, Vc, xmu, omega), toSb) self.irq_off = -mul(k, mmax(mmin(2 * omega - 1, 1), 0)) - irq # electrical torque in pu te = mul( xmu, mul(dae.x[self.irq], dae.y[self.isd]) - mul(dae.x[self.ird], dae.y[self.isq])) for i in range(self.n): if te[i] < 0: logger.error( 'Pe < 0 on bus <{}>. Wind speed initialize failed.'.format( self.bus[i])) retval = False # wind power in pu pw = mul(te, omega) dae.y[self.pw] = pw # wind speed initialization loop R = 4 * pi * self.system.freq * mul(self.R, self.ngb, div( 1, self.npole)) AA = pi * self.R**2 vw = 0.9 * self.Vwn for i in range(self.n): mis = 1 niter = 0 while abs(mis) > self.system.tds.config.tol: if niter > 50: logger.error( 'Wind <{}> init failed. ' 'Try increasing the nominal wind speed.'.format( self.wind[i])) retval = False break pw_iter, jac = self.windpower(self.ngen[i], self.rho[i], vw[i], AA[i], R[i], omega[i], theta[i]) mis = pw_iter - pw[i] inc = -mis / jac[1] vw[i] += inc niter += 1 # set wind speed dae.x[self.vw] = div(vw, self.Vwn) lamb = div(omega, vw, div(1, R)) ilamb = div(1, (div(1, lamb + 0.08 * theta) - div(0.035, theta**3 + 1))) cp = 0.22 * mul( div(116, ilamb) - 0.4 * theta - 5, exp(div(-12.5, ilamb))) dae.y[self.lamb] = lamb dae.y[self.ilamb] = ilamb dae.y[self.cp] = cp self.system.rmgen(self.gen) if not retval: logger.error('DFIG initialization failed') return retval
def benchmark_diffnet(sij_generator, ntimes=100, optimalities=['D', 'A', 'Etree'], constant_relative_error=False, epsilon=1e-2): ''' For each optimality, compute the reduction of covariance in the D-, A-, and E-optimal in reference to the minimum spanning tree. Args: sij_generator: function - sij_generator() generates a symmetric matrix of sij. Returns: ( stats, avg, topo ): tuple - stats['D'|'A'|'E'][o] is a numpy array of the covariance ratio ('D': ln(det(C)), 'A': tr(C), 'E': max(eig(C))) avg['D'|'A'|'E'][o] is the corresponding mean. topo[o][0] is the histogram of n_{ii}/s_{ii}. topo[o][1] is the histogram of n_{ij}/s_{ij} for j!=i. topo[o][2] is the list of connectivities of the measurement networks topo[o][3] is the list containing the numbers of edges that need to be added to the measurement networks to make the graphs 2-edge-connected (which ensures a cycle between any two nodes). o can be 'D', 'A', 'Etree', 'MSTn', 'MSTs', 'MSTv', 'cstn', 'cstv', 'csts'. ''' stats = dict(D=dict(), A=dict(), E=dict()) for s in stats: for o in optimalities + [ 'MSTn', 'MSTs', 'MSTv' ] + \ [ 'cstn', 'csts', 'cstv' ]: stats[s][o] = np.zeros(ntimes) emin = -5 emax = 2 nbins = 2 * (emax + 1 - emin) bins = np.concatenate([[0], np.logspace(emin, emax, nbins)]) # topo records the topology of the optimal measurement networks topo = dict([ (o, [np.zeros(nbins, dtype=float), np.zeros(nbins, dtype=float), [], []]) for o in optimalities ]) nfails = 0 for t in xrange(ntimes): if constant_relative_error: results = dict() si, sij = sij_generator() for o in optimalities: if o == 'A': results[o] = A_optimize_const_relative_error(si) elif o == 'D': results[o] = D_optimize_const_relative_error(si) else: results.update(optimize(sij, [o])) else: sij = sij_generator() results = optimize(sij, optimalities) ssum = np.sum(np.triu(sij)) if None in results.values(): nfails += 1 continue for o in optimalities: n = np.array(results[o]) n[n < 0] = 0 nos = ssum * n / sij d = np.diag(nos) u = [ nos[i, j] for i in xrange(n.shape[0]) for j in xrange(i + 1, n.shape[0]) ] hd, _ = np.histogram(d, bins, density=False) hu, _ = np.histogram(u, bins, density=False) topo[o][0] += hd topo[o][1] += hu nos[nos < epsilon] = 0 gdn = nx.from_numpy_matrix(nos) topo[o][2].append(nx.edge_connectivity(gdn)) topo[o][3].append(len(sorted(nx.k_edge_augmentation(gdn, 2)))) results.update( dict(MSTn=MST_optimize(sij, 'n'), MSTs=MST_optimize(sij, 'std'), MSTv=MST_optimize(sij, 'var'))) results.update( dict(cstn=const_allocation(sij, 'n'), csts=const_allocation(sij, 'std'), cstv=const_allocation(sij, 'var'))) CMSTn = covariance(cvxopt.div(results['MSTn'], sij**2)) DMSTn = np.log(linalg.det(CMSTn)) AMSTn = np.trace(CMSTn) EMSTn = np.max(linalg.eig(CMSTn)[0]).real for o in results: n = results[o] C = covariance(cvxopt.div(n, sij**2)) D = np.log(linalg.det(C)) A = np.trace(C) E = np.max(linalg.eig(C)[0]).real stats['D'][o][t - nfails] = D - DMSTn stats['A'][o][t - nfails] = A / AMSTn stats['E'][o][t - nfails] = E / EMSTn avg = dict() for s in stats: avg[s] = dict() for o in stats[s]: stats[s][o] = stats[s][o][:ntimes - nfails] avg[s][o] = np.mean(stats[s][o]) for o in optimalities: topo[o][0] /= (ntimes - nfails) topo[o][1] /= (ntimes - nfails) return stats, avg, topo
def fxcall(self, dae): dae.add_jac(Fy, div(1 + self.dSe, self.Te), self.vfout, self.vr) dae.add_jac(Fx, -div(1 + self.dSe, self.Te), self.vfout, self.vfout)
def F(W): # SVD R[j] = U[j] * diag(sig[j]) * Vt[j] lapack.gesvd(+W['r'][0], sv, jobu='A', jobvt='A', U=U, Vt=Vt) # Vt[j] := diag(sig[j])^-1 * Vt[j] for k in xrange(ns): blas.tbsv(sv, Vt, n=ns, k=0, ldA=1, offsetx=k * ns) # Gamma[j] is an ns[j] x ns[j] symmetric matrix # # (sig[j] * sig[j]') ./ sqrt(1 + rho * (sig[j] * sig[j]').^2) # S = sig[j] * sig[j]' S = matrix(0.0, (ns, ns)) blas.syrk(sv, S) Gamma = div(S, sqrt(1.0 + rho * S**2)) symmetrize(Gamma, ns) # As represents the scaled mapping # # As(x) = A(u * (Gamma .* x) * u') # As'(y) = Gamma .* (u' * A'(y) * u) # # stored in a similar format as A, except that we use packed # storage for the columns of As[i][j]. if type(A) is spmatrix: blas.scal(0.0, As) try: As[VecAIndex] = +A['s'][VecAIndex] except: As[VecAIndex] = +A[VecAIndex] else: blas.copy(A, As) # As[i][j][:,k] = diag( diag(Gamma[j]))*As[i][j][:,k] # As[i][j][l,:] = Gamma[j][l,l]*As[i][j][l,:] for k in xrange(ms): cngrnc(U, As, trans='T', offsetx=k * (ns2)) blas.tbmv(Gamma, As, n=ns2, k=0, ldA=1, offsetx=k * (ns2)) misc.pack(As, Aspkd, {'l': 0, 'q': [], 's': [ns] * ms}) # H is an m times m block matrix with i, k block # # Hik = sum_j As[i,j]' * As[k,j] # # of size ms[i] x ms[k]. Hik = 0 if As[i,j] or As[k,j] # are zero for all j H = matrix(0.0, (ms, ms)) blas.syrk(Aspkd, H, trans='T', beta=1.0, k=ns * (ns + 1) / 2) lapack.potrf(H) def solve(x, y, z): """ Returns solution of rho * ux + A'(uy) - r^-T * uz * r^-1 = bx A(ux) = by -ux - r * uz * r' = bz. On entry, x = bx, y = by, z = bz. On exit, x = ux, y = uy, z = uz. """ # bz is a copy of z in the format of x blas.copy(z, bz) blas.axpy(bz, x, alpha=rho) # x := Gamma .* (u' * x * u) # = Gamma .* (u' * (bx + rho * bz) * u) cngrnc(U, x, trans='T', offsetx=0) blas.tbmv(Gamma, x, n=ns2, k=0, ldA=1, offsetx=0) # y := y - As(x) # := by - As( Gamma .* u' * (bx + rho * bz) * u) #blas.copy(x,xp) #pack_ip(xp,n = ns,m=1,nl=nl) misc.pack(x, xp, {'l': 0, 'q': [], 's': [ns]}) blas.gemv(Aspkd, xp, y, trans = 'T',alpha = -1.0, beta = 1.0, \ m = ns*(ns+1)/2, n = ms,offsetx = 0) # y := -y - A(bz) # = -by - A(bz) + As(Gamma .* (u' * (bx + rho * bz) * u) Af(bz, y, alpha=-1.0, beta=-1.0) # y := H^-1 * y # = H^-1 ( -by - A(bz) + As(Gamma.* u'*(bx + rho*bz)*u) ) # = uy blas.trsv(H, y) blas.trsv(H, y, trans='T') # bz = Vt' * vz * Vt # = uz where # vz := Gamma .* ( As'(uy) - x ) # = Gamma .* ( As'(uy) - Gamma .* (u'*(bx + rho *bz)*u) ) # = Gamma.^2 .* ( u' * (A'(uy) - bx - rho * bz) * u ). #blas.copy(x,xp) #pack_ip(xp,n=ns,m=1,nl=nl) misc.pack(x, xp, {'l': 0, 'q': [], 's': [ns]}) blas.scal(-1.0, xp) blas.gemv(Aspkd, y, xp, alpha=1.0, beta=1.0, m=ns * (ns + 1) / 2, n=ms, offsety=0) # bz[j] is xp unpacked and multiplied with Gamma misc.unpack(xp, bz, {'l': 0, 'q': [], 's': [ns]}) blas.tbmv(Gamma, bz, n=ns2, k=0, ldA=1, offsetx=0) # bz = Vt' * bz * Vt # = uz cngrnc(Vt, bz, trans='T', offsetx=0) symmetrize(bz, ns, offset=0) # x = -bz - r * uz * r' # z contains r.h.s. bz; copy to x blas.copy(z, x) blas.copy(bz, z) cngrnc(W['r'][0], bz, offsetx=0) blas.axpy(bz, x) blas.scal(-1.0, x) return solve
def data_to_sys_base(self): """ Converts parameters to system base. Stores a copy in ``self._store``. Sets the flag ``self.flag['sysbase']`` to True. :return: None """ if (not self.n) or self._flags['sysbase']: return Sb = self.system.mva Vb = matrix([]) if 'bus' in self._ac.keys(): Vb = self.read_data_ext('Bus', 'Vn', idx=self.bus) elif 'bus1' in self._ac.keys(): Vb = self.read_data_ext('Bus', 'Vn', idx=self.bus1) for var in self._voltages: self._store[var] = self.__dict__[var] self.__dict__[var] = mul(self.__dict__[var], self.Vn) self.__dict__[var] = div(self.__dict__[var], Vb) for var in self._powers: self._store[var] = self.__dict__[var] self.__dict__[var] = mul(self.__dict__[var], self.Sn) self.__dict__[var] /= Sb for var in self._currents: self._store[var] = self.__dict__[var] self.__dict__[var] = mul(self.__dict__[var], self.Sn) self.__dict__[var] = div(self.__dict__[var], self.Vn) self.__dict__[var] = mul(self.__dict__[var], Vb) self.__dict__[var] /= Sb if len(self._z) or len(self._y): Zn = div(self.Vn**2, self.Sn) Zb = (Vb**2) / Sb for var in self._z: self._store[var] = self.__dict__[var] self.__dict__[var] = mul(self.__dict__[var], Zn) self.__dict__[var] = div(self.__dict__[var], Zb) for var in self._y: self._store[var] = self.__dict__[var] if self.__dict__[var].typecode == 'd': self.__dict__[var] = div(self.__dict__[var], Zn) self.__dict__[var] = mul(self.__dict__[var], Zb) elif self.__dict__[var].typecode == 'z': self.__dict__[var] = div(self.__dict__[var], Zn + 0j) self.__dict__[var] = mul(self.__dict__[var], Zb + 0j) if len(self._dcvoltages) or len(self._dccurrents) or len( self._r) or len(self._g): dckey = sorted(self._dc.keys())[0] Vbdc = self.read_data_ext('Node', 'Vdcn', self.__dict__[dckey]) Ib = div(Sb, Vbdc) Rb = div(Vbdc, Ib) for var in self._dcvoltages: self._store[var] = self.__dict__[var] self.__dict__[var] = mul(self.__dict__[var], self.Vdcn) self.__dict__[var] = div(self.__dict__[var], Vbdc) for var in self._dccurrents: self._store[var] = self.__dict__[var] self.__dict__[var] = mul(self.__dict__[var], self.Idcn) self.__dict__[var] = div(self.__dict__[var], Ib) for var in self._r: self._store[var] = self.__dict__[var] self.__dict__[var] = div(self.__dict__[var], Rb) for var in self._g: self._store[var] = self.__dict__[var] self.__dict__[var] = mul(self.__dict__[var], Rb) self._flags['sysbase'] = True
def F(W): """ Custom solver for the system [ It 0 0 Xt' 0 At1' ... Atk' ][ dwt ] [ rwt ] [ 0 0 0 -d' 0 0 ... 0 ][ db ] [ rb ] [ 0 0 0 -I -I 0 ... 0 ][ dv ] [ rv ] [ Xt -d -I -Wl1^-2 ][ dzl1 ] [ rl1 ] [ 0 0 -I -Wl2^-2 ][ dzl2 ] = [ rl2 ] [ At1 0 0 -W1^-2 ][ dz1 ] [ r1 ] [ | | | . ][ | ] [ | ] [ Atk 0 0 -Wk^-2 ][ dzk ] [ rk ] where It = [ I 0 ] Xt = [ -D*X E ] Ati = [ 0 -e_i' ] [ 0 0 ] [ -Pi 0 ] dwt = [ dw ] rwt = [ rw ] [ dt ] [ rt ]. """ # scalings and 'intermediate' vectors # db = inv(Wl1)^2 + inv(Wl2)^2 db = W['di'][:m]**2 + W['di'][m:2 * m]**2 dbi = div(1.0, db) # dt = I - inv(Wl1)*Dbi*inv(Wl1) dt = 1.0 - mul(W['di'][:m]**2, dbi) dtsqrt = sqrt(dt) # lam = Dt*inv(Wl1)*d lam = mul(dt, mul(W['di'][:m], d)) # lt = E'*inv(Wl1)*lam lt = matrix(0.0, (k, 1)) base.gemv(E, mul(W['di'][:m], lam), lt, trans='T') # Xs = sqrt(Dt)*inv(Wl1)*X tmp = mul(dtsqrt, W['di'][:m]) Xs = spmatrix(tmp, range(m), range(m)) * X # Es = D*sqrt(Dt)*inv(Wl1)*E Es = spmatrix(mul(d, tmp), range(m), range(m)) * E # form Ab = I + sum((1/bi)^2*(Pi'*Pi + 4*(v'*v + 1)*Pi'*y*y'*Pi)) + Xs'*Xs # and Bb = -sum((1/bi)^2*(4*ui*v'*v*Pi'*y*ei')) - Xs'*Es # and D2 = Es'*Es + sum((1/bi)^2*(1+4*ui^2*(v'*v - 1)) Ab = matrix(0.0, (n, n)) Ab[::n + 1] = 1.0 base.syrk(Xs, Ab, trans='T', beta=1.0) Bb = matrix(0.0, (n, k)) Bb = -Xs.T * Es # inefficient!? D2 = spmatrix(0.0, range(k), range(k)) base.syrk(Es, D2, trans='T', partial=True) d2 = +D2.V del D2 py = matrix(0.0, (n, 1)) for i in range(k): binvsq = (1.0 / W['beta'][i])**2 Ab += binvsq * Pt[i] dvv = blas.dot(W['v'][i], W['v'][i]) blas.gemv(P[i], W['v'][i][1:], py, trans='T', alpha=1.0, beta=0.0) blas.syrk(py, Ab, alpha=4 * binvsq * (dvv + 1), beta=1.0) Bb[:, i] -= 4 * binvsq * W['v'][i][0] * dvv * py d2[i] += binvsq * (1 + 4 * (W['v'][i][0]**2) * (dvv - 1)) d2i = div(1.0, d2) d2isqrt = sqrt(d2i) # compute a = alpha - lam'*inv(Wl1)*E*inv(D2)*E'*inv(Wl1)*lam alpha = blas.dot(lam, mul(W['di'][:m], d)) tmp = matrix(0.0, (k, 1)) base.gemv(E, mul(W['di'][:m], lam), tmp, trans='T') tmp = mul(tmp, d2isqrt) #tmp = inv(D2)^(1/2)*E'*inv(Wl1)*lam a = alpha - blas.dot(tmp, tmp) # compute M12 = X'*D*inv(Wl1)*lam + Bb*inv(D2)*E'*inv(Wl1)*lam tmp = mul(tmp, d2isqrt) M12 = matrix(0.0, (n, 1)) blas.gemv(Bb, tmp, M12, alpha=1.0) tmp = mul(d, mul(W['di'][:m], lam)) blas.gemv(X, tmp, M12, trans='T', alpha=1.0, beta=1.0) # form and factor M sBb = Bb * spmatrix(d2isqrt, range(k), range(k)) base.syrk(sBb, Ab, alpha=-1.0, beta=1.0) M = matrix([[Ab, M12.T], [M12, a]]) lapack.potrf(M) def f(x, y, z): # residuals rwt = x[:n + k] rb = x[n + k] rv = x[n + k + 1:n + k + 1 + m] iw_rl1 = mul(W['di'][:m], z[:m]) iw_rl2 = mul(W['di'][m:2 * m], z[m:2 * m]) ri = [ z[2 * m + i * (n + 1):2 * m + (i + 1) * (n + 1)] for i in range(k) ] # compute 'derived' residuals # rbwt = rwt + sum(Ai'*inv(Wi)^2*ri) + [-X'*D; E']*inv(Wl1)^2*rl1 rbwt = +rwt for i in range(k): tmp = +ri[i] qscal(tmp, W['beta'][i], W['v'][i], inv=True) qscal(tmp, W['beta'][i], W['v'][i], inv=True) rbwt[n + i] -= tmp[0] blas.gemv(P[i], tmp[1:], rbwt, trans='T', alpha=-1.0, beta=1.0) tmp = mul(W['di'][:m], iw_rl1) tmp2 = matrix(0.0, (k, 1)) base.gemv(E, tmp, tmp2, trans='T') rbwt[n:] += tmp2 tmp = mul(d, tmp) # tmp = D*inv(Wl1)^2*rl1 blas.gemv(X, tmp, rbwt, trans='T', alpha=-1.0, beta=1.0) # rbb = rb - d'*inv(Wl1)^2*rl1 rbb = rb - sum(tmp) # rbv = rv - inv(Wl2)*rl2 - inv(Wl1)^2*rl1 rbv = rv - mul(W['di'][m:2 * m], iw_rl2) - mul(W['di'][:m], iw_rl1) # [rtw;rtt] = rbwt + [-X'*D; E']*inv(Wl1)^2*inv(Db)*rbv tmp = mul(W['di'][:m]**2, mul(dbi, rbv)) rtt = +rbwt[n:] base.gemv(E, tmp, rtt, trans='T', alpha=1.0, beta=1.0) rtw = +rbwt[:n] tmp = mul(d, tmp) blas.gemv(X, tmp, rtw, trans='T', alpha=-1.0, beta=1.0) # rtb = rbb - d'*inv(Wl1)^2*inv(Db)*rbv rtb = rbb - sum(tmp) # solve M*[dw;db] = [rtw - Bb*inv(D2)*rtt; rtb + lt'*inv(D2)*rtt] tmp = mul(d2i, rtt) tmp2 = matrix(0.0, (n, 1)) blas.gemv(Bb, tmp, tmp2) dwdb = matrix([rtw - tmp2, rtb + blas.dot(mul(d2i, lt), rtt)]) lapack.potrs(M, dwdb) # compute dt = inv(D2)*(rtt - Bb'*dw + lt*db) tmp2 = matrix(0.0, (k, 1)) blas.gemv(Bb, dwdb[:n], tmp2, trans='T') dt = mul(d2i, rtt - tmp2 + lt * dwdb[-1]) # compute dv = inv(Db)*(rbv + inv(Wl1)^2*(E*dt - D*X*dw - d*db)) dv = matrix(0.0, (m, 1)) blas.gemv(X, dwdb[:n], dv, alpha=-1.0) dv = mul(d, dv) - d * dwdb[-1] base.gemv(E, dt, dv, beta=1.0) tmp = +dv # tmp = E*dt - D*X*dw - d*db dv = mul(dbi, rbv + mul(W['di'][:m]**2, dv)) # compute wdz1 = inv(Wl1)*(E*dt - D*X*dw - d*db - dv - rl1) wdz1 = mul(W['di'][:m], tmp - dv) - iw_rl1 # compute wdz2 = - inv(Wl2)*(dv + rl2) wdz2 = -mul(W['di'][m:2 * m], dv) - iw_rl2 # compute wdzi = inv(Wi)*([-ei'*dt; -Pi*dw] - ri) wdzi = [] tmp = matrix(0.0, (n, 1)) for i in range(k): blas.gemv(P[i], dwdb[:n], tmp, alpha=-1.0, beta=0.0) tmp1 = matrix([-dt[i], tmp]) blas.axpy(ri[i], tmp1, alpha=-1.0) qscal(tmp1, W['beta'][i], W['v'][i], inv=True) wdzi.append(tmp1) # solution x[:n] = dwdb[:n] x[n:n + k] = dt x[n + k] = dwdb[-1] x[n + k + 1:] = dv z[:m] = wdz1 z[m:2 * m] = wdz2 for i in range(k): z[2 * m + i * (n + 1):2 * m + (i + 1) * (n + 1)] = wdzi[i] return f
def fxcall(self, dae): dae.add_jac(Fx, mul(div(1, self.Te), -self.Ke - self.dSe), self.vfout, self.vfout) dae.add_jac(Fx, div(self.Ke + self.dSe, self.Te), self.vfout, self.vr1)
def servcall(self, dae): self.iT = div(1, self.T) self.t0 = self.system.TDS.t0 self.tf = self.system.TDS.tf
def gycall(self, dae): super(AGCTG, self).gycall(dae) for idx, item in enumerate(self.tg): Ktg = div(self.iR[idx], self.iRtot[idx]) dae.add_jac(Gx, Ktg, self.pin[idx], self.Pagc[idx])