Example #1
0
	def get_scores(self, sol, idx, y=[]):
		y = np.array(y)
		if (y.size==0):
			y=np.array(self.y[idx])

		(foo, T) = y.shape
		N = self.states
		F = self.dims
		scores = matrix(0.0, (1, T))

		# this is the score of the complete example
		anom_score = sol.trans()*self.get_joint_feature_map(idx)

		# transition matrix
		A = self.get_transition_matrix(sol)
		# emission matrix without loss
		em = self.calc_emission_matrix(sol, idx, augment_loss=False);
		
		# store scores for each position of the sequence		
		scores[0] = 0.0 + em[int(y[0,0]),0]
		for t in range(1,T):
			scores[t] = A[int(y[0,t-1]),int(y[0,t])] + em[int(y[0,t]),t]

		# transform for better interpretability
		# transform for better interpretability
		if max(abs(scores))>10.0**(-15):
			scores = exp(-abs(4.0*scores/max(abs(scores))))
		else:
			scores = matrix(0.0, (1,T))

		return (anom_score, scores)
Example #2
0
def testgp(opts):
    Aflr  = 1000.0  
    Awall = 100.0  
    alpha = 0.5  
    beta  = 2.0  
    gamma = 0.5  
    delta = 2.0  
 
    F = matrix( [[-1., 1., 1., 0., -1.,  1.,  0.,  0.],  
                 [-1., 1., 0., 1.,  1., -1.,  1., -1.],  
                 [-1., 0., 1., 1.,  0.,  0., -1.,  1.]])  
    g = log( matrix( [1.0, 2/Awall, 2/Awall, 1/Aflr, alpha, 1/beta, gamma, 
                      1/delta]) )  
    K = [1, 2, 1, 1, 1, 1, 1]  
    solvers.options.update(opts)
    sol = solvers.gp(K, F, g)
    #localcvx.options.update(opts)
    #sol = localcvx.gp(K, F, g, kktsolver='chol')
    if sol['status'] == 'optimal':
        x = sol['x']
        print "x=\n", helpers.strSpe(x, "%.17f")
        h, w, d = exp(x)
        print("\n h = %f,  w = %f, d = %f.\n" %(h,w,d))   
        print "\n *** running GO test ***"
        helpers.run_go_test("../testgp", {'x': x})
Example #3
0
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 
Example #4
0
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 
Example #5
0
    def test_cvxopt_sparse(self):
        m = 100
        n = 20

        mu = cvxopt.exp(cvxopt.normal(m))
        F = cvxopt.normal(m, n)
        D = cvxopt.spdiag(cvxopt.uniform(m))
        x = Variable(m)
        exp = square(norm2(D * x))
Example #6
0
    def test_cvxopt_sparse(self):
        m = 100
        n = 20

        mu = cvxopt.exp( cvxopt.normal(m) )
        F = cvxopt.normal(m, n)
        D = cvxopt.spdiag( cvxopt.uniform(m) )
        x = Variable(m)
        exp = square(norm2(D*x))
Example #7
0
    def init1(self, dae):
        retval = True

        # 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 self.te0[i] < 0:
                self.message(
                    'Electric power is negative at bus <{}>. Wind speed initialize failed.'
                    .format(self.bus[i]), ERROR)
                retval = False

        # wind power in pu
        omega = dae.x[self.omega_m]
        theta = dae.x[self.theta_p]
        pw = mul(self.te0, dae.x[self.omega_m])
        dae.y[self.pw] = pw

        # wind speed initialization loop

        R = 4 * pi * self.system.Settings.freq * mul(self.R, self.ngb,
                                                     div(1, self.npole[i]))
        AA = pi * self.R**2
        vw = 0.9 * self.Vwn

        for i in range(self.n):
            mis = 1
            iter = 0
            while abs(mis) > self.system.TDS.tol:
                if iter > 50:
                    self.message(
                        'Initialization of wind <{}> 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
                iter += 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
Example #8
0
    def init1(self, dae):
        # 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 self.te0[i] < 0:
                logger.error(
                    'Pe < 0 on bus <{}>. Wind speed initialize failed.'.format(
                        self.bus[i]))

        # wind power in pu
        omega = dae.x[self.omega_m]
        theta = dae.x[self.theta_p]
        pw = mul(self.te0, dae.x[self.omega_m])
        dae.y[self.pw] = pw

        # wind speed initialization loop

        R = 4 * pi * self.system.config.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:
                    self.message(
                        'Wind <{}> init failed. '
                        'Try increasing the nominal wind speed.'.format(
                            self.wind[i]))
                    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, lamb + 0.08 * theta) - div(0.035, theta**3 + 1)
        cp = 0.22 * mul(
            mul(116, ilamb) - 0.4 * theta - 5, exp(mul(-12.5, ilamb)))

        dae.y[self.lamb] = lamb
        dae.y[self.ilamb] = ilamb
        dae.y[self.cp] = cp
Example #9
0
 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)
Example #10
0
    def gcall(self, dae):
        toSb = div(self.Sn, self.system.Settings.mva)
        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] = mul(2*dae.x[self.omega_m] - 1, toSb) - dae.y[self.pwa]
        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')
Example #11
0
 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)
Example #12
0
 def F(x=None, z=None):
     # beta without constant x[:d], constant x[d], t = x[d+1:]
     if x is None: return 2 * d, matrix(0.0,(2*d+1,1)) # m = 2 *d is the number of constraints
     absE = absA*x[:d+1] # 0 - d contains the constant
     absW = exp(absE)
     cmpE = cmpA*x[:d+1]
     cmpW = exp(cmpE)
     f = matrix(0.0,(2*d+1,1))
     f[0] = absWeight*(-sum(absE) + sum(log(1+absW))) + cmpWeight*(-sum(cmpE) + sum(log(1+cmpW))) + lamda * sum(x[d+1:])# from d+1 withou the constant
     f[1:d+1] = x[:d] - x[d+1:] # beta - t < 0
     f[d+1:] = -x[:d] - x[d+1:] # -beta - t <0
     Df = matrix(0.0,(2*d+1,2*d+1))
     Df[0,:d+1] = absWeight*(matrix(absA.T * (div(absW,1+absW)-1.0))).T + cmpWeight*(matrix(cmpA.T * (div(cmpW,1+cmpW)-1.0))).T
     Df[0,d+1:] = lamda
     Df[1:d+1,0:d] = spdiag(matrix(1.0,(d,1)))
     Df[d+1:, 0:d] = spdiag(matrix(-1.0,(d,1)))
     Df[1:d+1,d+1:] = spdiag(matrix(-1.0,(d,1)))
     Df[d+1:,d+1:] = spdiag(matrix(-1.0,(d,1)))
     if z is None: return f ,Df
     H = matrix(0.0,(2*d+1,2*d+1))
     H[0:d+1,0:d+1] = absWeight*(absA.T *spdiag(div(absW, (1 + absW) ** 2)) * absA) + cmpWeight*(cmpA.T *spdiag(div(cmpW, (1 +cmpW) ** 2)) * cmpA)
     return f, Df, z[0]*H
