def SDPTDoALocate(self, RN1, RN2, TDoA, TDoAStd): """ Apply SDP approximation and localization """ RN1 = cvxm.matrix(RN1) RN2 = cvxm.matrix(RN2) TDoA = cvxm.matrix(TDoA) c = 3e08 RDoA = c*TDoA RDoAStd=cvxm.matrix(c*TDoAStd) mtdoa,ntdoa=cvxm.size(RN1) Im = cvxm.eye(mtdoa) Y=cvxm.optvar('Y',mtdoa+1,mtdoa+1) t=cvxm.optvar('t',ntdoa,1) prob=cvxm.problem(cvxm.minimize(cvxm.norm2(t))) prob.constr.append(Y>=0) prob.constr.append(Y[mtdoa,mtdoa]==1) for i in range(ntdoa): X0=cvxm.matrix([[Im, -cvxm.transpose(RN1[:,i])],[-RN1[:,i], cvxm.transpose(RN1[:,i])*RN1[:,i]]]) X1=cvxm.matrix([[Im, -cvxm.transpose(RN2[:,i])],[-RN2[:,i], cvxm.transpose(RN2[:,i])*RN2[:,i]]]) prob.constr.append(-RDoAStd[i,0]*t[i]<cvxm.trace(X0*Y)+cvxm.trace(X1*Y)-RDoA[i,0]**2) prob.constr.append(RDoAStd[i,0]*t[i]>cvxm.trace(X0*Y)+cvxm.trace(X1*Y)-RDoA[i,0]**2) prob.solve() Pval=Y.value X_cvx=Pval[:2,-1] return X_cvx
def SDPRSSLocate(self, RN, PL0, d0, RSS, RSSnp, RSSStd, Rest): RoA=self.getRange(RN, PL0, d0, RSS, RSSnp, RSSStd, Rest) RN=cvxm.matrix(RN) RSS=cvxm.matrix(RSS) RSSnp=cvxm.matrix(RSSnp) RSSStd=cvxm.matrix(RSSStd) PL0=cvxm.matrix(PL0) RoA=cvxm.matrix(RoA) mrss,nrss=cvxm.size(RN) Si = array([(1/d0**2)*10**((RSS[0,0]-PL0[0,0])/(5.0*RSSnp[0,0])),(1/d0**2)*10**((RSS[1,0]-PL0[1,0])/(5.0*RSSnp[1,0])),(1/d0**2)*10**((RSS[2,0]-PL0[2,0])/(5.0*RSSnp[2,0])),(1/d0**2)*10**((RSS[3,0]-PL0[3,0])/(5.0*RSSnp[3,0]))]) #Si = array([(1/d0**2)*10**(-(RSS[0,0]-PL0[0,0])/(5.0*RSSnp[0,0])),(1/d0**2)*10**(-(RSS[0,1]-PL0[1,0])/(5.0*RSSnp[0,1])),(1/d0**2)*10**(-(RSS[0,2]-PL0[2,0])/(5.0*RSSnp[0,2])),(1/d0**2)*10**(-(RSS[0,3]-PL0[3,0])/(5.0*RSSnp[0,3]))]) Im = cvxm.eye(mrss) Y=cvxm.optvar('Y',mrss+1,mrss+1) t=cvxm.optvar('t',nrss,1) prob=cvxm.problem(cvxm.minimize(cvxm.norm2(t))) prob.constr.append(Y>=0) prob.constr.append(Y[mrss,mrss]==1) for i in range(nrss): X0=cvxm.matrix([[Im, -cvxm.transpose(RN[:,i])],[-RN[:,i], cvxm.transpose(RN[:,i])*RN[:,i]]]) prob.constr.append(-RSSStd[i,0]*t[i]<Si[i]*cvxm.trace(X0*Y)-1) prob.constr.append(RSSStd[i,0]*t[i]>Si[i]*cvxm.trace(X0*Y)-1) prob.solve() Pval=Y.value X_cvx=Pval[:2,-1] return X_cvx
def SDPToALocate(self, RN, ToA, ToAStd): """ Apply SDP approximation and localization """ RN = cvxm.matrix(RN) ToA = cvxm.matrix(ToA) c = 3e08 # Speed of light RoA = c*ToA RoAStd = c*ToAStd RoAStd = cvxm.matrix(RoAStd) mtoa,ntoa=cvxm.size(RN) Im = cvxm.eye(mtoa) Y=cvxm.optvar('Y',mtoa+1,mtoa+1) t=cvxm.optvar('t',ntoa,1) prob=cvxm.problem(cvxm.minimize(cvxm.norm2(t))) prob.constr.append(Y>=0) prob.constr.append(Y[mtoa,mtoa]==1) for i in range(ntoa): X0=cvxm.matrix([[Im, -cvxm.transpose(RN[:,i])],[-RN[:,i], cvxm.transpose(RN[:,i])*RN[:,i]]]) prob.constr.append(-t[i]<(cvxm.trace(X0*Y)-RoA[i]**2)*(1/RoAStd[i])) prob.constr.append(t[i]>(cvxm.trace(X0*Y)-RoA[i]**2)*(1/RoAStd[i])) prob.solve() Pval=Y.value X_cvx=Pval[:2,-1] return X_cvx
def get_energy_per_quanto_state_all(self, baseFileName, convexOpt=False): """This function evaluates the .pwr file and calculates the individual power consumption per state for every node. It then sets the variable statePower on every node to a dictionary, where the keys are the string representation of the state, and the value is the average power consumption for that state. This function expects a very specific .pwr file, where one line starts with "#states:". This line encodes all the states that are considered by quanto. """ for n in self.nodes: f = open("%s.%s.log.pwr"%(baseFileName, n.ip), "r") X = [] Y = [] W = [] totalTime = 0 totalEnergy = 0 states = [] maxEntries = 0 for line in f: l = line.strip().split() if len(l) > 0 and l[0] == "#states:": # this line encodes the names of all the states. states = l[1:] continue if len(states) == 0 or len(l) != len(states)+3: # +2 comes from the icount and time field continue #time is in uS, convert it to seconds time = float(l[-3])/1e6 icount = int(l[-2]) occurences = int(l[-1]) # cut away the time and icount values l = l[0:-3] activeStates = [] for s in l: if s == '-': s = '0' #continue activeStates.append(int(s)) # add the constant power state activeStates.append(1) if len(activeStates) > maxEntries: maxEntries = len(activeStates) if time <= 0 or icount <= 0: # FIXME: this is a wrong line at the end of the quanto files. I # don't know why this happens!!! continue E = n.get_power(icount, time) if E == -1: raise CalibrationError, "Node with IP %s is not calibrated! \ Did you forget to load the calibration file?"%(n.ip,) if E < 0: raise CalibrationError, "Node with IP %s returned a \ negative Energy value %f for icount %d, time %f!"%(n.ip, E, icount, time) continue X.append(activeStates) Y.append(E) W.append(numpy.sqrt(E*time)) totalTime += time totalEnergy += E*time # filter out the incomplete datasets Xnew = [] Ynew = [] Wnew = [] for i in range(len(Y)): if len(X[i]) == maxEntries: Xnew.append(X[i]) Ynew.append(Y[i]) Wnew.append(W[i]) X = numpy.matrix(Xnew) Y = numpy.matrix(Ynew) W = numpy.matrix(numpy.diag(Wnew)) # filter states with all 0's states.append('const') deletedLines = 0 deletedStates = [] alwaysOnStates = [] # iterate through all the states, except the 'const' state for i in range(len(states)-1): correctedI = i - deletedLines if numpy.sum(X.T[correctedI]) == 0: deletedStates.append(states[correctedI]) X = numpy.delete(X, numpy.s_[correctedI:correctedI+1], axis=1) states = numpy.delete(states, correctedI) deletedLines += 1 elif numpy.sum(X.T[correctedI]) == len(X): # this state is always active. W have to remove them and # put them into the "const" category! alwaysOnStates.append(states[correctedI]) X = numpy.delete(X, numpy.s_[correctedI:correctedI+1], axis=1) states = numpy.delete(states, correctedI) deletedLines += 1 # search for linear dependent lines #for i in range(len(X)): # #print X[i] # for j in range(i+1, len(X)): # #if numpy.sum(X[i]) == numpy.sum(X[j]): # # print X[i], X[j] # equal = True # for m in range(X[i].shape[1]): # if X[i,m] != X[j,m]: # equal = False # break # if equal: # print X[i], X[j] # maxEntries includes the const state, which is not in the states # variable yet #states = states[:maxEntries - 1] #xtwx = X.T*X #for i in range(len(xtwx)): # print xtwx[i] #print states #(x, resids, rank, s) = numpy.linalg.lstsq(W*X, W*Y.T) #(x, resids, rank, s) = numpy.linalg.lstsq(X, Y.T) if cvxAvailable and convexOpt: A = cvxmod.matrix(W*X) b = cvxmod.matrix(W*Y.T) x = cvxmod.optvar('x', cvxmod.size(A)[1]) print A print b p = cvxmod.problem(cvxmod.minimize(norm2(A*x - b)), [x >= 0]) #p.constr.append(x |In| probsimp(5)) p.solve() print "Optimal problem value is %.4f." % p.value cvxmod.printval(x) x = x.value else: try: x = numpy.linalg.inv(X.T*W*X)*X.T*W*Y.T except numpy.linalg.LinAlgError, e: sys.stderr.write("State Matrix X for node with IP %s is singular. We did not \ collect enough energy and state information. Please run the application for \ longer!\n"%(n.ip,)) sys.stderr.write(repr(e)) sys.stderr.write("\n") sys.stderr.flush() n.statePower = {} n.alwaysOffStates = [] n.alwaysOnStates = [] continue n.statePower = {} for i in range(len(states)): # the entries in x are matrices. convert them back into a # number n.statePower[states[i]] = float(x[i]) n.alwaysOffStates = deletedStates n.alwaysOnStates = alwaysOnStates n.averagePower = totalEnergy / totalTime