def test_optimPCDTX(self): # test for simple problem with known outcome H = np.array([[[1. - 1j, -1.], [-1., 1.]], [[1. - 1j, 1.], [-1., 1.]], [[0.5, 1.j], [1., -1.j]]]) for k in np.arange(3): H[k, :, :] = scipy.dot(H[k, :, :], H[k, :, :].conj().T) noisepower = np.ones(3) rate = 1 linkBandwidth = 1 p0 = 10 m = 2 pS = 5 pMax = 10 obj, solution, status = optimMinPow.optimizePCDTX( H, noisepower, rate, linkBandwidth, pMax, p0, m, pS, 0) answerObj = 13.9204261 answerSol = np.array([0.32342002, 0.24371824, 0.27855287, 0.15430887]) np.testing.assert_almost_equal(obj, answerObj) np.testing.assert_almost_equal(solution, answerSol) for k in np.arange(H.shape[0]): ptx = optimMinPow2x2DTX.ptxOfMu(solution[k], rate, linkBandwidth, noisepower[k], H[k, :, :]) rate_test = solution[k] * np.real( utils.ergMIMOCapacityCDITCSIR(H[k, :, :], ptx)) np.testing.assert_almost_equal(rate_test, rate)
def test_optimPCDTX_trivial(self): # test for simple problem with known outcome H = np.ones([3, 2, 2]) for k in np.arange(3): H[k, :, :] = scipy.dot(H[k, :, :], H[k, :, :].conj().T) noisepower = np.ones(3) rate = 1 linkBandwidth = 1 p0 = 10 m = 2 pS = 5 pMax = 10 obj, solution, status = optimMinPow.optimizePCDTX( H, noisepower, rate, linkBandwidth, pMax, p0, m, pS, 0) answerObj = 17.000000115485285 answerSol = np.array([0.33333334, 0.33333334, 0.33333334, 0.]) np.testing.assert_almost_equal(obj, answerObj) np.testing.assert_almost_equal(solution, answerSol) for k in np.arange(H.shape[0]): ptx = optimMinPow2x2DTX.ptxOfMu(solution[k], rate, linkBandwidth, noisepower[k], H[k, :, :]) rate_test = solution[k] * np.real( utils.ergMIMOCapacityCDITCSIR(H[k, :, :], ptx)) np.testing.assert_almost_equal(rate_test, rate)
def test_optimPCDTXrandomChannel(self): # test for simple problem with known outcome users = 22 n_tx = 2 n_rx = 2 H = np.empty([users, n_tx, n_rx], dtype=complex) # very important to make it complex! for k in np.arange(users): H[k, :, :] = 10e-7 * utils.rayleighChannel(n_tx, n_rx) H[k, :, :] = scipy.dot(H[k, :, :], H[k, :, :].conj().T) noisepower = np.ones(users) * 4e-14 rate = 1.2e7 / users # bps linkBandwidth = 1e7 p0 = 100 m = 2.4 pS = 50 pMax = 40 obj, solution, status = optimMinPow.optimizePCDTX( H, noisepower, rate, linkBandwidth, pMax, p0, m, pS, 0) # Test that all calls were correct and their order. What goes in must come out. for k in np.arange(users): ptx = optimMinPow2x2DTX.ptxOfMu( solution[k], rate, linkBandwidth, noisepower[k], H[k, :, :]) # power as a function of the MIMO link rate_test = solution[k] * np.real( utils.ergMIMOCapacityCDITCSIR( H[k, :, :], ptx / noisepower[k])) * linkBandwidth # bps np.testing.assert_almost_equal(rate_test, rate)
def test_optimPCDTX(self): # test for simple problem with known outcome H = np.array([[[1.-1j,-1.],[-1.,1.]],[[1.-1j,1.],[-1.,1.]],[[0.5,1.j],[1.,-1.j]]]) for k in np.arange(3): H[k,:,:] = scipy.dot(H[k,:,:], H[k,:,:].conj().T) noisepower = np.ones(3) rate = 1 linkBandwidth = 1 p0 = 10 m = 2 pS = 5 pMax = 10 obj, solution, status = optimMinPow.optimizePCDTX(H, noisepower, rate, linkBandwidth, pMax, p0, m, pS, 0) answerObj = 13.9204261 answerSol = np.array([ 0.32342002, 0.24371824, 0.27855287, 0.15430887]) np.testing.assert_almost_equal(obj, answerObj) np.testing.assert_almost_equal(solution, answerSol) for k in np.arange(H.shape[0]): ptx = optimMinPow2x2DTX.ptxOfMu(solution[k], rate, linkBandwidth, noisepower[k], H[k,:,:]) rate_test = solution[k]*np.real(utils.ergMIMOCapacityCDITCSIR(H[k,:,:], ptx)) np.testing.assert_almost_equal(rate_test, rate)
def test_optimPCDTX_trivial(self): # test for simple problem with known outcome H = np.ones([3,2,2]) for k in np.arange(3): H[k,:,:] = scipy.dot(H[k,:,:], H[k,:,:].conj().T) noisepower = np.ones(3) rate = 1 linkBandwidth = 1 p0 = 10 m = 2 pS = 5 pMax = 10 obj, solution, status = optimMinPow.optimizePCDTX(H, noisepower, rate, linkBandwidth, pMax, p0, m, pS, 0) answerObj = 17.000000115485285 answerSol = np.array([ 0.33333334, 0.33333334, 0.33333334, 0. ]) np.testing.assert_almost_equal(obj, answerObj) np.testing.assert_almost_equal(solution, answerSol) for k in np.arange(H.shape[0]): ptx = optimMinPow2x2DTX.ptxOfMu(solution[k], rate, linkBandwidth, noisepower[k], H[k,:,:]) rate_test = solution[k]*np.real(utils.ergMIMOCapacityCDITCSIR(H[k,:,:], ptx)) np.testing.assert_almost_equal(rate_test, rate)
def test_optimPCDTXrandomChannel(self): # test for simple problem with known outcome users = 22 n_tx = 2 n_rx = 2 H = np.empty([users, n_tx, n_rx],dtype=complex) # very important to make it complex! for k in np.arange(users): H[k,:,:] = 10e-7*utils.rayleighChannel(n_tx,n_rx) H[k,:,:] = scipy.dot(H[k,:,:], H[k,:,:].conj().T) noisepower = np.ones(users) * 4e-14 rate = 1.2e7/users # bps linkBandwidth = 1e7 p0 = 100 m = 2.4 pS = 50 pMax = 40 obj, solution, status = optimMinPow.optimizePCDTX(H, noisepower, rate, linkBandwidth, pMax, p0, m, pS, 0) # Test that all calls were correct and their order. What goes in must come out. for k in np.arange(users): ptx = optimMinPow2x2DTX.ptxOfMu(solution[k], rate, linkBandwidth, noisepower[k], H[k,:,:]) # power as a function of the MIMO link rate_test = solution[k]*np.real(utils.ergMIMOCapacityCDITCSIR(H[k,:,:], ptx/noisepower[k]))*linkBandwidth # bps np.testing.assert_almost_equal(rate_test, rate)
def raps(wrld, cell, mobiles, rate, plotting=False): """In the cell, allocate powers and sleep modes to mobiles.""" # need to map algorithm indices to mobile ids (artifact from MATLAB) id_map = dict() for k, mob in enumerate(mobiles): id_map[k] = mob.id_ # Make sure all mobiles are associated with the cell correctly for mob in mobiles: if mob.cell != cell: raise ValueError('Faulty passing of mobiles to RAPS') logger.info( '{0:50} {1:5d}'.format('Mobiles in this cell:', len(mobiles))) # Build SINR arrays users = len(mobiles) N = wrld.PHY.numFreqChunks T = wrld.PHY.numTimeslots noisePower = wrld.wconf.systemNoisePower # EC_Optim contains one MIMO value per mobile (the center chunk effective channel) EC_Optim = np.empty([users, cell.antennas, wrld.mobiles[0].antennas], dtype=complex) # TODO Will we ever have mobiles with different numbers of annteas? # SINR_Quant contains one value for each RB and user SINR_Quant = np.empty([N, T, users]) centerChunkIndex = np.floor(N/2) whichTimeslotIndex = list(cell.sleep_slot_priority).index(0) for idx, mob in enumerate(mobiles): EC_Optim[idx,:,:] = mob.OFDMA_EC[:,:,centerChunkIndex,whichTimeslotIndex] / N # scale this effective channel over all chunks SINR_Quant[:,:,idx] = np.mean(mob.OFDMA_effSINR,0) # SINR for RCG ### Step 1 ### # Optimization call pSupplyOptim, resourceAlloc, status = optimMinPow.optimizePCDTX(EC_Optim, np.ones(EC_Optim.shape[0]), rate, wrld.PHY.systemBandwidth, cell.pMax, mobiles[0].BS.p0, mobiles[0].BS.m, mobiles[0].BS.pS) logger.debug( 'Resource Allocation: ' + str(resourceAlloc)) logger.debug( 'Sleep priority: ' + str(cell.sleep_slot_priority)) logger.info( '{0:50} {1:5.2f} W'.format('Real-valued optimization objective:', pSupplyOptim) ) ## Plot ## if cell.cellid == 12345 and plotting: # center in tier 1 from plotting import channelplotter channelplotter.bar(np.mean(np.mean(EC_Optim,1),1),'Abs mean of MIMO EC Optim', 'sinr_optim.pdf') channelplotter.OFDMAchannel(SINR_Quant, 'SINR Quant', 'sinr_quant.pdf') channelplotter.bar(resourceAlloc,'Resource Share Optim', 'rscshare.pdf') import pdb; pdb.set_trace() ### Step 2 ### # Map real valued solution to OFDMA frame # QUANTMAP resourcesPerTimeslot = quantmap.quantmap(resourceAlloc, N, T) outmap = np.empty([N, T]) # Handle sleep slot alignment here. resourcesPerTimeslot = resourcesPerTimeslot[cell.sleep_slot_priority] # RCG for t in np.arange(T): outmap[:,t],_ = rcg.rcg(SINR_Quant[:,t,:],resourcesPerTimeslot[t,:]) # outmap.shape = (N,T) tells the user index # Given allocation and rate target, we inverse waterfill channels for each user separately on the basis of full SINR # IWF powerlvls = np.empty([N, T, mob.antennas]) powerlvls[:] = np.nan for idx, obj in enumerate(mobiles): # grab user SINR EC_usr = obj.OFDMA_EC[:,:,outmap==idx] # all effective channels assigned to this user noiseIfPower_usr = np.real(EC_usr[0,0,:].repeat(2) * 0 + 1) # TODO remove later #(obj.baseStations[obj.BS].cells[obj.cell].OFDMA_interferencePower + obj.baseStations[obj.BS].cells[obj.cell].OFDMA_noisePower) * np.ones(SINR_user_all[0,0,:,:].shape)[outmap==idx].ravel().repeat(2) # one IF value per resource, so repeat once to match spatial channels # create list of eigVals eigVals = np.real([linalg.eig(EC_usr[:,:,i])[0] for i in np.arange(EC_usr.shape[2])]).ravel() # two eigvals (spatial channels) per resource targetLoad = rate * wrld.PHY.simulationTime # inverse waterfill and fill back to OFDMA position powlvl, waterlvl, cap = iwf.inversewaterfill(eigVals, targetLoad, noiseIfPower_usr, wrld.PHY.systemBandwidth / N, wrld.PHY.simulationTime / T) powerlvls[outmap==idx,:] = powlvl.reshape(EC_usr.shape[2],obj.antennas) ptx = np.array([np.nansum(np.nansum(powerlvls[:,t,:],axis=0),axis=0) for t in np.arange(T)]) logging.debug('Ptx' + str(ptx)) if (ptx > cell.pMax).any(): raise ValueError('Transmission power too high in IWF: '+str(ptx)+ ' W') # Store power levels in cell for next round cell.OFDMA_power[:] = np.swapaxes(np.swapaxes(powerlvls[:],1,2),0,1) cell.OFDMA_power[np.isnan(cell.OFDMA_power)] = 0 # remap to mobile ids outmap_ids = np.copy(outmap) for k,v in id_map.iteritems(): outmap_ids[outmap==k] = v cell.outmap = outmap_ids psupplyPerSlot = mobiles[0].BS.p0 + mobiles[0].BS.m * ptx psupplyPerSlot[np.isnan(psupplyPerSlot)] = mobiles[0].BS.pS pSupplyQuant = np.mean(psupplyPerSlot) logger.info( '{0:50} {1:5.2f} W'.format('Integer-valued optimization objective:', pSupplyQuant)) return pSupplyOptim, pSupplyQuant
def oneIteration(rate, CSI_Optim, SINR_Quant): """Perform one iteration and return the supply powers""" ### Step 1 ### # Optimization call import pdb; pdb.set_trace() pSupplyOptim, resourceAlloc, status = optimMinPow.optimizePCDTX(CSI_Optim, PnoiseIf_Optim, rate, wrld.PHY.systemBandwidth, cell.pMax, bs.p0, bs.m, bs.pS) print '{0:50} {1:5.2f} W'.format('Real-valued optimization objective:', pSupplyOptim) ## Plot ## if plotting: channelplotter.ChannelPlotter().bar(resourceAlloc,'Resource Share Optim', 'rscshare.pdf') channelplotter.ChannelPlotter().bar(PnoiseIf_Optim, 'Interference power Optim', 'ifpower.pdf') channelplotter.ChannelPlotter().bar(((np.abs(np.mean(np.mean(CSI_Optim,1),1)))**2)/(PnoiseIf_Optim), 'SINR Optim', 'OptimSINR.pdf') channelplotter.ChannelPlotter().OFDMAchannel(SINR_Quant, 'SINR Quant', 'sinrquant.pdf') channelplotter.ChannelPlotter().OFDMAchannel(noiseIfPQuant , 'Noise Interference Power Quant', 'noiseifquant.pdf') import pdb; pdb.set_trace() ### Step 2 ### # Map real valued solution to OFDMA frame # QUANTMAP resourcesPerTimeslot = quantmap.quantmap(resourceAlloc, N, T) outmap = np.empty([N, T]) for t in np.arange(T): # RCG outmap[:,t],_ = rcg.rcg(SINR_Quant[:,t,:],resourcesPerTimeslot[t,:]) # outmap.shape = (N,T) tells the user index # Given allocation and rate target, we inverse waterfill channels for each user separately on the basis of full CSI # IWF powerlvls = np.empty([N, T, mob.antennas]) powerlvls[:] = np.nan for idx, obj in enumerate(wrld.consideredMobiles): # WRONG TODO: Only all mobiles of a BS # grab user CSI CSI_usr = obj.OFDMA_SINR[:,:,outmap==idx] # all CSI assigned to this user noiseIfPower_usr = CSI_usr[0,0,:].repeat(2) * 0 + 1 # remove later #(obj.baseStations[obj.BS].cells[obj.cell].OFDMA_interferencePower + obj.baseStations[obj.BS].cells[obj.cell].OFDMA_noisePower) * np.ones(CSI_user_all[0,0,:,:].shape)[outmap==idx].ravel().repeat(2) # one IF value per resource, so repeat once to match spatial channels # create list of eigVals eigVals = np.real([linalg.eig(CSI_usr[:,:,i])[0] for i in np.arange(CSI_usr.shape[2])]).ravel() # two eigvals (spatial channels) per resource targetLoad = rate * wrld.PHY.simulationTime # inverse waterfill and fill back to OFDMA position powlvl, waterlvl, cap = iwf.inversewaterfill(eigVals, targetLoad, noiseIfPower_usr, wrld.PHY.systemBandwidth / N, wrld.PHY.simulationTime / T) powerlvls[outmap==idx,:] = powlvl.reshape(CSI_usr.shape[2],obj.antennas) ptx = np.array([np.nansum(np.nansum(powerlvls[:,t,:],axis=0),axis=0) for t in np.arange(T)]) if ptx.any() > cell.pMax: raise ValueError('Transmission power too high in IWF.') psupplyPerSlot = bs.p0 + bs.m * ptx psupplyPerSlot[np.isnan(psupplyPerSlot)] = bs.pS pSupplyQuant = np.mean(psupplyPerSlot) print '{0:50} {1:5.2f} W'.format('Integer-valued optimization objective:', pSupplyQuant) ### SOTA comparison ### pSupplyBA = np.nan CSI_BA = np.empty([2,2,N,T, users], dtype=complex) CSI_BA[:] = np.nan noiseIfPowerPerResource = np.empty([N,T,users]) noiseIfPowerPerResource[:] = np.nan for idx, obj in enumerate(wrld.consideredMobiles): CSI_BA[:,:,:,:,idx] = obj.baseStations[obj.BS].cells[obj.BS.cells[0]].CSI_OFDMA noiseIfPowerPerResource[:,:,idx] = obj.noiseIfPower * np.ones([N,T]) / N pTxBA = OFDMA_BA(np.ones(users)*rate*wrld.PHY.simulationTime, np.ones([N,T,users])*cell.pMax/N, wrld.PHY.systemBandwidth, wrld.PHY.simulationTime, noiseIfPowerPerResource, CSI_BA) pSupplyBA = scistats.nanmean(bs.p0 + bs.m * pTxBA) print '{0:50} {1:5.2f} W'.format('SOTA objective:', pSupplyBA) print ' ' return pSupplyOptim, pSupplyQuant, pSupplyBA
def raps(wrld, cell, mobiles, rate, plotting=False): """In the cell, allocate powers and sleep modes to mobiles.""" # need to map algorithm indices to mobile ids (artifact from MATLAB) id_map = dict() for k, mob in enumerate(mobiles): id_map[k] = mob.id_ # Make sure all mobiles are associated with the cell correctly for mob in mobiles: if mob.cell != cell: raise ValueError('Faulty passing of mobiles to RAPS') logger.info('{0:50} {1:5d}'.format('Mobiles in this cell:', len(mobiles))) # Build SINR arrays users = len(mobiles) N = wrld.PHY.numFreqChunks T = wrld.PHY.numTimeslots noisePower = wrld.wconf.systemNoisePower # EC_Optim contains one MIMO value per mobile (the center chunk effective channel) EC_Optim = np.empty( [users, cell.antennas, wrld.mobiles[0].antennas], dtype=complex ) # TODO Will we ever have mobiles with different numbers of annteas? # SINR_Quant contains one value for each RB and user SINR_Quant = np.empty([N, T, users]) centerChunkIndex = np.floor(N / 2) whichTimeslotIndex = list(cell.sleep_slot_priority).index(0) for idx, mob in enumerate(mobiles): EC_Optim[ idx, :, :] = mob.OFDMA_EC[:, :, centerChunkIndex, whichTimeslotIndex] / N # scale this effective channel over all chunks SINR_Quant[:, :, idx] = np.mean(mob.OFDMA_effSINR, 0) # SINR for RCG ### Step 1 ### # Optimization call pSupplyOptim, resourceAlloc, status = optimMinPow.optimizePCDTX( EC_Optim, np.ones(EC_Optim.shape[0]), rate, wrld.PHY.systemBandwidth, cell.pMax, mobiles[0].BS.p0, mobiles[0].BS.m, mobiles[0].BS.pS) logger.debug('Resource Allocation: ' + str(resourceAlloc)) logger.debug('Sleep priority: ' + str(cell.sleep_slot_priority)) logger.info('{0:50} {1:5.2f} W'.format( 'Real-valued optimization objective:', pSupplyOptim)) ## Plot ## if cell.cellid == 12345 and plotting: # center in tier 1 from plotting import channelplotter channelplotter.bar(np.mean(np.mean(EC_Optim, 1), 1), 'Abs mean of MIMO EC Optim', 'sinr_optim.pdf') channelplotter.OFDMAchannel(SINR_Quant, 'SINR Quant', 'sinr_quant.pdf') channelplotter.bar(resourceAlloc, 'Resource Share Optim', 'rscshare.pdf') import pdb pdb.set_trace() ### Step 2 ### # Map real valued solution to OFDMA frame # QUANTMAP resourcesPerTimeslot = quantmap.quantmap(resourceAlloc, N, T) outmap = np.empty([N, T]) # Handle sleep slot alignment here. resourcesPerTimeslot = resourcesPerTimeslot[cell.sleep_slot_priority] # RCG for t in np.arange(T): outmap[:, t], _ = rcg.rcg(SINR_Quant[:, t, :], resourcesPerTimeslot[ t, :]) # outmap.shape = (N,T) tells the user index # Given allocation and rate target, we inverse waterfill channels for each user separately on the basis of full SINR # IWF powerlvls = np.empty([N, T, mob.antennas]) powerlvls[:] = np.nan for idx, obj in enumerate(mobiles): # grab user SINR EC_usr = obj.OFDMA_EC[:, :, outmap == idx] # all effective channels assigned to this user noiseIfPower_usr = np.real( EC_usr[0, 0, :].repeat(2) * 0 + 1 ) # TODO remove later #(obj.baseStations[obj.BS].cells[obj.cell].OFDMA_interferencePower + obj.baseStations[obj.BS].cells[obj.cell].OFDMA_noisePower) * np.ones(SINR_user_all[0,0,:,:].shape)[outmap==idx].ravel().repeat(2) # one IF value per resource, so repeat once to match spatial channels # create list of eigVals eigVals = np.real([ linalg.eig(EC_usr[:, :, i])[0] for i in np.arange(EC_usr.shape[2]) ]).ravel() # two eigvals (spatial channels) per resource targetLoad = rate * wrld.PHY.simulationTime # inverse waterfill and fill back to OFDMA position powlvl, waterlvl, cap = iwf.inversewaterfill( eigVals, targetLoad, noiseIfPower_usr, wrld.PHY.systemBandwidth / N, wrld.PHY.simulationTime / T) powerlvls[outmap == idx, :] = powlvl.reshape(EC_usr.shape[2], obj.antennas) ptx = np.array([ np.nansum(np.nansum(powerlvls[:, t, :], axis=0), axis=0) for t in np.arange(T) ]) logging.debug('Ptx' + str(ptx)) if (ptx > cell.pMax).any(): raise ValueError('Transmission power too high in IWF: ' + str(ptx) + ' W') # Store power levels in cell for next round cell.OFDMA_power[:] = np.swapaxes(np.swapaxes(powerlvls[:], 1, 2), 0, 1) cell.OFDMA_power[np.isnan(cell.OFDMA_power)] = 0 # remap to mobile ids outmap_ids = np.copy(outmap) for k, v in id_map.iteritems(): outmap_ids[outmap == k] = v cell.outmap = outmap_ids psupplyPerSlot = mobiles[0].BS.p0 + mobiles[0].BS.m * ptx psupplyPerSlot[np.isnan(psupplyPerSlot)] = mobiles[0].BS.pS pSupplyQuant = np.mean(psupplyPerSlot) logger.info('{0:50} {1:5.2f} W'.format( 'Integer-valued optimization objective:', pSupplyQuant)) return pSupplyOptim, pSupplyQuant
def oneIteration(rate, CSI_Optim, SINR_Quant): """Perform one iteration and return the supply powers""" ### Step 1 ### # Optimization call import pdb pdb.set_trace() pSupplyOptim, resourceAlloc, status = optimMinPow.optimizePCDTX( CSI_Optim, PnoiseIf_Optim, rate, wrld.PHY.systemBandwidth, cell.pMax, bs.p0, bs.m, bs.pS) print '{0:50} {1:5.2f} W'.format('Real-valued optimization objective:', pSupplyOptim) ## Plot ## if plotting: channelplotter.ChannelPlotter().bar(resourceAlloc, 'Resource Share Optim', 'rscshare.pdf') channelplotter.ChannelPlotter().bar(PnoiseIf_Optim, 'Interference power Optim', 'ifpower.pdf') channelplotter.ChannelPlotter().bar( ((np.abs(np.mean(np.mean(CSI_Optim, 1), 1)))**2) / (PnoiseIf_Optim), 'SINR Optim', 'OptimSINR.pdf') channelplotter.ChannelPlotter().OFDMAchannel(SINR_Quant, 'SINR Quant', 'sinrquant.pdf') channelplotter.ChannelPlotter().OFDMAchannel( noiseIfPQuant, 'Noise Interference Power Quant', 'noiseifquant.pdf') import pdb pdb.set_trace() ### Step 2 ### # Map real valued solution to OFDMA frame # QUANTMAP resourcesPerTimeslot = quantmap.quantmap(resourceAlloc, N, T) outmap = np.empty([N, T]) for t in np.arange(T): # RCG outmap[:, t], _ = rcg.rcg(SINR_Quant[:, t, :], resourcesPerTimeslot[ t, :]) # outmap.shape = (N,T) tells the user index # Given allocation and rate target, we inverse waterfill channels for each user separately on the basis of full CSI # IWF powerlvls = np.empty([N, T, mob.antennas]) powerlvls[:] = np.nan for idx, obj in enumerate( wrld.consideredMobiles): # WRONG TODO: Only all mobiles of a BS # grab user CSI CSI_usr = obj.OFDMA_SINR[:, :, outmap == idx] # all CSI assigned to this user noiseIfPower_usr = CSI_usr[0, 0, :].repeat( 2 ) * 0 + 1 # remove later #(obj.baseStations[obj.BS].cells[obj.cell].OFDMA_interferencePower + obj.baseStations[obj.BS].cells[obj.cell].OFDMA_noisePower) * np.ones(CSI_user_all[0,0,:,:].shape)[outmap==idx].ravel().repeat(2) # one IF value per resource, so repeat once to match spatial channels # create list of eigVals eigVals = np.real([ linalg.eig(CSI_usr[:, :, i])[0] for i in np.arange(CSI_usr.shape[2]) ]).ravel() # two eigvals (spatial channels) per resource targetLoad = rate * wrld.PHY.simulationTime # inverse waterfill and fill back to OFDMA position powlvl, waterlvl, cap = iwf.inversewaterfill( eigVals, targetLoad, noiseIfPower_usr, wrld.PHY.systemBandwidth / N, wrld.PHY.simulationTime / T) powerlvls[outmap == idx, :] = powlvl.reshape(CSI_usr.shape[2], obj.antennas) ptx = np.array([ np.nansum(np.nansum(powerlvls[:, t, :], axis=0), axis=0) for t in np.arange(T) ]) if ptx.any() > cell.pMax: raise ValueError('Transmission power too high in IWF.') psupplyPerSlot = bs.p0 + bs.m * ptx psupplyPerSlot[np.isnan(psupplyPerSlot)] = bs.pS pSupplyQuant = np.mean(psupplyPerSlot) print '{0:50} {1:5.2f} W'.format('Integer-valued optimization objective:', pSupplyQuant) ### SOTA comparison ### pSupplyBA = np.nan CSI_BA = np.empty([2, 2, N, T, users], dtype=complex) CSI_BA[:] = np.nan noiseIfPowerPerResource = np.empty([N, T, users]) noiseIfPowerPerResource[:] = np.nan for idx, obj in enumerate(wrld.consideredMobiles): CSI_BA[:, :, :, :, idx] = obj.baseStations[obj.BS].cells[obj.BS.cells[0]].CSI_OFDMA noiseIfPowerPerResource[:, :, idx] = obj.noiseIfPower * np.ones([N, T]) / N pTxBA = OFDMA_BA( np.ones(users) * rate * wrld.PHY.simulationTime, np.ones([N, T, users]) * cell.pMax / N, wrld.PHY.systemBandwidth, wrld.PHY.simulationTime, noiseIfPowerPerResource, CSI_BA) pSupplyBA = scistats.nanmean(bs.p0 + bs.m * pTxBA) print '{0:50} {1:5.2f} W'.format('SOTA objective:', pSupplyBA) print ' ' return pSupplyOptim, pSupplyQuant, pSupplyBA