Example #13
0
 def gcall(self, dae):
     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.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.cp] = -dae.y[self.cp] + mul(
         -1.1 + mul(25.52, dae.y[self.ilamb]) +
         mul(-0.08800000000000001, dae.x[self.theta_p]),
         exp(mul(-12.5, dae.y[self.ilamb])))
     dae.g[self.ilamb] = div(
         1, dae.y[self.lamb] +
         mul(0.08, dae.x[self.theta_p])) - dae.y[self.ilamb] + mul(
             -0.035, div(1, 1 + (dae.x[self.theta_p])**3))
Example #14
0
    def windpower(self, ngen, rho, vw, Ar, R, omega, theta, derivative=False):
        mva_mega = self.system.mva * 1e6
        lamb = omega * R / vw
        ilamb = 1 / (1 / (lamb + 0.08 * theta) - 0.035 / (theta**3 + 1))
        cp = 0.22 * (116 / ilamb - 0.4 * theta - 5) * exp(-12.5 / ilamb)
        pw = 0.5 * ngen * rho * cp * Ar * vw**3 / mva_mega

        a1 = exp(-12.5 / ilamb)
        a2 = (lamb + 0.08 * theta)**2
        a3 = 116. / ilamb - 0.4 * theta - 5
        a4 = -9.28 / (lamb + 0.08 * theta) ** 2 + \
            12.180 * theta * theta / (theta ** 3 + 1) ** 2 - 0.4
        a5 = 1.000 / (lamb + 0.08 * theta) ** 2 - \
            1.3125 * theta * theta / (theta ** 3 + 1) ** 2

        jac = ones(1, 3)
        jac[0] = ngen * R * a1 * rho * vw * vw * Ar * (
            -12.760 + 1.3750 * a3) / a2 / mva_mega
        jac[1] = ngen * (omega * R * (12.760 - 1.3750 * a3) / a2 +
                         0.330 * a3 * vw) * vw * Ar * rho * a1 / mva_mega
        jac[2] = ngen * 0.110 * rho * (a4 +
                                       a3 * a5) * a1 * Ar * vw**3 / mva_mega

        return pw, jac
Example #15
0
	def get_kernel(X, Y, type='linear', param=1.0):
		"""Calculates a kernel given the data X and Y (dims x exms)"""
		(Xdims,Xn) = X.size
		(Ydims,Yn) = Y.size
    	
		kernel = matrix(1.0)
		if type=='linear':
			print('Calculating linear kernel with size {0}x{1}.'.format(Xn,Yn))
			kernel = matrix([ dotu(X[:,i],Y[:,j]) for j in range(Yn) for i in range(Xn)], (Xn,Yn), 'd')

		if type=='rbf':
			print('Calculating Gaussian kernel with size {0}x{1}.'.format(Xn,Yn))
			kernel = matrix([dotu(X[:,i]-Y[:,j],X[:,i]-Y[:,j]) for j in range(Yn) for i in range(Xn)], (Xn,Yn))
			kernel = exp(-param*kernel)
		return kernel
def computeLoss(Z,Y,D,lam_t,lam_s,T,n_rows,n_cols,lh_trend):
    '''
    This function evaluates the objective function at a given solution
    Z.
    '''
        
    n_t=n_rows*n_cols*(T-2);#no. of temporal constraints
    n_lh=0
    if lh_trend:
        n_year=T/52
        n_lh=(n_year-2)*n_rows*n_cols
    n_s=D.size[0]-n_lh-n_t#no. of spatial constraints
    lam_vec=np.array(n_t*[lam_t]+n_s*[lam_s]+n_lh*[lam_t]).reshape((1,-1))
    
    f1=np.sum(np.array(Z+mul(Y**2,exp(-Z))))
    f2=float(lam_vec.dot( np.abs(np.array(D*Z)) ))
    
    return f1+f2
Example #17
0
def solving_for_cloud_x(m, M):
    N, T = m.shape
    K = [1]
    for i in range(T):
        K.append(N)

    g = [1]
    for i in range(N * T):
        g.append(1 / M)

    F = np.zeros((N * T + 1, N * T))
    F[0, :] = -1 * m.reshape(1, N * T)
    for i in range(T):
        for j in range(N):
            F[N * i + j + 1, j * T + i] = 1

    solvers.options['show_progress'] = False
    sol_cloud = solvers.gp(K, matrix(F), log(matrix(g, tc='d')))
    x_cloud = array(exp(sol_cloud['x'])).reshape((N, T))
    return x_cloud
Example #18
0
 def F(x=None, z=None):
     # beta without constant x[:d], constant x[d], t = x[d+1:]
     if x is None: return 2 * d, matrix(0.0,(2*d+1,1)) # m = 2 *d is the number of constraints
     e = A*x[:d+1] # 0 - d contains the constant
     w = exp(e)
     f = matrix(0.0,(2*d+1,1))
     f[0] = alpha*(-sum(e) + sum(log(1+w))) + lamda * sum(x[d+1::])# from d+1 withou the constant
     f[1:d+1] = x[:d] - x[d+1:] # beta - t < 0
     f[d+1:] = -x[:d] - x[d+1:] # -beta - t <0
     Df = matrix(0.0,(2*d+1,2*d+1))
     # Df[0,:d+1] = (matrix(A.T * (div(w,1+w)-1.0))).T
     Df[0, :d + 1] = alpha*(matrix(A.T * (div(w, 1 + w) - 1.0))).T
     Df[0,d+1:] = lamda
     Df[1:d+1,0:d] = spdiag(matrix(1.0,(d,1)))
     Df[d+1:, 0:d] = spdiag(matrix(-1.0,(d,1)))
     Df[1:d+1,d+1:] = spdiag(matrix(-1.0,(d,1)))
     Df[d+1:,d+1:] = spdiag(matrix(-1.0,(d,1)))
     if z is None: return f ,Df
     H = matrix(0.0,(2*d+1,2*d+1))
     H[0:d+1,0:d+1] =  alpha*(A.T *spdiag(div(w, (1 + w) ** 2)) * A)
     return f, Df, z[0]*H
Example #19
0
    def get_kernel(X, Y, type='linear', param=1.0):
        """Calculates a kernel given the data X and Y (dims x exms)"""
        (Xdims, Xn) = X.size
        (Ydims, Yn) = Y.size

        kernel = matrix(1.0)
        if type == 'linear':
            print('Calculating linear kernel with size {0}x{1}.'.format(
                Xn, Yn))
            kernel = matrix(
                [dotu(X[:, i], Y[:, j]) for j in range(Yn) for i in range(Xn)],
                (Xn, Yn), 'd')

        if type == 'rbf':
            print('Calculating Gaussian kernel with size {0}x{1}.'.format(
                Xn, Yn))
            kernel = matrix([
                dotu(X[:, i] - Y[:, j], X[:, i] - Y[:, j]) for j in range(Yn)
                for i in range(Xn)
            ], (Xn, Yn))
            kernel = exp(-param * kernel)
        return kernel
