def price(): buy_price=np.zeros(365*48) sell_price=np.zeros(365*48) count=0 import csv with open('price.csv',newline='') as csvfile: raw_price=csv.reader(csvfile,delimiter=',') for row in raw_price: buy_price[count]=max(0.00001,float(row[0])) sell_price[count]=max(0.00001,float(row[1])) count+=1 return [buy_price,sell_price]
def energy_system_conditioal(pv,load,storage,buy_price,sell_price,period): #period indicates which day of year the energy system is run total_output=np.array([0]*len(pv[0]['output']),dtype=float) for pvid in pv: total_output+=pv[pvid]['output'] fix_load=np.array(load[1]+load[3]) #load which assmued to be accurately predicted, which is heat load float_load=np.array(load[0])+np.array(load[2]) #Load which cannot be predicited accurately total_load=np.array([0]*len(load[0]),dtype=float) for loadid in load: total_load+=np.array(load[loadid]) excess=total_output-fix_load-float_load storage_time=0 #At time 0, storage has now charge. Storage records the charge avaliable for this time slot buy=[] #Power bought from market, negative means sold balancing=[] #Record power taken or given by storage to meet excess power, after accounting efficiency for day in period: float_load_est=float_load[48*(day-7):48*(day-5)] max_sell_price=np.amax(sell_price[48*day:48*day+47]) max_sell_price_t=np.argmax(sell_price[48*day:48*day+47]) #Find the index of maximum sell price of the day max_sell_price_t_list=np.flip(np.argsort(sell_price[48*day:48*day+47])) #List of times with desecding sell price # sunrise=0 # for sun in total_output[48*(day+1):]: #Find the sunrise of next day # if sun > 0: # break # sunrise+=1 save=max(0,-sum(total_output[day*48+max_sell_price_t:day*48+38])+sum(float_load_est[max_sell_price_t:38])+sum(fix_load[day*48+max_sell_price_t:day*48+38])) #Maximum price always occur between t=31 and t=38, this sum all estimated load between maximum price and 19:00 max_buy_price=np.amax(buy_price[day*48+39:day*48+78]) #Find maximum buy price between 19:00 of today and 16:00 of tomorrow # print(max_sell_price-max_buy_price) for t in range(48): dexcess=excess[day*48+t] balancing.append(0) for storageid in storage: #run through all storage facilities if t in max_sell_price_t_list[0:4]: #Decide how many time periods will be used for forced export # if 31<=t<=38 and dexcess>=0: # if max(max_sell_price_t,31)<=t<=38 and dexcess>=0: #Sell everything when max_sell_price>max_buy_price # if sell_price[day*48+t]>=max_buy_price and 31<=t<=38 and dexcess>=0: charge_power=-min(storage[storageid]['power'],storage[storageid]['stored'][storage_time],50000-dexcess) # print(charge_power) dexcess-=charge_power*storage[storageid]['efficiency'] #amount of power taken from dexcess, after accounting efficiency balancing[storage_time]-=charge_power*storage[storageid]['efficiency'] else: if dexcess>=0: #pv > load, storage charging charge_power=min(dexcess*storage[storageid]['efficiency'],storage[storageid]['capacity']-storage[storageid]['stored'][storage_time],storage[storageid]['power']) #charge power is the lesser of dexcess or remaining space of storage dexcess-=charge_power/storage[storageid]['efficiency'] #amount of power taken from dexcess, after accounting efficiency balancing[storage_time]-=charge_power/storage[storageid]['efficiency'] else: #pv < load, storage discharging charge_power=max(dexcess/storage[storageid]['efficiency'],-storage[storageid]['stored'][storage_time],-storage[storageid]['power']) #charge power is the less negative of dexcess or remaining charge dexcess-=charge_power*storage[storageid]['efficiency'] #amount of power given to dexcess, after accounting efficiency balancing[storage_time]-=charge_power*storage[storageid]['efficiency'] storage[storageid]['stored'].append(storage[storageid]['stored'][storage_time]+charge_power) storage_time+=1 buy.append(-dexcess) # print(max(buy, key=abs)) return [buy,total_output,total_load,balancing]
def setUp(self): """ Use cvxopt to get ground truth values """ from cvxopt import lapack, solvers, matrix, spdiag, log, div, normal, setseed from cvxopt.modeling import variable, op, max, sum solvers.options['show_progress'] = 0 setseed() m, n = 100, 30 A = normal(m, n) b = normal(m, 1) b /= (1.1 * max(abs(b))) self.m, self.n, self.A, self.b = m, n, A, b # l1 approximation # minimize || A*x + b ||_1 x = variable(n) op(sum(abs(A * x + b))).solve() self.x1 = x.value # l2 approximation # minimize || A*x + b ||_2 bprime = -matrix(b) Aprime = matrix(A) lapack.gels(Aprime, bprime) self.x2 = bprime[:n] # Deadzone approximation # minimize sum(max(abs(A*x+b)-0.5, 0.0)) x = variable(n) dzop = op(sum(max(abs(A * x + b) - 0.5, 0.0))) dzop.solve() self.obj_dz = sum( np.max([np.abs(A * x.value + b) - 0.5, np.zeros((m, 1))], axis=0)) # Log barrier # minimize -sum (log ( 1.0 - (A*x+b)**2)) def F(x=None, z=None): if x is None: return 0, matrix(0.0, (n, 1)) y = A * x + b if max(abs(y)) >= 1.0: return None f = -sum(log(1.0 - y**2)) gradf = 2.0 * A.T * div(y, 1 - y**2) if z is None: return f, gradf.T H = A.T * spdiag(2.0 * z[0] * div(1.0 + y**2, (1.0 - y**2)**2)) * A return f, gradf.T, H self.cxlb = solvers.cp(F)['x']
def setUp(self): """ Use cvxopt to get ground truth values """ from cvxopt import lapack,solvers,matrix,spdiag,log,div,normal,setseed from cvxopt.modeling import variable,op,max,sum solvers.options['show_progress'] = 0 setseed() m,n = 100,30 A = normal(m,n) b = normal(m,1) b /= (1.1*max(abs(b))) self.m,self.n,self.A,self.b = m,n,A,b # l1 approximation # minimize || A*x + b ||_1 x = variable(n) op(sum(abs(A*x+b))).solve() self.x1 = x.value # l2 approximation # minimize || A*x + b ||_2 bprime = -matrix(b) Aprime = matrix(A) lapack.gels(Aprime,bprime) self.x2 = bprime[:n] # Deadzone approximation # minimize sum(max(abs(A*x+b)-0.5, 0.0)) x = variable(n) dzop = op(sum(max(abs(A*x+b)-0.5, 0.0))) dzop.solve() self.obj_dz = sum(np.max([np.abs(A*x.value+b)-0.5,np.zeros((m,1))],axis=0)) # Log barrier # minimize -sum (log ( 1.0 - (A*x+b)**2)) def F(x=None, z=None): if x is None: return 0, matrix(0.0,(n,1)) y = A*x+b if max(abs(y)) >= 1.0: return None f = -sum(log(1.0 - y**2)) gradf = 2.0 * A.T * div(y, 1-y**2) if z is None: return f, gradf.T H = A.T * spdiag(2.0*z[0]*div(1.0+y**2,(1.0-y**2)**2))*A return f,gradf.T,H self.cxlb = solvers.cp(F)['x']
def energy_system(pv,load,storage): total_output=np.array([0]*len(pv[0]['output']),dtype=float) for pvid in pv: total_output+=pv[pvid]['output'] total_load=np.array([0]*len(load[0]),dtype=float) for loadid in load: total_load+=np.array(load[loadid]) excess=total_output-total_load #Calculate excess power before using storage storage_time=0 #At time 0, storage has now charge. Storage records the charge avaliable for this time slot buy=[] #Power bought from market, negative means sold balancing=[] #Record power taken or given by storage to meet excess power, after accounting efficiency for dexcess in excess: #dexcess is the excess at this time slot balancing.append(0) for storageid in storage: #run through all storage facilities #charge power is the amount charged to storage if dexcess>=0: #pv > load, storage charging charge_power=min(dexcess*storage[storageid]['efficiency'],storage[storageid]['capacity']-storage[storageid]['stored'][storage_time],storage[storageid]['power']) #charge power is the lesser of dexcess or remaining space of storage dexcess-=charge_power/storage[storageid]['efficiency'] #amount of power taken from dexcess, after accounting efficiency balancing[storage_time]-=charge_power/storage[storageid]['efficiency'] else: #pv < load, storage discharging charge_power=max(dexcess/storage[storageid]['efficiency'],-storage[storageid]['stored'][storage_time],-storage[storageid]['power']) #charge power is the less negative of dexcess or remaining charge dexcess-=charge_power*storage[storageid]['efficiency'] #amount of power given to dexcess, after accounting efficiency balancing[storage_time]-=charge_power*storage[storageid]['efficiency'] storage[storageid]['stored'].append(storage[storageid]['stored'][storage_time]+charge_power) storage_time+=1 buy.append(-dexcess) return [buy,total_output,total_load,balancing]
def F(x=None, z=None): if x is None: return 0, matrix(0.0,(n,1)) y = A*x+b if max(abs(y)) >= 1.0: return None f = -sum(log(1.0 - y**2)) gradf = 2.0 * A.T * div(y, 1-y**2) if z is None: return f, gradf.T H = A.T * spdiag(2.0*z[0]*div(1.0+y**2,(1.0-y**2)**2))*A return f,gradf.T,H
def F(x=None, z=None): if x is None: return 0, matrix(0.0, (n, 1)) y = A * x + b if max(abs(y)) >= 1.0: return None f = -sum(log(1.0 - y**2)) gradf = 2.0 * A.T * div(y, 1 - y**2) if z is None: return f, gradf.T H = A.T * spdiag(2.0 * z[0] * div(1.0 + y**2, (1.0 - y**2)**2)) * A return f, gradf.T, H
def test_case3(self): m, n = 500, 100 setseed(100) A = normal(m,n) b = normal(m) x1 = variable(n) lp1 = op(max(abs(A*x1-b))) lp1.solve() self.assertTrue(lp1.status == 'optimal') x2 = variable(n) lp2 = op(sum(abs(A*x2-b))) lp2.solve() self.assertTrue(lp2.status == 'optimal') x3 = variable(n) lp3 = op(sum(max(0, abs(A*x3-b)-0.75, 2*abs(A*x3-b)-2.25))) lp3.solve() self.assertTrue(lp3.status == 'optimal')
def test_case3(self): m, n = 500, 100 setseed(100) A = normal(m, n) b = normal(m) x1 = variable(n) lp1 = op(max(abs(A * x1 - b))) lp1.solve() self.assertTrue(lp1.status == 'optimal') x2 = variable(n) lp2 = op(sum(abs(A * x2 - b))) lp2.solve() self.assertTrue(lp2.status == 'optimal') x3 = variable(n) lp3 = op( sum(max(0, abs(A * x3 - b) - 0.75, 2 * abs(A * x3 - b) - 2.25))) lp3.solve() self.assertTrue(lp3.status == 'optimal')
def barrier(): # variables kept same from cvxopt example MAXITERS = 100 ALPHA = 0.01 BETA = 0.5 x = matrix(0.0, (n, 1)) H = matrix(0.0, (n, n)) # Symmetrix matrix for iter in range(MAXITERS): # get the gradient of the function d = (b - A * x)**-1 g = A.T * d # print(d[:, n*[0]].size) # print(A.size) """bug here: won't multiply of two matrix of same dimension. code is looking into another dimension?""" # get Hessian # lower diaganol multiplied to constraint matrix, n*[0] is first center x^t(0) h = np.zeros(shape=(m, n)) np.matmul(d[:, n * [0]], A, h) # use the BLAS solver to get the symmetric matrix and get roots blas.syrk(h, H, trans='T') # do Newton's step v = -g # g is our gradient # LAPACK solves the matrix and gives us the tep value to transverse with lapack.posv(H, v) # Stop condition if exceeding tolerance lam = blas.dot(g, v) if sqrt(-lam) < mu: return x # return the orignal value if we're above tolerance # Line search to go to optimal using ALPHA and BETA 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 # increment x by the step times the negative gradient otherwise x += step * v
def test_problem_penalty(self): """ Compare cvxpy solutions to cvxopt ground truth """ from cvxpy import (matrix, variable, program, minimize, sum, abs, norm2, log, square, zeros, max, hstack, vstack) m, n = self.m, self.n A = matrix(self.A) b = matrix(self.b) # set tolerance to 5 significant digits tol_exp = 5 # l1 approximation x = variable(n) p = program(minimize(sum(abs(A * x + b)))) p.solve(True) np.testing.assert_array_almost_equal(x.value, self.x1, tol_exp) # l2 approximation x = variable(n) p = program(minimize(norm2(A * x + b))) p.solve(True) np.testing.assert_array_almost_equal(x.value, self.x2, tol_exp) # Deadzone approximation - implementation is currently ugly (need max along axis) x = variable(n) Axbm = abs(A * x + b) - 0.5 Axbm_deadzone = vstack( [max(hstack((Axbm[i, 0], 0.0))) for i in range(m)]) p = program(minimize(sum(Axbm_deadzone))) p.solve(True) obj_dz_cvxpy = np.sum( np.max([np.abs(A * x.value + b) - 0.5, np.zeros((m, 1))], axis=0)) np.testing.assert_array_almost_equal(obj_dz_cvxpy, self.obj_dz, tol_exp) # Log barrier x = variable(n) p = program(minimize(-sum(log(1.0 - square(A * x + b))))) p.solve(True) np.testing.assert_array_almost_equal(x.value, self.cxlb, tol_exp)
def test_problem_penalty(self): """ Compare cvxpy solutions to cvxopt ground truth """ from cvxpy import (matrix,variable,program,minimize, sum,abs,norm2,log,square,zeros,max, hstack,vstack) m, n = self.m, self.n A = matrix(self.A) b = matrix(self.b) # set tolerance to 5 significant digits tol_exp = 5 # l1 approximation x = variable(n) p = program(minimize(sum(abs(A*x + b)))) p.solve(True) np.testing.assert_array_almost_equal(x.value,self.x1,tol_exp) # l2 approximation x = variable(n) p = program(minimize(norm2(A*x + b))) p.solve(True) np.testing.assert_array_almost_equal(x.value,self.x2,tol_exp) # Deadzone approximation - implementation is currently ugly (need max along axis) x = variable(n) Axbm = abs(A*x+b)-0.5 Axbm_deadzone = vstack([max(hstack((Axbm[i,0],0.0))) for i in range(m)]) p = program(minimize(sum(Axbm_deadzone))) p.solve(True) obj_dz_cvxpy = np.sum(np.max([np.abs(A*x.value+b)-0.5,np.zeros((m,1))],axis=0)) np.testing.assert_array_almost_equal(obj_dz_cvxpy,self.obj_dz,tol_exp) # Log barrier x = variable(n) p = program(minimize(-sum(log(1.0-square(A*x + b))))) p.solve(True) np.testing.assert_array_almost_equal(x.value,self.cxlb,tol_exp)
# The 1-norm support vector classifier of section 10.5 (Examples). from cvxopt import normal, setseed from cvxopt.modeling import variable, op, max, sum from cvxopt.blas import nrm2 m, n = 500, 100 A = normal(m,n) x = variable(A.size[1],'x') u = variable(A.size[0],'u') op(sum(abs(x)) + sum(u), [A*x >= 1-u, u >= 0]).solve() x2 = variable(A.size[1],'x') op(sum(abs(x2)) + sum(max(0, 1 - A*x2))).solve() print("\nDifference between two solutions: %e" %nrm2(x.value - x2.value))
def cvxopt(storage_size_list): cost_list=[] for storage_max in storage_size_list: storage_max=float(storage_max) storage_power=storage_max/4 [buy_price,sell_price]=price() pvl=236000*0.9*0.2*0.9*solar_data()+88000*0.9*0.2*0.9*solar_data_flat() fix_load=load_heat_data()+hot_water() #load which assmued to be accurately predicted, which is heat load float_load=residential()+load_sciencepark() #Load which cannot be predicited accurately, so predicted by data of a week ago use_load=fix_load+np.roll(float_load,7*48) #Estimated total load to be used for cvxopt ''' #use_load=load_heat_data()+hot_water()+residential()+load_sciencepark() eff=math.sqrt(0.85) start=200 end=207 duration=(end-start)*48 day_i=list(range(start*48,end*48)) cml=([-1.]+[0.]*(duration-1)+[1.])*(duration-1)+[-1.] #cml=([-math.sqrt(0.85)]+[0.]*(duration-1)+[math.sqrt(0.85)])*(duration-1)+[-math.sqrt(0.85)] #cml=([-0.85]+[0.]*(duration-1)+[0.85])*(duration-1)+[-0.85] cm=matrix(cml,(duration,duration)) pv=matrix(pvl[day_i],(duration,1)) load=matrix(use_load[day_i],(duration,1)) bp=matrix(buy_price[day_i],(duration,1)) sp=matrix(sell_price[day_i],(duration,1)) storage_max=100000. zero=matrix([0.]*duration,(duration,1)) emax=matrix([storage_max]*duration,(duration,1)) #maximum storage pmax=matrix([50.e3]*duration,(duration,1)) #maximum power to grid charge_pmax=matrix([25000.]*duration,(duration,1)) effm=matrix([eff]*duration,(duration,1)) ieffm=matrix([1/eff]*duration,(duration,1)) #discharge_pmax=matrix([-25000.]*duration,(duration,1)) e=variable(duration) #Stored energy c=variable(duration) #Charging energy d=variable(duration) #Discharging energy b=variable(duration) #Buy s=variable(duration) #Sell i1=(b>=zero) i2=(s>=zero) i3=(e>=zero) i4=(e<=emax) i5=(b<=pmax) i6=(s<=pmax) i7=(c<=charge_pmax) i8=(d<=charge_pmax) i9=(c>=zero) i10=(d>=zero) e1=(c/eff-d*eff+load-pv==b-s) e2=(e[0]==matrix([0.])) e3=(c-d==cm*e) ob=dot(b,bp)-dot(s,sp) lp=op(ob,[i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,e1,e2,e3]) solvers.options['show_progress'] = True lp.solve() ''' eff=math.sqrt(0.85) start=0 end=365 duration=(end-start)*48 day_i=list(range(start*48,end*48)) cvxopt_balancing=[] cvxopt_buy=np.array([]) #Record power traded with grid, positive = import cvxopt_storage=np.array([]) #Record amount of stored energy day_cost=0 for day in range(start,end): time_index=list(range(day*48,day*48+48)) cml=([-1.]+[0.]*(48-1)+[1.])*(48-1)+[-1.] #cml=([-math.sqrt(0.85)]+[0.]*(duration-1)+[math.sqrt(0.85)])*(duration-1)+[-math.sqrt(0.85)] #cml=([-0.85]+[0.]*(duration-1)+[0.85])*(duration-1)+[-0.85] cm=matrix(cml,(48,48)) pv=matrix(pvl[time_index],(48,1)) load=matrix(use_load[time_index],(48,1)) bp=matrix(buy_price[time_index],(48,1)) sp=matrix(sell_price[time_index],(48,1)) zero=matrix([0.]*48,(48,1)) emax=matrix([storage_max]*48,(48,1)) #maximum storage pmax=matrix([50.e3]*48,(48,1)) #maximum power to grid charge_pmax=matrix([storage_power]*48,(48,1)) #discharge_pmax=matrix([-25000.]*duration,(duration,1)) e=variable(48) #Stored energy c=variable(48) #Charging energy d=variable(48) #Discharging energy b=variable(48) #Buy s=variable(48) #Sell i1=(b>=zero) i2=(s>=zero) i3=(e>=zero) i4=(e<=emax) i5=(b<=pmax) i6=(s<=pmax) i7=(c<=charge_pmax) i8=(d<=charge_pmax) i9=(c>=zero) i10=(d>=zero) i11=(c[47]-d[47]+e[47]>=matrix([0.])) i12=(c[47]-d[47]+e[47]<=matrix([storage_max])) e1=(c/eff-d*eff+load-pv==b-s) if day == start: e2=(e[0]==matrix([0.])) else: next_storage=cvxopt_storage[-1]-cvxopt_balancing[-1] e2=(e[0]==matrix(next_storage)) e3=(c-d==cm*e) ob=dot(b,bp)-dot(s,sp) lp=op(ob,[i1,i2,i3,i4,i5,i6,i7,i8,i9,i10,i11,i12,e1,e2,e3]) solvers.options['show_progress'] = False lp.solve() day_cost+=lp.objective.value()[0] for t in range(0,48): cvxopt_balancing.append(d.value[t]-c.value[t]) cvxopt_buy=np.append(cvxopt_buy,b.value[t]-s.value[t]) cvxopt_storage=np.append(cvxopt_storage,e.value[t]) #print(b.value[47]-s.value[47]) #print(c.value[47]*eff-d.value[47]/eff+e.value[47]) # print(day_cost) buy=[] charge_power_l=[] balancing_l=[] storage=np.array([e.value[0]]) #Initial charge in storage decided by cvxopt excess=(pvl-fix_load-float_load)[day_i] for t in range(duration): if cvxopt_balancing[t]>0: #Storage discharge if cvxopt_balancing[t]>storage[t]: #CVXOPT wants more discharge than currently stored # balancing=-storage[t]*eff #Storage discharge all stored charge_power=-storage[t] # print('a') else: # balancing=-cvxopt_balancing[t]*eff #Do as CVXOPT wants charge_power=-cvxopt_balancing[t] # print('b') else: #Storage charge if cvxopt_balancing[t]>storage_max-storage[t]: #CVXOPT wants to charge more than remaining capacity # balancing=(storage_max-storage[t])/eff #Charge by remaining capacity charge_power=storage_max-storage[t] # print('c') else: # balancing=-cvxopt_balancing[t]/eff #Do as CVXOPT wants charge_power=-cvxopt_balancing[t] # print('d') if charge_power>0: balancing=charge_power/eff else: balancing=charge_power*eff buy.append(-excess[t]+balancing) balancing_l.append(balancing) charge_power_l.append(-charge_power) storage=np.append(storage,storage[t]+charge_power) # print(t,excess[t],charge_power,cvxopt_balancing[t]) # print(buy[t],cvxopt_buy[t]) # print(storage[t],cvxopt_storage[t]) running_cost=market(buy,sell_price[day_i],buy_price[day_i]) # print(running_cost) cost_list.append(running_cost) print(max(max(buy-cvxopt_buy),-min(buy-cvxopt_buy))) #print(sell_price[day_i]) #print(buy_price[day_i]) #fig,ax=plt.subplots() #ax.plot(list(range(0,duration)),(fix_load+float_load)[day_i],'-r',label='actual') #ax.plot(list(range(0,duration)),use_load[day_i],'-b',label='estimate') #ax.step(list(range(0,duration)),buy,'-r',label='actual') #ax.step(list(range(0,duration)),cvxopt_buy,'-b',label='estimate') #ax.step(list(range(0,duration)),charge_power_l,'-r',label='actual') #ax.step(list(range(0,duration)),cvxopt_balancing,'-b',label='estimate') #ax.step(list(range(0,duration+1)),storage,'-b',label='estimate') #fig.legend() return cost_list
# Figure 6.2, page 297. # Penalty approximation. # # The problem data are not the same as in the book figure. import pylab, numpy from cvxopt import lapack, solvers, matrix, spdiag, log, div, normal from cvxopt.modeling import variable, op, max, sum solvers.options['show_progress'] = 0 m, n = 100, 30 A = normal(m, n) b = normal(m, 1) b /= (1.1 * max(abs(b))) # Make x = 0 feasible for log barrier. # l1 approximation # # minimize || A*x + b ||_1 x = variable(n) op(sum(abs(A * x + b))).solve() x1 = x.value pylab.figure(1, facecolor='w', figsize=(10, 10)) pylab.subplot(411) nbins = 100 bins = [-1.5 + 3.0 / (nbins - 1) * k for k in xrange(nbins)] pylab.hist(A * x1 + b, numpy.array(bins)) nopts = 200 xs = -1.5 + 3.0 / (nopts - 1) * matrix(range(nopts)) pylab.plot(xs, (35.0 / 1.5) * abs(xs), 'g-')
# LS fit of 5th order polynomial # # minimize ||A*x - y ||_2 n = 6 A = matrix([[t**k] for k in range(n)]) xls = +y lapack.gels(+A, xls) xls = xls[:n] # Chebyshev fit of 5th order polynomial # # minimize ||A*x - y ||_inf xinf = variable(n) op(max(abs(A * xinf - y))).solve() xinf = xinf.value if pylab_installed: pylab.figure(1, facecolor='w') pylab.plot(t, y, 'bo', mfc='w', mec='b') nopts = 1000 ts = -1.1 + (1.1 - (-1.1)) / nopts * matrix(list(range(nopts)), tc='d') yls = sum(xls[k] * ts**k for k in range(n)) yinf = sum(xinf[k] * ts**k for k in range(n)) pylab.plot(ts, yls, 'g-', ts, yinf, '--r') pylab.axis([-1.1, 1.1, -0.1, 0.25]) pylab.xlabel('u') pylab.ylabel('p(u)') pylab.title('Polynomial fitting (fig. 6.19)')
# LS fit of 5th order polynomial # # minimize ||A*x - y ||_2 n = 6 A = matrix( [[t**k] for k in range(n)] ) xls = +y lapack.gels(+A,xls) xls = xls[:n] # Chebyshev fit of 5th order polynomial # # minimize ||A*x - y ||_inf xinf = variable(n) op( max(abs(A*xinf - y)) ).solve() xinf = xinf.value if pylab_installed: pylab.figure(1, facecolor='w') pylab.plot(t, y, 'bo', mfc='w', mec='b') nopts = 1000 ts = -1.1 + (1.1 - (-1.1))/nopts * matrix(list(range(nopts)), tc='d') yls = sum( xls[k] * ts**k for k in range(n) ) yinf = sum( xinf[k] * ts**k for k in range(n) ) pylab.plot(ts,yls,'g-', ts, yinf, '--r') pylab.axis([-1.1, 1.1, -0.1, 0.25]) pylab.xlabel('u') pylab.ylabel('p(u)') pylab.title('Polynomial fitting (fig. 6.19)')
c5 = [] # resource capacity m = j + k n = j * k TMU = np.zeros(shape=(m, n), dtype=int) # a totally unimodular matrix of zeros # an m x n matrix representing the constraints 5 (computational resource exceed) and constraints 6 # (each job assigned to at least 1 datacenter) A = matrix(np.array(TMU), tc='i') # b is our value that x can reach given constraints of A. b = uniform(m, 1) # Make x = 0 feasible for barrier. A flow can be allocated 0 time in favor of antoher getting more time. b is always positive. b /= (1.1 * max(abs(b))) # %% """ Centering uses Newton's Centering Method. This part is from the example given by cvxopt library. Our barrier function is simply the update of the x value towards an optimal solution. We are given mu by the tolerance above. If any centering reaches close to mu we stop since that is close to the edge of non-feasible solutions and exterior to any optimal solution. """ def barrier(): # variables kept same from cvxopt example MAXITERS = 100
def get_fapx(tight, fs, l, u, y = None, tol = 1e-10, debug = False ): ''' Returns the piecewise linear approximation fapxi to fi for each fi in fs that is tight at each point in tight[i], as well as at l and u, in 3 formats: slopes/offsets: obey for i,slope_list,offset_list in enumerate(zip(slopes,offsets)): for s,o in zip(slope_list,offset_list): fapxs[i] <= s*x[i] + o fapxs: a list of functions fapxi ms: as cvxopt modeling function (multiplied by -1, because cvxopt minimizes, and doesn't maximize) (only computed if cvxopt.modeling.variable y is given) Also returns lists of slopes and offsets of linear functionals approximating f ''' if y is not None: ms = [] slopes = [] offsets = [] fapxs = [] for i in range(len(l)): # cast to float, since cvxopt breaks if numpy.float64 floats are used f = lambda x: float(fs[i][0](x)) fprime = lambda x: float(fs[i][1](x)) # If there are any points at which the apx should be tight, # make it tight there if tight[i]: if tight[i][0]>l[i]: if y is not None: m = max([-(f(l[i])+\ (f(tight[i][0])-f(l[i]))/(tight[i][0]-l[i])*(y[i]-l[i]))] + [-float(f(z)) - float(fprime(z))*(y[i]-z) for z in tight[i]]) slope = [(f(tight[i][0]) - f(l[i]))/(tight[i][0]-l[i])] + \ [ float(fprime(z)) for z in tight[i]] offset = [f(l[i])+(f(tight[i][0])-f(l[i]))/(tight[i][0]-l[i])*(-l[i])] + \ [float(f(z)) - float(fprime(z))*z for z in tight[i]] else: if y is not None: m = max([-float(f(z)) - float(fprime(z))*(y[i]-z) for z in tight[i]]) slope = [float(fprime(z)) for z in tight[i]] offset = [float(f(z)) - float(fprime(z))*z for z in tight[i]] # check if upper and lower bounds are the same elif (u[i] - l[i] < tol): if y is not None: m = f(l[i]) + 0*y[i] slope = [0] offset = [f(l[i])] # otherwise we only use the line connecting (l,f(l)) with (u,f(u)) else: if y is not None: m = -(f(l[i]) + (f(u[i]) - f(l[i]))/(u[i]-l[i]) * (y[i]-l[i])) slope = [(f(u[i]) - f(l[i]))/(u[i]-l[i])] offset = [f(l[i]) + (f(u[i]) - f(l[i]))/(u[i]-l[i]) * (-l[i])] if y is not None: ms.append(m); slopes.append(slope); offsets.append(offset) def fapxi(xi,slope=slope,offset=offset): fi = [] for s,o in zip(slope,offset): fi.append(s*xi + o) return min(fi) fapxs.append(fapxi) if not y is None: return (slopes,offsets,fapxs) else: return (slopes,offsets,fapxs)
# The norm and penalty approximation problems of section 10.5 (Examples). from cvxopt import normal, setseed from cvxopt.modeling import variable, op, max, sum setseed(0) m, n = 500, 100 A = normal(m, n) b = normal(m) x1 = variable(n) prob1 = op(max(abs(A * x1 + b))) prob1.solve() x2 = variable(n) prob2 = op(sum(abs(A * x2 + b))) prob2.solve() x3 = variable(n) prob3 = op(sum(max(0, abs(A * x3 + b) - 0.75, 2 * abs(A * x3 + b) - 2.25))) prob3.solve() try: import pylab except ImportError: pass else: pylab.subplot(311) pylab.hist(A * x1.value + b, m // 5) pylab.subplot(312) pylab.hist(A * x2.value + b, m // 5)
def get_fapx(tight, fs, l, u, y=None, tol=1e-10, debug=False): ''' Returns the piecewise linear approximation fapxi to fi for each fi in fs that is tight at each point in tight[i], as well as at l and u, in 3 formats: slopes/offsets: obey for i,slope_list,offset_list in enumerate(zip(slopes,offsets)): for s,o in zip(slope_list,offset_list): fapxs[i] <= s*x[i] + o fapxs: a list of functions fapxi ms: as cvxopt modeling function (multiplied by -1, because cvxopt minimizes, and doesn't maximize) (only computed if cvxopt.modeling.variable y is given) Also returns lists of slopes and offsets of linear functionals approximating f ''' if y is not None: ms = [] slopes = [] offsets = [] fapxs = [] for i in range(len(l)): # cast to float, since cvxopt breaks if numpy.float64 floats are used f = lambda x: float(fs[i][0](x)) fprime = lambda x: float(fs[i][1](x)) # If there are any points at which the apx should be tight, # make it tight there if tight[i]: if tight[i][0] > l[i]: if y is not None: m = max([-(f(l[i])+\ (f(tight[i][0])-f(l[i]))/(tight[i][0]-l[i])*(y[i]-l[i]))] + [-float(f(z)) - float(fprime(z))*(y[i]-z) for z in tight[i]]) slope = [(f(tight[i][0]) - f(l[i]))/(tight[i][0]-l[i])] + \ [ float(fprime(z)) for z in tight[i]] offset = [f(l[i])+(f(tight[i][0])-f(l[i]))/(tight[i][0]-l[i])*(-l[i])] + \ [float(f(z)) - float(fprime(z))*z for z in tight[i]] else: if y is not None: m = max([ -float(f(z)) - float(fprime(z)) * (y[i] - z) for z in tight[i] ]) slope = [float(fprime(z)) for z in tight[i]] offset = [float(f(z)) - float(fprime(z)) * z for z in tight[i]] # check if upper and lower bounds are the same elif (u[i] - l[i] < tol): if y is not None: m = f(l[i]) + 0 * y[i] slope = [0] offset = [f(l[i])] # otherwise we only use the line connecting (l,f(l)) with (u,f(u)) else: if y is not None: m = -(f(l[i]) + (f(u[i]) - f(l[i])) / (u[i] - l[i]) * (y[i] - l[i])) slope = [(f(u[i]) - f(l[i])) / (u[i] - l[i])] offset = [f(l[i]) + (f(u[i]) - f(l[i])) / (u[i] - l[i]) * (-l[i])] if y is not None: ms.append(m) slopes.append(slope) offsets.append(offset) def fapxi(xi, slope=slope, offset=offset): fi = [] for s, o in zip(slope, offset): fi.append(s * xi + o) return min(fi) fapxs.append(fapxi) if not y is None: return (slopes, offsets, fapxs) else: return (slopes, offsets, fapxs)
# Figure 6.2, page 297. # Penalty approximation. # # The problem data are not the same as in the book figure. from cvxopt import lapack, solvers, matrix, spdiag, log, div, normal from cvxopt.modeling import variable, op, max, sum #solvers.options['show_progress'] = 0 try: import numpy, pylab except ImportError: pylab_installed = False else: pylab_installed = True m, n = 100, 30 A = normal(m,n) b = normal(m,1) b /= (1.1 * max(abs(b))) # Make x = 0 feasible for log barrier. # l1 approximation # # minimize || A*x + b ||_1 x = variable(n) op(sum(abs(A*x+b))).solve() x1 = x.value if pylab_installed: pylab.figure(1, facecolor='w', figsize=(10,10)) pylab.subplot(411) nbins = 100 bins = [-1.5 + 3.0/(nbins-1)*k for k in range(nbins)]