def constraints(data, flow_vectors, degree): """Construct constraints for the Inverse Optimization with polynomial delay delay at link i is D_i(x) = ffdelays[i]*(1 + sum^d_k=1 theta[k-1]*(slope[i]*x)^k) estimate the coefficients theta Parameters ---------- data: data for the inverse optimization problem, given by get_data flow_vectors: list of link flow vectors in equilibrium degree: degree of the polynomial function to estimate Return value ------------ c, A, b: such that min c'*x + r(x) s.t. A*x <= b """ Aeq, beqs, ffdelays, slopes = data N, n = len(beqs), len(ffdelays) p = Aeq.size[1]/n m = Aeq.size[0]/p b = matrix([ffdelays]*p*N) tmp1, tmp2 = matrix(0.0, (degree, 1)), matrix(0.0, (p*N*n, degree)) tmp3, tmp4 = matrix(0.0, (p*n*N, m*N*p)), matrix(0.0, (p*m*N, 1)) for j, beq, linkflows in zip(range(N), beqs, flow_vectors): tmp5 = mul(slopes, linkflows) for deg in range(degree): tmp6 = mul(tmp5**(deg+1), ffdelays) tmp1[deg] += (linkflows.T) * tmp6 tmp2[j*n*p:(j+1)*n*p, deg] = -matrix([tmp6]*p) tmp3[j*n*p:(j+1)*n*p, j*m*p:(j+1)*m*p] = Aeq.T tmp4[j*m*p:(j+1)*m*p, 0] = -beq c, A = matrix([tmp1, tmp4]), matrix([[tmp2], [tmp3]]) return c, A, b
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 _cost_function(self, reg, M=None, U=None, I=None, R=None): """ Computes the value of the cost function :param reg: the regularization parameter :type reg: float :param M: the training matrix :type M: cvxopt spmatrix :param U: the user matrix :type U: cvxopt matrix :param I: the item matrix :type I: cvxopt matrix :param R: a matrix containing a 1 where a value is present in the training matrix :type R: cvxopt spmatrix """ if M is None: M = self._M if U is None: U = self._U if I is None: I = self._I if R is None: R = self._R #print "Calculating cost.........\n" error = mul((M - U * I), R) sqerror = mul(error, error) cost = sum(sqerror) + reg * (sum(U**2) + sum(I**2)) return cost
def _gradient(self, reg, M=None, U=None, I=None, R=None): """ Computes the value of the gradient :param reg: the regularization parameter :type reg: float :param M: the training matrix :type M: cvxopt spmatrix :param U: the user matrix :type U: cvxopt matrix :param I: the item matrix :type I: cvxopt matrix :param R: a matrix containing a 1 where a value is present in the training matrix :type R: cvxopt spmatrix """ if M is None: M = self._M if U is None: U = self._U if I is None: I = self._I if R is None: R = self._R grad_U = mul((U * I - M), R) * I.trans() + reg * U grad_I = (mul((U * I - M), R).trans() * U).trans() + reg * I return (grad_U, grad_I)
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 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 test2(delaytype): if delaytype == 'Polynomial': theta = matrix([0.0, 0.0, 0.0, 0.15, 0.0, 0.0]) if delaytype == 'Hyperbolic': theta = (3.5, 3.0) g = los_angeles_2(theta, delaytype) l, x = ue.solver(g, update=True, full=True) d.draw_delays(g) print (max(mul(l,g.get_slopes()))) print ('cost UE:', sum([link.delay*link.flow for link in g.links.values()])) l2, x2 = ue.solver(g, update=True, full=True, SO=True) print (max(mul(l2,g.get_slopes()))) print ('cost SO:', sum([link.delay*link.flow for link in g.links.values()]))
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 f(x, y, z): x[:n] += P.T * ( mul( div(d2**2 - d1**2, d1**2 + d2**2), x[n:]) + mul( .5*D, z[:m]-z[m:] ) ) lapack.potrs(A, x) u = P*x[:n] x[n:] = div( x[n:] - div(z[:m], d1**2) - div(z[m:], d2**2) + mul(d1**-2 - d2**-2, u), d1**-2 + d2**-2 ) z[:m] = div(u-x[n:]-z[:m], d1) z[m:] = div(-u-x[n:]-z[m:], d2)
def func(x, y_unused, z): #Ok, that y is not used x[:n] += P.T * (cvxopt.mul(cvxopt.div(d2**2 - d1**2, d1**2 + d2**2), x[n:]) + cvxopt.mul(.5*D, z[:m]-z[m:])) cvxopt.lapack.potrs(A, x) u = P*x[:n] x[n:] = cvxopt.div(x[n:] - cvxopt.div(z[:m], d1**2) - cvxopt.div(z[m:], d2**2) + cvxopt.mul(d1**-2 - d2**-2, u), d1**-2 + d2**-2) z[:m] = cvxopt.div(u-x[n:]-z[:m], d1) z[m:] = cvxopt.div(-u-x[n:]-z[m:], d2)
def loglikelyhood_hess_cvxopt(xxf,z,extra_args,to_CVXOPT=False): """ Computes Hessian matrix, using sparse matrix format CVXOPT """ # implement BLAS and LAPACK stuff! case,sin,sout,selfs,M,nvarx,nvary,inds_selfs,inds_full_ij = extra_args[:9] if not to_CVXOPT: hess= mw.fitter_s.loglikelyhood_hess(np.array(xxf).flatten(),*extra_args) inds = np.tril_indices(nvarx+nvary) hess = hess.toarray()[inds] #2Nx2N, keep lower diagonal else: x = xxf[:nvarx] y = xxf[nvarx:] x2 = cvxopt.mul(x,x) y2 = cvxopt.mul(y,y) ## common terms ## if case == 'W': aux = 1.-np.einsum('ik,jk',x,y) elif case == 'B': aux = 1.+np.einsum('ik,jk',x,y) else: aux = np.ones((nvarx,nvary)) #assert(np.all(aux>epsilon)) aux = 1./(aux*aux) if not selfs: aa = aux.flatten() aa[inds_selfs] = 0 aux = aa.reshape(nvarx,nvary) ## diagonal ## if case == 'B': ## diagonal ## Hxx = cvxopt.div(sout,(x2+epsilon)) - M*np.einsum('jk,ij',y2,aux) Hyy = cvxopt.div(sin ,(y2+epsilon)) - M*np.einsum('ik,ij',x2,aux) ## off diagonal, lower and upper corner ## elif case =='W': ## diagonal ## Hxx = cvxopt.div(sout,(x2+epsilon)) + M*np.einsum('jk,ij',y2,aux) Hyy = cvxopt.div(sin ,(y2+epsilon)) + M*np.einsum('ik,ij',x2,aux) else: ## diagonal ## Hxx = cvxopt.div(sout,(x2+epsilon)) Hyy = cvxopt.div(sin ,(y2+epsilon)) ## off diagonal, lower and upper corner ## Hxy = M*aux ## Return as CVXOPT matrix ## -> http://cvxopt.org/userguide/matrices.html#sparse-matrices # triplet description (value,col,row) # rows and columns of diagonal rows_d = np.arange(nvarx+nvary) cols_d = rows_d # rows and columns of the lower block rows_ndl = inds_full_ij[1]+nvarx #lower (invert indices) cols_ndl = inds_full_ij[0] inds = (np.r_[rows_d,rows_ndl],np.r_[cols_d,cols_ndl]) hess = np.r_[Hxx.reshape((nvarx,)),Hyy.reshape((nvary,)),Hxy.reshape((nvarx*nvary,))] return cvxopt.spmatrix(z[0]*hess,inds[0],inds[1])
def G(x, y, alpha = 1.0, beta = 0.0, trans = 'N'): """ Implements the linear operator [ -DX E -d -I ] [ 0 0 0 -I ] [ 0 -e_1' 0 0 ] G = [ -P_1' 0 0 0 ] [ . . . . ] [ 0 -e_k' 0 0 ] [ -P_k' 0 0 0 ] and its adjoint G'. """ if trans == 'N': tmp = +y[:m] # y[:m] = alpha*(-DXw + Et - d*b - v) + beta*y[:m] base.gemv(E, x[n:n+k], tmp, alpha = alpha, beta = beta) blas.axpy(x[n+k+1:], tmp, alpha = -alpha) blas.axpy(d, tmp, alpha = -alpha*x[n+k]) y[:m] = tmp base.gemv(X, x[:n], tmp, alpha = alpha, beta = 0.0) tmp = mul(d,tmp) y[:m] -= tmp # y[m:2*m] = -v y[m:2*m] = -alpha * x[n+k+1:] + beta * y[m:2*m] # SOC 1,...,k for i in range(k): l = 2*m+i*(n+1) y[l] = -alpha * x[n+i] + beta * y[l] y[l+1:l+1+n] = -alpha * P[i] * x[:n] + beta * y[l+1:l+1+n]; else: tmp1 = mul(d,x[:m]) tmp2 = y[:n] blas.gemv(X, tmp1, tmp2, trans = 'T', alpha = -alpha, beta = beta) for i in range(k): l = 2*m+1+i*(n+1) blas.gemv(P[i], x[l:l+n], tmp2, trans = 'T', alpha = -alpha, beta = 1.0) y[:n] = tmp2 tmp2 = y[n:n+k] base.gemv(E, x[:m], tmp2, trans = 'T', alpha = alpha, beta = beta) blas.axpy(x[2*m:2*m+k*(1+n):n+1], tmp2, alpha = -alpha) y[n:n+k] = tmp2 y[n+k] = -alpha * blas.dot(d,x[:m]) + beta * y[n+k] y[n+k+1:] = -alpha * (x[:m] + x[m:2*m]) + beta * y[n+k+1:]
def F(x=None, z=None): if x is None: return 0, matrix(0.0, (2*N,1)) y = AA*x + BB d = y[:L]**2 + y[L:]**2 f = sum(d**2) gradg = matrix(0.0, (2*L,1)) gradg[:L], gradg[L:] = 4*mul(d,y[:L]), 4*mul(d,y[L:]) g = gradg.T * AA if z is None: return f, g H = matrix(0.0, (2*L, 2*L)) for k in range(L): H[k,k], H[k+L,k+L] = 4*d[k], 4*d[k] H[[k,k+L], [k,k+L]] += 8 * y[[k,k+L]] * y[[k,k+L]].T return f, g, AA.T*H*AA
def acent(A, b): """ Computes analytic center of A*x <= b with A m by n of rank n. We assume that b > 0 and the feasible set is bounded. """ MAXITERS = 100 ALPHA = 0.01 BETA = 0.5 TOL = 1e-8 ntdecrs = [] m, n = A.size x = matrix(0.0, (n, 1)) H = matrix(0.0, (n, n)) for iter in range(MAXITERS): # Gradient is g = A^T * (1./(b-A*x)). d = (b - A * x) ** -1 g = A.T * d # Hessian is H = A^T * diag(1./(b-A*x))^2 * A. Asc = mul(d[:, n * [0]], A) blas.syrk(Asc, H, trans="T") # Newton step is v = H^-1 * g. v = -g lapack.posv(H, v) # Directional derivative and Newton decrement. lam = blas.dot(g, v) ntdecrs += [sqrt(-lam)] print("%2d. Newton decr. = %3.3e" % (iter, ntdecrs[-1])) if ntdecrs[-1] < TOL: return x, ntdecrs # Backtracking line search. y = mul(A * v, d) step = 1.0 while 1 - step * max(y) < 0: step *= BETA while True: if -sum(log(1 - step * y)) < ALPHA * step * lam: break step *= BETA x += step * v
def vdf_second_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 ''' bpr_2d = 3.0 * (f ** 3) / (c **4) return mul(t0, bpr_2d)
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_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 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 dSbr_dV(Yf, Yt, V, buses, branches): """ Computes the branch power flow vector and the partial derivative of branch power flow w.r.t voltage. """ nl = len(branches) nb = len(V) f = matrix([l.from_bus._i for l in branches]) t = matrix([l.to_bus._i for l in branches]) # Compute currents. If = Yf * V It = Yt * V Vnorm = div(V, abs(V)) diagVf = spdiag(V[f]) diagIf = spdiag(If) diagVt = spdiag(V[t]) diagIt = spdiag(It) diagV = spdiag(V) diagVnorm = spdiag(Vnorm) ibr = range(nl) size = (nl, nb) # Partial derivative of S w.r.t voltage phase angle. dSf_dVa = 1j * (conj(diagIf) * spmatrix(V[f], ibr, f, size) - diagVf * conj(Yf * diagV)) dSt_dVa = 1j * (conj(diagIt) * spmatrix(V[t], ibr, t, size) - diagVt * conj(Yt * diagV)) # Partial derivative of S w.r.t. voltage amplitude. dSf_dVm = diagVf * conj(Yf * diagVnorm) + conj(diagIf) * \ spmatrix(Vnorm[f], ibr, f, size) dSt_dVm = diagVt * conj(Yt * diagVnorm) + conj(diagIt) * \ spmatrix(Vnorm[t], ibr, t, size) # Compute power flow vectors. Sf = mul(V[f], conj(If)) St = mul(V[t], conj(It)) return dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St
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 tau(self, action, observation, S): """POMDPs""" ts = [] for alpha in S: t1 = mul(alpha, self.M[(observation,action)]) t2 = self.T[action] * t1 t3 = (1/len(self.O)) * self.R[action] + self.gamma*t2 ts.append(t3) return ts
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 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 d2Sbr_dV2(Cbr, Ybr, V, lam): """ Computes 2nd derivatives of complex power flow w.r.t. voltage. """ nb = len(V) diaglam = spdiag(lam) diagV = spdiag(V) A = Ybr.H * diaglam * Cbr B = conj(diagV) * A * diagV D = spdiag(mul((A*V), conj(V))) E = spdiag(mul((A.T * conj(V)), V)) F = B + B.T G = spdiag(div(matrix(1.0, (nb, 1)), abs(V))) Haa = F - D - E Hva = 1j * G * (B - B.T - D + E) Hav = Hva.T Hvv = G * F * G return Haa, Hav, Hva, Hvv
def F(x=None, z=None): # x = (t1, t2) # t1 - log(t2) <= 0 if x is None: return m, cvxopt.matrix(m*[0.0] + m*[1.0]) if min(x[m:]) <= 0.0: return None f = x[0:m] - cvxopt.log(x[m:]) Df = cvxopt.sparse([[cvxopt.spdiag(cvxopt.matrix(1.0, (m,1)))], [cvxopt.spdiag(-(x[m:]**-1))]]) if z is None: return f, Df ret = cvxopt.mul(z, x[m:]**-2) # TODO: add regularization for the Hessian? H = cvxopt.spdiag(cvxopt.matrix([cvxopt.matrix(0, (m,1)), ret])) return f, Df, H
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 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 assign_traffic(algorithm='FW'): # generate the graph theta = matrix([0.0, 0.0, 0.0, 0.15]) graph = test_LA(datapath='./', parameters=theta,delaytype='Polynomial') d.draw(graph) # traffic assignment l,x = ue.solver(graph, update=True, full=True) d.draw_delays(graph, l) delay = np.asarray([link.delay for link in graph.links.itervalues()]) ffdelay = np.asarray([link.ffdelay for link in graph.links.itervalues()]) edge_ratios = delay/ffdelay print max(mul(l,graph.get_slopes())) print 'cost UE:', sum([link.delay*link.flow for link in graph.links.values()])
def normalize(K): """ @param K: the matrix @type K: cvxopt dense matrix or numpy array @return: the row-normalized matrix @rtype: cvxopt dense matrix """ if type(K) is np.ndarray: d = np.array([[K[i,i] for i in range(K.shape[0])]]) return K / np.sqrt(np.dot(d.T,d)) else: YY = cvx.diagonal_vec(K) YY = co.sqrt(YY)**(-1) return co.mul(K, YY*YY.T)
def covsel(Y): """ Returns the solution of minimize -log det K + tr(KY) subject to K_ij = 0 if (i,j) not in zip(I, J). Y is a symmetric sparse matrix with nonzero diagonal elements. I = Y.I, J = Y.J. """ cholmod.options['supernodal'] = 2 I, J = Y.I, Y.J n, m = Y.size[0], len(I) # non-zero positions for one-argument indexing N = I + J * n # position of diagonal elements D = [k for k in range(m) if I[k] == J[k]] # starting point: symmetric identity with nonzero pattern I,J K = spmatrix(0.0, I, J) K[::n + 1] = 1.0 # Kn is used in the line search Kn = spmatrix(0.0, I, J) # symbolic factorization of K F = cholmod.symbolic(K) # Kinv will be the inverse of K Kinv = matrix(0.0, (n, n)) for iters in range(100): # numeric factorization of K cholmod.numeric(K, F) d = cholmod.diag(F) # compute Kinv by solving K*X = I Kinv[:] = 0.0 Kinv[::n + 1] = 1.0 cholmod.solve(F, Kinv) # solve Newton system grad = 2 * (Y.V - Kinv[N]) hess = 2 * (mul(Kinv[I, J], Kinv[J, I]) + mul(Kinv[I, I], Kinv[J, J])) v = -grad lapack.posv(hess, v) # stopping criterion sqntdecr = -blas.dot(grad, v) print("Newton decrement squared:%- 7.5e" % sqntdecr) if (sqntdecr < 1e-12): print("number of iterations: %d" % (iters + 1)) break # line search dx = +v dx[D] *= 2 f = -2.0 * sum(log(d)) # f = -log det K s = 1 for lsiter in range(50): Kn.V = K.V + s * dx try: cholmod.numeric(Kn, F) except ArithmeticError: s *= 0.5 else: d = cholmod.diag(F) fn = -2.0 * sum(log(d)) + 2 * s * blas.dot(v, Y.V) if (fn < f - 0.01 * s * sqntdecr): break else: s *= 0.5 K.V = Kn.V return 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 gcall(self, dae): Turbine.gcall(self, dae) MPPT.gcall(self, dae) dae.g[self.isd] = -self.qs0 + mul(dae.y[self.isd], dae.y[self.vsq]) - mul( dae.x[self.isq], dae.y[self.vsd]) dae.g[self.vsd] = -dae.y[self.vsd] - mul( dae.y[self.isd], self.rs) + mul(dae.x[self.isq], dae.x[self.omega_m], self.xq) dae.g[self.vsq] = -dae.y[self.vsq] - mul( dae.x[self.isq], self.rs) - mul( dae.x[self.omega_m], -self.psip + mul(dae.y[self.isd], self.xd)) dae.g[self.ps] = -dae.y[self.ps] + mul( dae.y[self.isd], dae.y[self.vsd]) + mul(dae.x[self.isq], dae.y[self.vsq]) dae.g[self.te] = -dae.y[self.te] + mul( dae.x[self.isq], self.psip + mul(dae.y[self.isd], self.xq - self.xd)) dae.g += spmatrix( -mul(dae.y[self.ps], div(1, dae.y[self.v1] - dae.y[self.v2])), self.v1, [0] * self.n, (dae.m, 1), 'd') dae.g += spmatrix( mul(dae.y[self.ps], div(1, dae.y[self.v1] - dae.y[self.v2])), self.v2, [0] * self.n, (dae.m, 1), 'd')
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 gycall(self, dae): dae.add_jac(Gy, mul(self.xmu, 1 - dae.x[self.omega_m]), self.vrd, self.isq) dae.add_jac(Gy, -mul(self.xmu, 1 - dae.x[self.omega_m]), self.vrq, self.isd) dae.add_jac(Gy, -sin(dae.y[self.a]), self.vsd, self.v) dae.add_jac(Gy, -mul(dae.y[self.v], cos(dae.y[self.a])), self.vsd, self.a) dae.add_jac(Gy, cos(dae.y[self.a]), self.vsq, self.v) dae.add_jac(Gy, -mul(dae.y[self.v], sin(dae.y[self.a])), self.vsq, self.a) 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.088, 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) dae.add_jac(Gy, -mul(dae.y[self.isd], self.u0), self.a, self.vsd) dae.add_jac(Gy, -mul(dae.x[self.irq], self.u0), self.a, self.vrq) dae.add_jac(Gy, -mul(self.u0, dae.y[self.vsq]), self.a, self.isq) dae.add_jac(Gy, -mul(dae.x[self.ird], self.u0), self.a, self.vrd) dae.add_jac(Gy, -mul(dae.y[self.isq], self.u0), self.a, self.vsq) dae.add_jac(Gy, -mul(self.u0, dae.y[self.vsd]), self.a, self.isd) dae.add_jac( Gy, mul( self.u0, mul(2, dae.y[self.v], div(1, self.x0)) + mul(dae.x[self.ird], self.xmu, div(1, self.x0))), self.v, self.v)
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 data_to_elem_base(self): """Custom system base unconversion function""" if not self.n or self._flags['sysbase'] is False: return self.R = mul(self.R, self.Sn) / self.system.mva super(GovernorBase, self).data_to_elem_base()
def gcall(self, dae): pm = dae.x[self.xg] + self.pm0 + mul(self.gain, self.T12, self.wref0 - dae.x[self.omega]) dae.g[self.pout] = pm - dae.y[self.pout] dae.hard_limit(self.pout, self.pmin, self.pmax) super(TG2, self).gcall(dae)
def fcall(self, dae): dae.f[self.xg] = mul( self.iT2, mul(self.gain, 1 - self.T12, self.wref0 - dae.x[self.omega]) - dae.x[self.xg])
def jac0(self, dae): super(TG1, self).jac0(dae) dae.add_jac(Gy0, -self.u + 1e-6, self.pin, self.pin) dae.add_jac(Gx0, -mul(self.u, self.gain), self.pin, self.omega) dae.add_jac(Gy0, mul(self.u, self.gain), self.pin, self.wref) dae.add_jac(Fx0, -mul(self.u, self.iTs) + 1e-6, self.xg1, self.xg1) dae.add_jac(Fy0, mul(self.u, self.iTs), self.xg1, self.pin) dae.add_jac(Fx0, mul(self.u, self.k2, self.iTc), self.xg2, self.xg1) dae.add_jac(Fx0, -mul(self.u, self.iTc), self.xg2, self.xg2) dae.add_jac(Fx0, mul(self.u, self.k4, self.iT5), self.xg3, self.xg2) dae.add_jac(Fx0, mul(self.u, self.k4, self.k1, self.iT5), self.xg3, self.xg1) dae.add_jac(Fx0, -mul(self.u, self.iT5), self.xg3, self.xg3) dae.add_jac(Gx0, self.u, self.pout, self.xg3) dae.add_jac(Gx0, mul(self.u, self.k3), self.pout, self.xg2) dae.add_jac(Gx0, mul(self.u, self.k3, self.k1), self.pout, self.xg1) dae.add_jac(Gy0, -self.u + 1e-6, self.pout, self.pout)
def F(x=None, z=None): """ Evaluates the objective and nonlinear constraint functions. """ if x is None: # Include power mismatch constraint twice to force equality. nln_N = self.om.nln_N + neqnln return nln_N, x0 # Evaluate objective function ------------------------------------- Pgen = x[Pg.i1:Pg.iN + 1] # Active generation in p.u. Qgen = x[Qg.i1:Qg.iN + 1] # Reactive generation in p.u. xx = matrix([Pgen, Qgen]) * base_mva # Evaluate the objective function value. if len(ipol) > 0: # FIXME: Implement reactive power costs. f0 = sum([g.total_cost(xx[i]) for i, g in enumerate(gn)]) else: f0 = 0 # Piecewise linear cost of P and Q. if ny: y = self.om.get_var("y") ccost = spmatrix(matrix(1.0, (ny, 1)), range(y.i1, y.iN + 1), matrix(0.0, (ny, 1)), size=(nxyz, 1)).T f0 = f0 + ccost * x else: ccost = matrix(0.0, (1, nxyz)) # TODO: Generalised cost term. # Evaluate cost gradient ------------------------------------------ iPg = range(Pg.i1, Pg.iN + 1) iQg = range(Qg.i1, Qg.iN + 1) # Polynomial cost of P and Q. df_dPgQg = matrix(0.0, (2 * ng, 1)) # w.r.t p.u. Pg and Qg for i in ipol: df_dPgQg[i] = \ base_mva * polyval(polyder(list(gn[i].p_cost)), xx[i]) df0 = matrix(0.0, (nxyz, 1)) df0[iPg] = df_dPgQg[:ng] df0[iQg] = df_dPgQg[ng:ng + ng] # Piecewise linear cost of P and Q. df0 = df0 + ccost.T # TODO: Generalised cost term. # Evaluate cost Hessian ------------------------------------------- # d2f = None # Evaluate nonlinear equality constraints ------------------------- for i, g in enumerate(gn): g.p = Pgen[i] * base_mva # active generation in MW g.q = Qgen[i] * base_mva # reactive generation in MVAr # Rebuild the net complex bus power injection vector in p.u. Sbus = matrix(case.getSbus(bs)) Vang = x[Va.i1:Va.iN + 1] Vmag = x[Vm.i1:Vm.iN + 1] V = mul(Vmag, exp(1j * Vang)) # Evaluate the power flow equations. mis = mul(V, conj(Ybus * V)) - Sbus # Equality constraints (power flow). g = matrix([ mis.real(), # active power mismatch for all buses mis.imag() ]) # reactive power mismatch for all buses # Evaluate nonlinear inequality constraints ----------------------- # Inequality constraints (branch flow limits). # (line constraint is actually on square of limit) flow_max = matrix([(l.rate_a / base_mva)**2 for l in ln]) # FIXME: There must be a more elegant way to do this. for i, rate in enumerate(flow_max): if rate == 0.0: flow_max[i] = 1e5 if self.flow_lim == IFLOW: If = Yf * V It = Yt * V # Branch current limits. h = matrix([(If * conj(If)) - flow_max, (If * conj(It)) - flow_max]) else: i_fbus = [e.from_bus._i for e in ln] i_tbus = [e.to_bus._i for e in ln] # Complex power injected at "from" bus (p.u.). Sf = mul(V[i_fbus], conj(Yf * V)) # Complex power injected at "to" bus (p.u.). St = mul(V[i_tbus], conj(Yt * V)) if self.flow_lim == PFLOW: # active power limit, P (Pan Wei) # Branch real power limits. h = matrix( [Sf.real()**2 - flow_max, St.real()**2 - flow_max]) elif self.flow_lim == SFLOW: # apparent power limit, |S| # Branch apparent power limits. h = matrix([ mul(Sf, conj(Sf)) - flow_max, mul(St, conj(St)) - flow_max ]).real() else: raise ValueError # Evaluate partial derivatives of constraints --------------------- iVa = matrix(range(Va.i1, Va.iN + 1)) iVm = matrix(range(Vm.i1, Vm.iN + 1)) iPg = matrix(range(Pg.i1, Pg.iN + 1)) iQg = matrix(range(Qg.i1, Qg.iN + 1)) iVaVmPgQg = matrix([iVa, iVm, iPg, iQg]).T # Compute partials of injected bus powers. dSbus_dVm, dSbus_dVa = dSbus_dV(Ybus, V) i_gbus = [gen.bus._i for gen in gn] neg_Cg = spmatrix(matrix(-1.0, (ng, 1)), i_gbus, range(ng), (nb, ng)) # Transposed Jacobian of the power balance equality constraints. dg = spmatrix([], [], [], (nxyz, 2 * nb)) blank = spmatrix([], [], [], (nb, ng)) dg[iVaVmPgQg, :] = sparse([[dSbus_dVa.real(), dSbus_dVa.imag()], [dSbus_dVm.real(), dSbus_dVm.imag()], [neg_Cg, blank], [blank, neg_Cg]]).T # Compute partials of flows w.r.t V. if self.flow_lim == IFLOW: dFf_dVa, dFf_dVm, dFt_dVa, dFt_dVm, Ff, Ft = \ dIbr_dV(Yf, Yt, V) else: dFf_dVa, dFf_dVm, dFt_dVa, dFt_dVm, Ff, Ft = \ dSbr_dV(Yf, Yt, V, bs, ln) if self.flow_lim == PFLOW: dFf_dVa = dFf_dVa.real dFf_dVm = dFf_dVm.real dFt_dVa = dFt_dVa.real dFt_dVm = dFt_dVm.real Ff = Ff.real Ft = Ft.real # Squared magnitude of flow (complex power, current or real power). df_dVa, df_dVm, dt_dVa, dt_dVm = \ dAbr_dV(dFf_dVa, dFf_dVm, dFt_dVa, dFt_dVm, Ff, Ft) # Construct Jacobian of inequality constraints (branch limits) and # transpose it. dh = spmatrix([], [], [], (nxyz, 2 * nl)) dh[matrix([iVa, iVm]).T, :] = sparse([[df_dVa, dt_dVa], [df_dVm, dt_dVm]]).T f = matrix([f0, g, h, -g]) df = matrix([[df0], [dg], [dh], [-dg]]).T if z is None: return f, df # Evaluate cost Hessian ------------------------------------------- nxtra = nxyz - (2 * nb) # Evaluate d2f ---------------------------------------------------- d2f_dPg2 = matrix(0.0, (ng, 1)) # w.r.t p.u. Pg d2f_dQg2 = matrix(0.0, (ng, 1)) # w.r.t p.u. Qg for i in ipol: d2f_dPg2[i, 0] = polyval(polyder(list(gn[i].p_cost), 2), Pg.v0[i] * base_mva) * base_mva**2 # TODO: Reactive power costs. # for i in ipol: # d2f_dQg2[i] = polyval(polyder(list(gn[i].q_cost), 2), # Qg.v0[i] * base_mva) * base_mva**2 i = matrix([range(Pg.i1, Pg.iN + 1), range(Qg.i1, Qg.iN + 1)]) d2f = spmatrix(matrix([d2f_dPg2, d2f_dQg2]), i, i, (nxyz, nxyz)) # TODO: Generalised cost model. d2f = d2f * self.opt["cost_mult"] # Evaluate Hessian of power balance constraints ------------------- eqnonlin = z[1:neqnln + 1] nlam = len(eqnonlin) / 2 lamP = eqnonlin[:nlam] lamQ = eqnonlin[nlam:nlam + nlam] Gpaa, Gpav, Gpva, Gpvv = d2Sbus_dV2(Ybus, V, lamP) Gqaa, Gqav, Gqva, Gqvv = d2Sbus_dV2(Ybus, V, lamQ) d2G_1 = sparse([[ sparse([[Gpaa, Gpva], [Gpav, Gpvv]]).real() + sparse([[Gqaa, Gqva], [Gqav, Gqvv]]).imag() ], [spmatrix([], [], [], (2 * nb, nxtra))]]) d2G_2 = spmatrix([], [], [], (nxtra, 2 * nb + nxtra)) d2G = sparse([d2G_1, d2G_2]) # Evaluate Hessian of flow constraints --------------------------- ineqnonlin = z[1 + neqnln:1 + neqnln + niqnln] nmu = len(ineqnonlin) / 2 muF = ineqnonlin[:nmu] muT = ineqnonlin[nmu:nmu + nmu] if self.flow_lim == IFLOW: dIf_dVa, dIf_dVm, dIt_dVa, dIt_dVm, If, It = \ dIbr_dV(Yf, Yt, V) Hfaa, Hfav, Hfva, Hfvv = \ d2AIbr_dV2(dIf_dVa, dIf_dVm, If, Yf, V, muF) Htaa, Htav, Htva, Htvv = \ d2AIbr_dV2(dIt_dVa, dIt_dVm, It, Yt, V, muT) else: fr = [e.from_bus._i for e in ln] to = [e.to_bus._i for e in ln] # Line-bus connection matrices. Cf = spmatrix(1.0, range(nl), fr, (nl, nb)) Ct = spmatrix(1.0, range(nl), to, (nl, nb)) dSf_dVa, dSf_dVm, dSt_dVa, dSt_dVm, Sf, St = \ dSbr_dV(Yf, Yt, V, bs, ln) if self.flow_lim == PFLOW: Hfaa, Hfav, Hfva, Hfvv = \ d2ASbr_dV2(dSf_dVa.real(), dSf_dVm.real(), Sf.real(), Cf, Yf, V, muF) Htaa, Htav, Htva, Htvv = \ d2ASbr_dV2(dSt_dVa.real(), dSt_dVm.real(), St.real(), Ct, Yt, V, muT) elif self.flow_lim == SFLOW: Hfaa, Hfav, Hfva, Hfvv = \ d2ASbr_dV2(dSf_dVa, dSf_dVm, Sf, Cf, Yf, V, muF) Htaa, Htav, Htva, Htvv = \ d2ASbr_dV2(dSt_dVa, dSt_dVm, St, Ct, Yt, V, muT) else: raise ValueError d2H_1 = sparse([[ sparse([[Hfaa, Hfva], [Hfav, Hfvv]]) + sparse([[Htaa, Htva], [Htav, Htvv]]) ], [spmatrix([], [], [], (2 * nb, nxtra))]]) d2H_2 = spmatrix([], [], [], (nxtra, 2 * nb + nxtra)) d2H = sparse([d2H_1, d2H_2]) Lxx = d2f + d2G + d2H return f, df, Lxx
def gcall(self, dae): dae.g[self.vref] = self.vref0 - dae.y[self.vref] dae.g += spmatrix(mul(self.u0, self.vf0 - dae.x[self.vfout]), self.vf, [0] * self.n, (dae.m, 1), 'd')
def fcall(self, dae): dae.f[self.vm] = mul(dae.y[self.v] - dae.x[self.vm], self.iTv) dae.f[self.am] = mul(dae.y[self.a] - dae.x[self.am], self.iTa)
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 phi(self): deg1 = pi / 180 dae = self.system.dae above = agtb(dae.x[self.omega_m], 1) phi_degree_step = mfloor((dae.x[self.omega_m] - 1) / deg1) * deg1 return mul(phi_degree_step, above)
def gcall(self, dae): dae.g[self.pm] += self.pm0 - mul( self.u, dae.y[self.pout]) # update the Syn.pm equations dae.g[self.wref] = dae.y[self.wref] - self.wref0
def fcall(self, dae): toSb = self.Sn / self.system.mva omega = not0(dae.x[self.omega_m]) 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) dae.f[self.omega_m] = mul( 0.5, div(1, self.H), mul(dae.y[self.pw], div(1, dae.x[self.omega_m])) - mul( self.xmu, mul(dae.x[self.irq], dae.y[self.isd]) - mul(dae.x[self.ird], dae.y[self.isq]))) dae.f[self.ird] = mul( div(1, self.Ts), -dae.x[self.ird] + mul(self.KV, dae.y[self.v] - dae.y[self.vref]) - mul(dae.y[self.v], div(1, self.xmu))) dae.anti_windup(self.ird, self.ird_min, self.irq_max) k = mul(self.x0, toSb, div(1, dae.y[self.v]), div(1, self.xmu), div(1, omega)) dae.f[self.irq] = mul( div(1, self.Te), -dae.x[self.irq] - self.irq_off - mul(dae.y[self.pwa], k)) dae.anti_windup(self.irq, self.irq_min, self.irq_max)
except ImportError: pylab_installed = False else: pylab_installed = True # Extreme points and inequality description of Voronoi region around # first symbol (0,0). m = 6 V = matrix([ 1.0, 1.0, -1.0, 2.0, -2.0, 1.0, -2.0, -1.0, 0.0, -2.0, 1.5, -1.0, 1.0, 1.0 ], (2,m+1)) A0 = matrix([-(V[1,:m] - V[1,1:]), V[0,:m] - V[0,1:]]).T b0 = mul(A0, V[:,:m].T) * matrix(1.0, (2,1)) # List of symbols. C = [ matrix(0.0, (2,1)) ] + \ [ 2.0 * b0[k] / blas.nrm2(A0[k,:])**2 * A0[k,:].T for k in range(m) ] # Voronoi set around C[1] A1, b1 = matrix(0.0, (3,2)), matrix(0.0, (3,1)) A1[0,:] = -A0[0,:] b1[0] = -b0[0] A1[1,:] = (C[m] - C[1]).T b1[1] = 0.5 * A1[1,:] * ( C[m] + C[1] ) A1[2,:] = (C[2] - C[1]).T b1[2] = 0.5 * A1[2,:] * ( C[2] + C[1] ) # Voronoi set around C[2]
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 fcall(self, dae): dae.f[self.Pagc] = mul(self.Ki, dae.y[self.ace])
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 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 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 gcall(self, dae): self.switch() for idx in range(0, self.n): dae.g[self.ace[idx]] -= mul(self.en[idx], self.cl[:, idx], self.Pl[idx])
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) W2 = mul(+W['d'], +W['d']) # 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) 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) #H = H + spmatrix(W2[:nl/2] + W2[nl/2:] ,range(nl/2),range(nl/2)) blas.axpy(W2, H, n=ms, incy=ms + 1, alpha=1.0) blas.axpy(W2, H, offsetx=ms, n=ms, incy=ms + 1, alpha=1.0) 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, offsetx=nl, offsety=nl) # x := Gamma .* (u' * x * u) # = Gamma .* (u' * (bx + rho * bz) * u) cngrnc(U, x, trans='T', offsetx=nl) blas.tbmv(Gamma, x, n=ns2, k=0, ldA=1, offsetx=nl) blas.tbmv(+W['d'], x, n=nl, k=0, ldA=1) # y := y - As(x) # := by - As( Gamma .* u' * (bx + rho * bz) * u) misc.pack(x, xp, dims) blas.gemv(Aspkd, xp, y, trans = 'T',alpha = -1.0, beta = 1.0, \ m = ns*(ns+1)/2, n = ms,offsetx = nl) #y = y - mul(+W['d'][:nl/2],xp[:nl/2])+ mul(+W['d'][nl/2:nl],xp[nl/2:nl]) blas.tbmv(+W['d'], xp, n=nl, k=0, ldA=1) blas.axpy(xp, y, alpha=-1, n=ms) blas.axpy(xp, y, alpha=1, n=ms, offsetx=nl / 2) # 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 ). misc.pack(x, xp, dims) blas.scal(-1.0, xp) blas.gemv(Aspkd, y, xp, alpha=1.0, beta=1.0, m=ns * (ns + 1) / 2, n=ms, offsety=nl) #xp[:nl/2] = xp[:nl/2] + mul(+W['d'][:nl/2],y) #xp[nl/2:nl] = xp[nl/2:nl] - mul(+W['d'][nl/2:nl],y) blas.copy(y, tmp) blas.tbmv(+W['d'], tmp, n=nl / 2, k=0, ldA=1) blas.axpy(tmp, xp, n=nl / 2) blas.copy(y, tmp) blas.tbmv(+W['d'], tmp, n=nl / 2, k=0, ldA=1, offsetA=nl / 2) blas.axpy(tmp, xp, alpha=-1, n=nl / 2, offsety=nl / 2) # bz[j] is xp unpacked and multiplied with Gamma blas.copy(xp, bz) #,n = nl) misc.unpack(xp, bz, dims) blas.tbmv(Gamma, bz, n=ns2, k=0, ldA=1, offsetx=nl) # bz = Vt' * bz * Vt # = uz cngrnc(Vt, bz, trans='T', offsetx=nl) symmetrize(bz, ns, offset=nl) # x = -bz - r * uz * r' # z contains r.h.s. bz; copy to x #so far, z = bzc (untouched) blas.copy(z, x) blas.copy(bz, z) cngrnc(W['r'][0], bz, offsetx=nl) blas.tbmv(W['d'], bz, n=nl, k=0, ldA=1) blas.axpy(bz, x) blas.scal(-1.0, x) return solve
def fcall(self, dae): dae.f[self.vw] = mul(dae.y[self.ws] - dae.x[self.vw], self.iT)
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
# Figure 7.8, page 384. # Chernoff lower bound. from cvxopt import matrix, mul, exp, normal, solvers, blas #solvers.options['show_progress'] = False # Extreme points and inequality description of Voronoi region around # first symbol (at the origin). m = 6 V = matrix([ 1.0, 1.0, -1.0, 2.0, -2.0, 1.0, -2.0, -1.0, 0.0, -2.0, 1.5, -1.0, 1.0, 1.0 ], (2, m + 1)) # A and b are lists with the inequality descriptions of the regions. A = [matrix([-(V[1, :m] - V[1, 1:]), V[0, :m] - V[0, 1:]]).T] b = [mul(A[0], V[:, :m].T) * matrix(1.0, (2, 1))] # List of symbols. C = [ matrix(0.0, (2,1)) ] + \ [ 2.0 * b[0][k] / blas.nrm2(A[0][k,:])**2 * A[0][k,:].T for k in range(m) ] # Voronoi set around C[1] A += [matrix(0.0, (3, 2))] b += [matrix(0.0, (3, 1))] A[1][0, :] = -A[0][0, :] b[1][0] = -b[0][0] A[1][1, :] = (C[m] - C[1]).T b[1][1] = 0.5 * A[1][1, :] * (C[m] + C[1]) A[1][2, :] = (C[2] - C[1]).T b[1][2] = 0.5 * A[1][2, :] * (C[2] + C[1])
def dSe(self): dae = self.system.dae vfout = dae.x[self.vfout] return mul(self.Ae, exp(mul(self.Be, abs(vfout)))) \ + mul(self.Ae, self.Be, abs(vfout), exp(mul(self.Be, abs(vfout))))
def gcall(self, dae): dae.g[self.dwdt] = ( mul(self.iTd, dae.x[self.w]) - dae.x[self.xdw]) - dae.y[self.dwdt]