Example #20
0
    def test_cvxopt_sparse(self):
        m = 100
        n = 20

        mu = cvxopt.exp( cvxopt.normal(m) )
        F = cvxopt.normal(m, n)
        D = cvxopt.spdiag( cvxopt.uniform(m) )
        x = Variable(m)
        exp = square(norm2(D*x))

    # # TODO
    # # Test scipy sparse matrices.
    # def test_scipy_sparse(self):
    #     m = 100
    #     n = 20

    #     mu = cvxopt.exp( cvxopt.normal(m) )
    #     F = cvxopt.normal(m, n)
    #     x = Variable(m)

    #     D = scipy.sparse.spdiags(1.5, 0, m, m )
    #     exp = square(norm2(D*x))
Example #21
0
 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)
Example #22
0
    def __init__(self, casefile, **kwargs):
        """
        Optional keyword arguments:

        branch_rmin         (default: -inf  )
        shunt_gmin          (default: -inf  )
        gen_elim            (default: 0.0   )
        truncate_gen_bounds (default: None  )
        line_constraints    (default: True  )
        scale               (default: False )
        """
        self.to_real = kwargs.get('to_real', True)
        self.conversion = kwargs.get('conversion', False)
        self.scale = kwargs.get('scale', False)
        self.shunt_gmin = kwargs.get('shunt_gmin', -float('inf'))
        self.branch_rmin = kwargs.get('branch_rmin', -float('inf'))
        self.gen_elim = kwargs.get('gen_elim', 0.0)
        self.truncate_gen_bounds = kwargs.get('truncate_gen_bounds',None)
        self.line_constraints = kwargs.get('line_constraints', True)
        self.pad_constraints = kwargs.get('pad_constraints', True)
        self.__verbose = kwargs.get('verbose',0)
        self.eigtol = kwargs.get('eigtol',1e5)

        ### load data
        data = _load_case(casefile, verbose = kwargs.get('verbose',0))
        assert data['version'] == '2'

        if kwargs.get('verbose',0): print("Extracting data from case file.")

        ### add data to object
        self.baseMVA = data['baseMVA']
        self.cost_scale = self.baseMVA
        self.nbus = data['bus'].shape[0]

        # branches in service
        active_branches = [i for i in range(data['branch'].shape[0]) if data['branch'][i,10] > 0]
        self.nbranch = len(active_branches)

        # generators in service
        active_generators = [i for i in range(data['gen'].shape[0]) if data['gen'][i,7] > 0]
        self.ngen = len(active_generators)

        # bus data
        self.busses = []
        for k in range(self.nbus):
            bus = {'id': int(data['bus'][k,0]),
                   'type': int(data['bus'][k,1]),
                   'Pd': data['bus'][k,2] / self.baseMVA,
                   'Qd': data['bus'][k,3] / self.baseMVA,
                   'Gs': data['bus'][k,4],
                   'Bs': data['bus'][k,5],
                   'area': data['bus'][k,6],
                   'Vm': data['bus'][k,7],
                   'Va': data['bus'][k,8],
                   'baseKV': data['bus'][k,9],
                   'maxVm': data['bus'][k,11],
                   'minVm': data['bus'][k,12]}
            if bus['Gs'] < self.shunt_gmin: bus['Gs'] = self.shunt_gmin
            self.busses.append(bus)

        self.bus_id_to_index = {}
        for k, bus in enumerate(self.busses):
            self.bus_id_to_index[bus['id']] = k

        # generator data
        self.generators = []
        ii_p = 0
        ii_q = 0
        for k in active_generators:
            gen = {'bus_id': int(data['gen'][k,0]),
                   'Pg': data['gen'][k,1] / self.baseMVA,
                   'Pmax': data['gen'][k,8] / self.baseMVA,
                   'Pmin': data['gen'][k,9] / self.baseMVA,
                   'Qg': data['gen'][k,2] / self.baseMVA,
                   'Qmax': data['gen'][k,3] / self.baseMVA,
                   'Qmin': data['gen'][k,4] / self.baseMVA,
                   'Vg': data['gen'][k,5],
                   'mBase': data['gen'][k,6]
                   }
            if gen['Pmax'] > gen['Pmin'] + self.gen_elim:
                gen['pslack'] = ii_p
                ii_p += 1
            else:
                # eliminate slack variable and set Pmin and Pmax to their average
                gen['pslack'] = None
                gen['Pmin'] = (gen['Pmax'] + gen['Pmin'])/2.0
                gen['Pmax'] = gen['Pmin']

            if gen['Qmax'] > gen['Qmin'] + self.gen_elim:
                gen['qslack'] = ii_q
                ii_q += 1
            else:
                # eliminate slack variable and set Qmin and Qmax to their average
                gen['qslack'] = None
                gen['Qmin'] = (gen['Qmax'] + gen['Qmin'])/2.0
                gen['Qmax'] = gen['Qmin']

            if self.truncate_gen_bounds:
                if gen['Pmin'] < -self.truncate_gen_bounds or gen['Pmax'] > self.truncate_gen_bounds:
                    if kwargs.get('verbose',0):
                       print("Warning: generator at bus %i with large active bound(s); decreasing bound(s)"%(gen['bus_id']))
                    gen['Pmin'] = max(-self.truncate_gen_bounds, gen['Pmin'])
                    gen['Pmax'] = min( self.truncate_gen_bounds, gen['Pmax'])

                if gen['Qmin'] < -self.truncate_gen_bounds or gen['Qmax'] > self.truncate_gen_bounds:
                    if kwargs.get('verbose',0):
                       print("Warning: generator at bus %i with large reactive bound(s); decreasing bound(s)"%(gen['bus_id']))
                    gen['Qmin'] = max(-self.truncate_gen_bounds, gen['Qmin'])
                    gen['Qmax'] = min( self.truncate_gen_bounds, gen['Qmax'])

            self.generators.append(gen)

        self.bus_id_to_genlist = {}
        for k, gen in enumerate(self.generators):
            if gen['bus_id'] in self.bus_id_to_genlist:
                self.bus_id_to_genlist[gen['bus_id']].append(k)
            else:
                self.bus_id_to_genlist[gen['bus_id']] = [k]

        # branch data
        self.branches = []
        for k in active_branches:
            branch = {'from': int(data['branch'][k,0]),
                      'to': int(data['branch'][k,1]),
                      'r': data['branch'][k,2],
                      'x': data['branch'][k,3],
                      'b': data['branch'][k,4],
                      'rateA': data['branch'][k,5],
                      'rateB': data['branch'][k,6],
                      'rateC': data['branch'][k,7],
                      'ratio': data['branch'][k,8],
                      'angle': data['branch'][k,9],
                      'angle_min': data['branch'][k,11],
                      'angle_max': data['branch'][k,12]
                      }
            if branch['r'] < self.branch_rmin:
                if kwargs.get('verbose',0): print("Warning: branch (%i:%i->%i) with small resistance; enforcing min. resistance"%(k,branch['from'],branch['to']))
                branch['r'] = self.branch_rmin
            if not self.line_constraints:
               branch['rateA'] = 0.0
            if not self.pad_constraints:
               branch['angle_min'] = -360.0
               branch['angle_max'] = 360.0
            elif (branch['angle_min'] > -360.0 and branch['angle_min'] <= -180.0) or (branch['angle_max'] < 360.0 and branch['angle_max'] >= 180.0) or (branch['angle_min']==0.0 and branch['angle_max']==0.0):
               if kwargs.get('verbose',0): print("Warning: branch (%i:%i->%i) with unsupported phase angle diff. constraint; dropping constraint"%(k,branch['from'],branch['to']))
               branch['angle_min'] = -360.0
               branch['angle_max'] = 360.0

            self.branches.append(branch)


        # gen cost
        for i, k in enumerate(active_generators):
            gencost = {'model': int(data['gencost'][k,0]),
                       'startup': data['gencost'][k,1],
                       'shutdown': data['gencost'][k,2],
                       'ncoef': int(data['gencost'][k,3]),
                       'coef': data['gencost'][k,4:].T
                       }
            if gencost['model'] == 1:
                raise TypeError("Piecewise linear cost functions are not supported.")
            self.generators[i]['Pcost'] = gencost

        if data['gencost'].shape[0] == 2*data['gen'].shape[0]:
            offset = data['gen'].shape[0]
            for i, k in enumerate(active_generators):
                gencost = {'model': int(data['gencost'][offset + k,0]),
                           'startup': data['gencost'][offset + k,1],
                           'shutdown': data['gencost'][offset + k,2],
                           'ncoef': int(data['gencost'][offset + k,3]),
                           'coef': data['gencost'][offset + k,4:].T
                           }
                self.generators[i]['Qcost'] = gencost

        ### Compute bus admittance matrix and connection matrices
        j = complex(0.0,1.0)
        r = matrix([branch['r'] for branch in self.branches])
        b = matrix([branch['b'] for branch in self.branches])
        x = matrix([branch['x'] for branch in self.branches])
        Gs = matrix([bus['Gs'] for bus in self.busses])
        Bs = matrix([bus['Bs'] for bus in self.busses])

        tap = matrix([1.0 if branch['ratio'] == 0.0 else branch['ratio'] for branch in self.branches])
        angle = matrix([branch['angle'] for branch in self.branches])
        tap = mul(tap, exp(j*pi/180.*angle))
        self.tap = tap

        Ys = div(1.0, r + j*x)
        Ytt = Ys + j*b/2.0
        Yff = div(Ytt, mul(tap, tap.H.T))
        Yft = -div(Ys, tap.H.T)
        Ytf = -div(Ys, tap)
        Ysh = (Gs+j*Bs)/self.baseMVA

        self.Ybr = []
        for k in range(self.nbranch): self.Ybr.append([[Yff[k],Yft[k]],[Ytf[k],Ytt[k]]])

        f = matrix([self.bus_id_to_index[branch['from']] for branch in self.branches])
        t = matrix([self.bus_id_to_index[branch['to']] for branch in self.branches])

        Cf = spmatrix(1.0, range(self.nbranch), f, (self.nbranch,self.nbus))
        Ct = spmatrix(1.0, range(self.nbranch), t, (self.nbranch,self.nbus))
        Yf = spmatrix(matrix([Yff,Yft]), 2*list(range(self.nbranch)), matrix([f,t]), (self.nbranch,self.nbus))
        Yt = spmatrix(matrix([Ytf,Ytt]), 2*list(range(self.nbranch)), matrix([f,t]), (self.nbranch,self.nbus))
        Ybus = Cf.T*Yf + Ct.T*Yt + spmatrix(Ysh, range(self.nbus), range(self.nbus), (self.nbus,self.nbus))

        self.Cf = Cf
        self.Ct = Ct
        self.Yf = Yf
        self.Yt = Yt
        self.Ybus = Ybus

        if kwargs.get('verbose',0): print("Building cone LP.")
        self._build_conelp()
        if self.conversion:
           if kwargs.get('verbose',0):
               if kwargs.get('coupling','full') == 'full':
                  print("Applying chordal conversion to cone LP.")
               else:
                  print("Applying partial chordal conversion to cone LP.")
           _conelp_convert(self, **kwargs)
        if self.scale:
           if kwargs.get('verbose',0): print("Scaling cone LP.")
           _conelp_scale(self, **kwargs)
        if self.to_real:
           if kwargs.get('verbose',0): print("Converting to real-valued cone LP.")
           _conelp_to_real(self, **kwargs)

        return
Example #23
0
 def Se(self):
     dae = self.system.DAE
     vfout = dae.x[self.vfout]
     return mul(self.Ae, exp(mul(self.Be, abs(vfout))))
Example #24
0
    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)
Example #25
0
# The small GP of section 9.3 (Geometric programming).

from cvxopt import matrix, log, exp, solvers

Aflr = 1000.0
Awall = 100.0
alpha = 0.5
beta = 2.0
gamma = 0.5
delta = 2.0

F = matrix([[-1., 1., 1., 0., -1., 1., 0., 0.],
            [-1., 1., 0., 1., 1., -1., 1., -1.],
            [-1., 0., 1., 1., 0., 0., -1., 1.]])
g = log(
    matrix([
        1.0, 2 / Awall, 2 / Awall, 1 / Aflr, alpha, 1 / beta, gamma, 1 / delta
    ]))
K = [1, 2, 1, 1, 1, 1, 1]
h, w, d = exp(solvers.gp(K, F, g)['x'])
print("\n h = %f,  w = %f, d = %f.\n" % (h, w, d))
Example #26
0
b[6][2] = 0.5 * A[6][2, :] * (C[5] + C[6])

# For regions k=1, ..., 6, let pk be the optimal value of
#
#     minimize    x'*x
#     subject to  A*x <= b.
#
# The Chernoff upper bound is  1.0 - sum exp( - pk / (2 sigma^2)).

P = matrix([1.0, 0.0, 0.0, 1.0], (2, 2))
q = matrix(0.0, (2, 1))
optvals = matrix(
    [blas.nrm2(solvers.qp(P, q, A[k], b[k])['x'])**2 for k in range(1, 7)])
nopts = 200
sigmas = 0.2 + (0.5 - 0.2) / nopts * matrix(list(range(nopts)), tc='d')
bnds = [1.0 - sum(exp(-optvals / (2 * sigma**2))) for sigma in sigmas]

try:
    import pylab
except ImportError:
    pass
else:
    pylab.figure(facecolor='w')
    pylab.plot(sigmas, bnds, '-')
    pylab.axis([0.2, 0.5, 0.9, 1.0])
    pylab.title('Chernoff lower bound (fig. 7.8)')
    pylab.xlabel('sigma')
    pylab.ylabel('Probability of correct detection')
    pylab.show()

    if 0:  # uncomment out for the Monte Carlo estimation.
Example #27
0
        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
Example #28
0
File: math.py Project: buaaqq/andes
def polar(m, a):
    """Return complex number from polar form m*exp(1j*a)"""
    return mul(m, exp(1j * a))
Example #29
0
def sigmoid(X):
    return (1.0 + co.exp(-X))**(-1)
Example #30
0
 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))))
Example #31
0
import cvxopt
import numpy
from cvxpy import *
from multiprocessing import Pool
from pylab import figure, show
import math

num_assets = 100
num_factors = 20

mu = cvxopt.exp(cvxopt.normal(num_assets))
F = cvxopt.normal(num_assets, num_factors)
D = cvxopt.spdiag(cvxopt.uniform(num_assets))
x = Variable(num_assets)
gamma = Parameter(sign="positive")

expected_return = mu.T * x
variance = square(norm2(F.T * x)) + square(norm2(D * x))

# construct portfolio optimization problem *once*
p = Problem(Maximize(expected_return - gamma * variance), [sum(x) == 1, x >= 0])

# encapsulate the allocation function
def allocate(gamma_value):
    gamma.value = gamma_value
    p.solve()
    w = x.value
    expected_return, risk = mu.T * w, w.T * (F * F.T + D * D) * w
    return (expected_return[0], math.sqrt(risk[0]))

import cvxopt
import numpy
from cvxpy import *
from multiprocessing import Pool
from pylab import figure, show
import math

num_assets = 100
num_factors = 20

mu = cvxopt.exp( cvxopt.normal(num_assets) )
F = cvxopt.normal(num_assets, num_factors)
D = cvxopt.spdiag( cvxopt.uniform(num_assets) )
x = Variable(num_assets)
gamma = Parameter(sign="positive")

expected_return = mu.T * x
variance = square(norm2(F.T*x)) + square(norm2(D*x))

# construct portfolio optimization problem *once*
p = Problem(
    Maximize(expected_return - gamma * variance),
    [sum(x) == 1, x >= 0]
)

# encapsulate the allocation function
def allocate(gamma_value):
    gamma.value = gamma_value
    p.solve()
    w = x.value
    expected_return, risk = mu.T*w, w.T*(F*F.T + D*D)*w
Example #33
0
def sigmoid(X):
	return (1.0 + co.exp(-X))**(-1)
Example #34
0
    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
Example #35
0
c = -matrix([sum( uk for uk, yk in zip(u,y) if yk ), sum(y) ])

# minimize  c'*x + sum log (1 + exp(A*x)) 
#
# variable x (2).

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 
sol = solvers.cp(F)
a, b = sol['x'][0], sol['x'][1]

try: import pylab
except ImportError: pass
else:
    pylab.figure(facecolor='w')
    nopts = 200
    pts = -1.0 + 12.0/nopts * matrix(list(range(nopts))) 
    w = exp(a*pts + b)
    pylab.plot(u, y, 'o', pts, div(w, 1+w), '-')
    pylab.title('Logistic regression (fig. 7.1)')
    pylab.axis([-1, 11, -0.1, 1.1])
    pylab.xlabel('u')
    pylab.ylabel('Prob(y=1)')
    pylab.show()
Example #36
0
# Basis functions are Gabor pulses:  for k = 0,...,K-1,
#
#     exp(-(t - k * tau)^2/sigma^2 ) * cos (l*omega0*t),  l = 0,...,L
#     exp(-(t - k * tau)^2/sigma^2 ) * sin (l*omega0*t),  l = 1,...,L

sigma = 0.05 
tau = 0.002    
omega0 = 5.0
K = 501
L = 30  
N = 501       # number of samples of each signal in [0,1] 

# Build dictionary matrix
ts = (1.0/N) * matrix(range(N), tc='d')
B = ts[:, K*[0]] - tau * matrix(range(K), (1,K), 'd')[N*[0],:]
B = exp(-(B/sigma)**2)
A = matrix(0.0, (N, K*(2*L+1)))

# First K columns are DC pulses for k = 0,...,K-1
A[:,:K] = B
for l in range(L):

    # Cosine pulses for omega = (l+1)*omega0 and k = 0,...,K-1.
    A[:, K+l*(2*K) : K+l*(2*K)+K] = mul(B, cos((l+1)*omega0*ts)[:, K*[0]])

    # Sine pulses for omega = (l+1)*omega0 and k = 0,...,K-1.
    A[:, K+l*(2*K)+K : K+(l+1)*(2*K)] = \
        mul(B, sin((l+1)*omega0*ts)[:,K*[0]])

if pylab_installed:
Example #37
0

# For regions k=1, ..., 6, let pk be the optimal value of 
#
#     minimize    x'*x 
#     subject to  A*x <= b.
#
# The Chernoff upper bound is  1.0 - sum exp( - pk / (2 sigma^2)).

P = matrix([1.0, 0.0, 0.0, 1.0], (2,2))
q = matrix(0.0, (2,1))
optvals = matrix([ blas.nrm2( solvers.qp(P, q, A[k], b[k] )['x'] )**2
    for k in range(1,7) ])
nopts = 200
sigmas = 0.2 + (0.5 - 0.2)/nopts * matrix(list(range(nopts)), tc='d')
bnds = [ 1.0 - sum( exp( - optvals / (2*sigma**2) )) for sigma 
    in sigmas]

try: import pylab
except ImportError: pass
else:
    pylab.figure(facecolor='w')
    pylab.plot(sigmas, bnds, '-')
    pylab.axis([0.2, 0.5, 0.9, 1.0])
    pylab.title('Chernoff lower bound (fig. 7.8)')
    pylab.xlabel('sigma')
    pylab.ylabel('Probability of correct detection')
    pylab.show()
    
    if 0:  # uncomment out for the Monte Carlo estimation.
        N = 100000
# Basis functions are Gabor pulses:  for k = 0,...,K-1,
#
#     exp(-(t - k * tau)^2/sigma^2 ) * cos (l*omega0*t),  l = 0,...,L
#     exp(-(t - k * tau)^2/sigma^2 ) * sin (l*omega0*t),  l = 1,...,L

sigma = 0.05
tau = 0.002
omega0 = 5.0
K = 501
L = 30
N = 501  # number of samples of each signal in [0,1]

# Build dictionary matrix
ts = (1.0 / N) * matrix(range(N), tc='d')
B = ts[:, K * [0]] - tau * matrix(range(K), (1, K), 'd')[N * [0], :]
B = exp(-(B / sigma)**2)
A = matrix(0.0, (N, K * (2 * L + 1)))

# First K columns are DC pulses for k = 0,...,K-1
A[:, :K] = B
for l in range(L):

    # Cosine pulses for omega = (l+1)*omega0 and k = 0,...,K-1.
    A[:, K + l * (2 * K):K + l * (2 * K) + K] = mul(
        B,
        cos((l + 1) * omega0 * ts)[:, K * [0]])

    # Sine pulses for omega = (l+1)*omega0 and k = 0,...,K-1.
    A[:, K+l*(2*K)+K : K+(l+1)*(2*K)] = \
        mul(B, sin((l+1)*omega0*ts)[:,K*[0]])
Example #39
0
def PA_GP_MCS_minRate(channel_alloc, channel_gain, B, noise_vec, priority,
                      SU_power, minRate, SNR_gap, QAM_cap, objective_list):

    n_su = channel_alloc.shape[0]
    n_channel = channel_alloc.shape[1]

    channel_gain = copy.deepcopy(channel_gain)
    Noise = copy.deepcopy(noise_vec)
    channel_gain = channel_gain * (10**8)
    Noise = Noise * (10**8)

    # non-zero power list
    channel_alloc_total = np.sum(channel_alloc, dtype=np.int32)

    def A(m, n, j, t):
        if (t == n):
            return -1
        else:
            if (t == j):
                return 1
            else:
                return 0

    def C(m, n, j):
        if (j == n):
            return (Noise[n]) / (channel_gain[n, n] / SNR_gap[n])
        else:
            return channel_gain[n, j] / (channel_gain[n, n] / SNR_gap[n])

    # Objective function
    F_obj = np.zeros(channel_alloc_total * 2)
    i = 0
    for m in range(n_channel):
        for n in range(n_su):
            if (channel_alloc[n, m] == 1):
                F_obj[channel_alloc_total + i] = priority[n] * B / (10**6)
                i = i + 1

    g_obj = np.zeros(1)

    # Constraints of slack variables (m => n => j)
    n_F_slack = 0
    for m in range(n_channel):
        for n in range(n_su):
            if (channel_alloc[n, m] == 1):
                for j in range(n_su):
                    if (channel_alloc[j, m] == 1):
                        n_F_slack = n_F_slack + 1

    F_slack = np.zeros((n_F_slack, channel_alloc_total * 2))

    index0 = 0
    index1 = 0
    for m in range(n_channel):
        for n in range(n_su):
            if (channel_alloc[n, m] == 1):
                for j in range(n_su):
                    if (channel_alloc[j, m] == 1):
                        F_slack[index0, channel_alloc_total + index1] = -1

                        index3 = 0
                        for t in range(n_su):
                            if (channel_alloc[t, m] == 1):
                                F_slack[index0,
                                        int(np.sum(channel_alloc[:, 0:m])) +
                                        index3] = A(m, n, j, t)
                                index3 = index3 + 1
                        index0 = index0 + 1
                index1 = index1 + 1

    g_slack = np.zeros(n_F_slack)
    index0 = 0
    for m in range(n_channel):
        for n in range(n_su):
            if (channel_alloc[n, m] == 1):
                for j in range(n_su):
                    if (channel_alloc[j, m] == 1):
                        g_slack[index0] = np.log(C(m, n, j))
                        index0 = index0 + 1

    # Constraints of maximum power
    F_power = np.zeros((channel_alloc_total, channel_alloc_total * 2))
    index0 = 0
    for n in range(n_su):
        for m in range(n_channel):
            if (channel_alloc[n, m] == 1):
                F_power[index0,
                        int(np.sum(channel_alloc[:, 0:m])) +
                        int(np.sum(channel_alloc[:(n + 1), m])) - 1] = 1
                index0 = index0 + 1

    g_power = np.zeros(channel_alloc_total)
    index0 = 0
    for n in range(n_su):
        for m in range(n_channel):
            if (channel_alloc[n, m] == 1):
                g_power[index0] = np.log(1 / SU_power[n])
                index0 = index0 + 1

    # Constraints of minimum data rate constraint
    F_minRate = np.zeros((n_su, channel_alloc_total * 2))
    index0 = 0
    for n in range(n_su):
        for m in range(n_channel):
            if (channel_alloc[n, m] == 1):
                F_minRate[n, channel_alloc_total + index0] = B / (10**6)
                index0 = index0 + 1

    g_minRate = np.zeros(n_su)
    for n in range(n_su):
        g_minRate[n] = np.log(2**(minRate[n] / (10**6)))

    # Constraints of QAM capability
    F_QAM = np.zeros((channel_alloc_total, channel_alloc_total * 2))
    index0 = 0
    for m in range(n_channel):
        for n in range(n_su):
            if (channel_alloc[n, m] == 1):
                F_QAM[index0, channel_alloc_total + index0] = 1
                index0 = index0 + 1

    g_QAM = np.zeros(channel_alloc_total)
    index0 = 0
    for m in range(n_channel):
        for n in range(n_su):
            if (channel_alloc[n, m] == 1):
                g_QAM[index0] = np.log(2**-(QAM_cap[n] + 1))
                index0 = index0 + 1

    K_obj = np.ones(1)

    K_slack = n_su * np.ones(channel_alloc_total)
    index0 = 0
    for m in range(n_channel):
        for n in range(n_su):
            if (channel_alloc[n, m] == 1):
                K_slack[index0] = np.sum(channel_alloc[:, m])
                index0 = index0 + 1

    K_power = n_channel * np.ones(n_su)
    for n in range(n_su):
        K_power[n] = np.sum(channel_alloc[n, :])

    K_minRate = np.ones(n_su)

    K_QAM = np.ones(channel_alloc_total)

    K_arr = np.concatenate((K_obj, K_slack, K_power, K_minRate, K_QAM))
    K_arr = K_arr.astype(int)

    F_arr = np.vstack((F_obj, F_slack, F_power, F_minRate, F_QAM))

    g_arr = np.concatenate((g_obj, g_slack, g_power, g_minRate, g_QAM))

    K = K_arr.tolist()
    F_arr = F_arr.T
    F = cvx.matrix(F_arr.tolist())
    g_arr = g_arr.T
    g = cvx.matrix(g_arr.tolist())

    cvx.solvers.options['show_progress'] = False

    sol = cvx.exp(cvx.solvers.gp(K, F, g, quiet=True)['x'])

    power_alloc = np.zeros((n_su, n_channel))
    index0 = 0
    for m in range(n_channel):
        for n in range(n_su):
            if (channel_alloc[n, m] == 1):
                power_alloc[n, m] = sol[index0]
                index0 = index0 + 1

    objective_list['total'].append(
        objective_value(channel_alloc, power_alloc, priority,
                        channel_gain / (10**8), B, noise_vec, SNR_gap))

    return power_alloc
Example #40
0
# The small GP of section 9.3 (Geometric programming).

from cvxopt import matrix, log, exp, solvers  
 
Aflr  = 1000.0  
Awall = 100.0  
alpha = 0.5  
beta  = 2.0  
gamma = 0.5  
delta = 2.0  
 
F = matrix( [[-1., 1., 1., 0., -1.,  1.,  0.,  0.],  
             [-1., 1., 0., 1.,  1., -1.,  1., -1.],  
             [-1., 0., 1., 1.,  0.,  0., -1.,  1.]])  
g = log( matrix( [1.0, 2/Awall, 2/Awall, 1/Aflr, alpha, 1/beta, gamma, 
    1/delta]) )  
K = [1, 2, 1, 1, 1, 1, 1]  
h, w, d = exp( solvers.gp(K, F, g)['x'] )
print("\n h = %f,  w = %f, d = %f.\n" %(h,w,d))   
Example #41
0

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


sol = solvers.cp(F)
a, b = sol['x'][0], sol['x'][1]

try:
    import pylab
except ImportError:
    pass
else:
    pylab.figure(facecolor='w')
    nopts = 200
    pts = -1.0 + 12.0 / nopts * matrix(list(range(nopts)))
    w = exp(a * pts + b)
    pylab.plot(u, y, 'o', pts, div(w, 1 + w), '-')
    pylab.title('Logistic regression (fig. 7.1)')
    pylab.axis([-1, 11, -0.1, 1.1])
    pylab.xlabel('u')
    pylab.ylabel('Prob(y=1)')
    pylab.show()
    def _solve(self):
        # An alias to the internal problem instance.
        p = self.int

        # This class doubles as an implementation for the SMCP solver.
        solver = self.ext.options['solver'].lower()
        assert solver in ("cvxopt", "smcp")

        isGP = self._is_geometric_program()

        # Check if the problem type is supported.
        # TODO: Check if general-obj problems are properly handled.
        if solver == 'smcp':
            # SMCP is a standalone solver made available through the SMCPSolver
            # class. However, since SMCP both depends on CVXOPT and has a
            # similar interface, its logic is implemented inside CVXOPTSolver,
            # and SMCPSolver subclasses it. Ensure that self is indeed a
            # SMCPSolver instance.
            assert self.__class__.__name__ == "SMCPSolver", \
                "SMCP needs to be used through the SMCPSolver class."
            import smcp

        # Clear all options set previously. This is necessary because CVXOPT
        # options are global, and might be changed even by another problem.
        cvx.solvers.options.clear()

        # Handle "verbose" option.
        cvx.solvers.options['show_progress'] = (self.verbosity() >= 1)

        # Handle "tol", "feastol", "abstol" and "reltol" options.
        feastol = self.ext.options['feastol']
        if feastol is None:
            feastol = self.ext.options['tol']
        abstol = self.ext.options['abstol']
        if abstol is None:
            abstol = self.ext.options['tol']
        reltol = self.ext.options['reltol']
        if reltol is None:
            reltol = 10 * self.ext.options['tol']
        cvx.solvers.options['feastol'] = feastol
        cvx.solvers.options['abstol'] = abstol
        cvx.solvers.options['reltol'] = reltol

        # Handle "maxit" option.
        maxit = self.ext.options['maxit']
        if maxit is None:
            maxit = int(1e6)
        cvx.solvers.options['maxiters'] = maxit

        # Allow solving GPs that are not strictly feasible.
        # TODO: Turn this into a proper option?
        cvx.solvers.options['kktreg'] = 1e-6

        # Handle unsupported options.
        self._handle_unsupported_options('lp_root_method', 'lp_node_method',
                                         'timelimit', 'treememory', 'nbsol',
                                         'hotstart')

        # TODO: Add CVXOPT-sepcific options. Candidates are:
        #       - refinement

        # Set options for SMCP.
        if solver == 'smcp':
            # Restore default options.
            smcp.solvers.options = self._smcp_default_options.copy()

            # Copy options also used by CVXOPT.
            smcp.solvers.options.update(cvx.solvers.options)

            # Further handle "verbose" option.
            smcp.solvers.options['debug'] = (self.verbosity() >= 2)

            # TODO: Add SMCP-sepcific options.

        if self._debug():
            from pprint import pformat
            if solver == 'smcp':
                options = smcp.solvers.options
            else:
                options = cvx.solvers.options
            self._debug("Setting options:\n{}\n".format(pformat(options)))

        # Print a header.
        if solver == 'smcp':
            subsolverText = None
        else:
            if isGP:
                subsolverText = 'internal GP solver'
            else:
                subsolverText = 'internal CONELP solver'

        # Further prepare the problem for the CVXOPT/SMCP CONELP solvers.
        # TODO: This should be done during import.
        if not isGP:
            # Retrieve the structure of the cone, which is a cartesian product
            # of the non-negative orthant of dimension l, a number of second
            # order cones with dimensions in q and a number of positive
            # semidefinite cones with dimensions in s.
            dims = {
                'l': p['Gl'].size[0],
                'q': [Gqi.size[0] for Gqi in p['Gq']],
                's': [int(numpy.sqrt(Gsi.size[0])) for Gsi in p['Gs']]
            }

            # Construct G and h to contain all conic inequalities, starting with
            # those with respect to the non-negative orthant.
            G = p['Gl']
            h = p['hl']

            # SMCP's ConeLP solver does not handle (linear) equalities, so cast
            # them as inequalities.
            if solver == 'smcp':
                if p['A'].size[0] > 0:
                    G = cvx.sparse([G, p['A']])
                    G = cvx.sparse([G, -p['A']])
                    h = cvx.matrix([h, p['b']])
                    h = cvx.matrix([h, -p['b']])
                    dims['l'] += (2 * p['A'].size[0])

            # Add second-order cone inequalities.
            for i in range(len(dims['q'])):
                G = cvx.sparse([G, p['Gq'][i]])
                h = cvx.matrix([h, p['hq'][i]])

            # Add semidefinite cone inequalities.
            for i in range(len(dims['s'])):
                G = cvx.sparse([G, p['Gs'][i]])
                h = cvx.matrix([h, p['hs'][i]])

            # Remove zero lines from linear equality constraint matrix, as
            # CVXOPT expects this matrix to have full row rank.
            JP = list(set(p['A'].I))
            IP = range(len(JP))
            VP = [1] * len(JP)
            if any([b for (i, b) in enumerate(p['b']) if i not in JP]):
                raise SolverError(
                    'Infeasible constraint of the form 0 = a with a != 0.')
            P = spmatrix(VP, IP, JP, (len(IP), p['A'].size[0]))
            A = P * p['A']
            b = P * p['b']

        # Attempt to solve the problem.
        with self._header(subsolverText), self._stopwatch():
            if solver == 'smcp':
                if self._debug():
                    self._debug(
                        "Calling smcp.solvers.conelp(c, G, h, dims) "
                        "with\nc:\n{}\nG:\n{}\nh:\n{}\ndims:\n{}\n".format(
                            p['c'], G, h, dims))
                try:
                    result = smcp.solvers.conelp(p['c'], G, h, dims)
                except TypeError:
                    # HACK: Work around "'NoneType' object is not subscriptable"
                    #       exception with infeasible/unbounded problems.
                    result = None
            else:
                if isGP:
                    result = cvx.solvers.gp(p['K'],
                                            p['F'],
                                            p['g'],
                                            p['Gl'],
                                            p['hl'],
                                            p['A'],
                                            p['b'],
                                            kktsolver='ldl')
                else:
                    result = cvx.solvers.conelp(p['c'], G, h, dims, A, b)

        # Retrieve primals.
        if self.ext.options["noprimals"]:
            primals = None
        elif result is None or result["x"] is None:
            primals = None
        else:
            primals = {}

            # Retrieve values for all but LSE auxiliary variables.
            for var in self.ext.variables.values():
                # Auxiliary variables for LSE metaconstraints have no
                # meaningful value at this point.
                if isinstance(var.origin, LSEConstraint):
                    continue

                # HACK: Cast from numpy array to list so that _retrieve_matrix
                #       will respect the target matrix size.
                # TODO: Refactor _retrieve_matrix to handle different input
                #       types consistently.
                value = list(result["x"][var.startIndex:var.endIndex])

                primals[var.name] = value

            # Give auxiliary variables added for an LSE metaconstraint a
            # solution value.
            for var in self.ext.variables.values():
                if isinstance(var.origin, LSEConstraint):
                    value = []
                    for i, exponent in enumerate(var.origin.le0Exponents):
                        value.append(
                            cvx.matrix(exponent.constant if exponent.
                                       constant else 0.0))
                        for v, factor in exponent.factors.items():
                            value[i] += factor * cvx.matrix(primals[v.name])
                        value[i] = cvx.exp(value[i])[0, 0]
                    primals[var.name] = cvx.matrix(value, var.size)

        # Retrieve duals.
        if self.ext.options["noduals"]:
            duals = None
        elif result is None:
            duals = None
        else:
            duals = []
            (indy, indzl, indzq, indznl, indzs) = (0, 0, 0, 0, 0)

            if isGP:
                zkey = 'zl'
                zqkey = 'zq'
                zskey = 'zs'
            else:
                zkey = 'z'
                zqkey = 'z'
                zskey = 'z'
                indzq = dims['l']
                indzs = dims['l'] + _bsum(dims['q'])

            if solver == 'smcp':
                # Equality constraints were cast as two inequalities.
                ieq = p['Gl'].size[0]
                neq = (dims['l'] - ieq) // 2
                soleq = result['z'][ieq:ieq + neq]
                soleq -= result['z'][ieq + neq:ieq + 2 * neq]
            else:
                soleq = result['y']

            seenLSEConstraints = []

            for constraint in self.ext.constraints:
                dual = None
                consSz = len(constraint)

                if isinstance(constraint.origin, LSEConstraint):
                    # We are looking at an auxiliary constraint for a
                    # metaconstraint that was imported directly.

                    # We don't get any duals:
                    # - The affine constraint was imported for technical reasons
                    #   and all variables used in it are irrelevant to the
                    #   objective function. Hence the dual will always be 0.
                    #   We don't store it since that could produce a bad result
                    #   when querying the LSE metaconstraint for its dual.
                    # - The exponential cone constraints were never imported.
                    #   Instead, a single LSE constraint was imported.
                    if isinstance(constraint, AffineConstraint):
                        assert constraint.is_inequality()
                        indzl += len(constraint)  # = 1
                    else:
                        assert isinstance(constraint, ExpConeConstraint)
                        if constraint.origin not in seenLSEConstraints:
                            indznl += len(constraint.origin)  # = 1
                            seenLSEConstraints.append(constraint.origin)
                elif isinstance(constraint, AffineConstraint):
                    if constraint.is_equality():
                        if soleq is not None:
                            dual = (P.T * soleq)[indy:indy + consSz]
                            indy += consSz
                    else:
                        if result[zkey] is not None:
                            dual = result[zkey][indzl:indzl + consSz]
                            indzl += consSz
                elif isinstance(constraint, SOCConstraint) \
                or isinstance(constraint, RSOCConstraint):
                    if result[zqkey] is not None:
                        if isGP:
                            dual = result[zqkey][indzq]
                            dual[1:] = -dual[1:]
                            indzq += 1
                        else:
                            dual = result[zqkey][indzq:indzq + consSz]
                            # Swap the sign of the SOcone's Lagrange multiplier,
                            # as PICOS wants it the other way round.
                            # Note that this also affects RScone constraints
                            # which were cast as SOcone constraints on import.
                            dual[1:] = -dual[1:]
                            if isinstance(constraint, RSOCConstraint):
                                # RScone were cast as a SOcone on import, so
                                # transform the dual to a proper RScone dual.
                                alpha = dual[0] - dual[-1]
                                beta = dual[0] + dual[-1]
                                z = 2.0 * dual[1:-1]
                                dual = cvx.matrix([alpha, beta, z])
                            indzq += consSz
                elif isinstance(constraint, LMIConstraint):
                    if result[zskey] is not None:
                        matSz = constraint.size[0]
                        if isGP:
                            dual = cvx.matrix(result[zskey][indzs],
                                              (matSz, matSz))
                            indzs += 1
                        else:
                            dual = cvx.matrix(
                                result[zskey][indzs:indzs + consSz],
                                (matSz, matSz))
                            indzs += consSz

                duals.append(dual)

        # Retrieve objective value.
        if result is None:
            objectiveValue = None
        elif isGP:
            objectiveValue = 'toEval'
        else:
            p = result['primal objective']
            d = result['dual objective']
            if p is not None and d is not None:
                objectiveValue = 0.5 * (p + d)
            elif p is not None:
                objectiveValue = p
            elif d is not None:
                objectiveValue = d
            else:
                objectiveValue = None
            if self.ext.objective[0] == 'max' and objectiveValue is not None:
                objectiveValue = -objectiveValue

        # Retrieve solution metadata.
        meta = {
            'cvxopt_sol': result,
            'status': result['status'] if result else "unavailable"
        }

        return (primals, duals, objectiveValue, meta)
Example #43
0
        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