User Manual, Developers Guide and API Documentation

TreeBasedGrouper.cpp

Go to the documentation of this file.
00001 /*******************************************************************************
00002  * This file is part of openWNS (open Wireless Network Simulator)
00003  * _____________________________________________________________________________
00004  *
00005  * Copyright (C) 2004-2009
00006  * Chair of Communication Networks (ComNets)
00007  * Kopernikusstr. 5, D-52074 Aachen, Germany
00008  * phone: ++49-241-80-27910,
00009  * fax: ++49-241-80-22242
00010  * email: info@openwns.org
00011  * www: http://www.openwns.org
00012  * _____________________________________________________________________________
00013  *
00014  * openWNS is free software; you can redistribute it and/or modify it under the
00015  * terms of the GNU Lesser General Public License version 2 as published by the
00016  * Free Software Foundation;
00017  *
00018  * openWNS is distributed in the hope that it will be useful, but WITHOUT ANY
00019  * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR
00020  * A PARTICULAR PURPOSE.  See the GNU Lesser General Public License for more
00021  * details.
00022  *
00023  * You should have received a copy of the GNU Lesser General Public License
00024  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
00025  *
00026  ******************************************************************************/
00027 
00028 #include <WNS/scheduler/grouper/TreeBasedGrouper.hpp>
00029 
00030 #include <WNS/pyconfig/View.hpp>
00031 #include <WNS/StaticFactory.hpp>
00032 #include <WNS/scheduler/SchedulerTypes.hpp>
00033 
00034 #include <list>
00035 #include <math.h>
00036 #include <algorithm>
00037 
00038 using namespace wns::scheduler;
00039 using namespace wns::scheduler::grouper;
00040 
00041 TreeBasedGrouper::TreeBasedGrouper(const wns::pyconfig::View& config)
00042     : SpatialGrouper(config)
00043 {
00044 }
00045 
00046 
00047 std::map<UserID, wns::CandI>
00048 TreeBasedGrouper::getCandIsForGroup(const UserSet group, ModeType mode)
00049 {
00050     std::map<UserID, wns::CandI> candis;
00051     candis.clear();
00052 
00053     switch(mode) {
00054     case tx:
00055     {
00056         if(beamforming){
00057 
00058             std::map<wns::node::Interface*, wns::Power> userNoiseIInterMap;
00059             userNoiseIInterMap.clear();
00060 
00061             for (UserSet::const_iterator iter = group.begin();
00062                  iter != group.end(); ++iter) {
00063                 UserID user = *iter;
00064 
00065                 userNoiseIInterMap[user.getNode()] = 
00066                     colleagues.registry->estimateTxSINRAt(user).interference;
00067             }
00068 
00069             candis = convertMap(friends.ofdmaProvider->calculateCandIsTx(userNoiseIInterMap, x_friendliness, txPower));
00070         }
00071         else{
00072             assure(group.size() == 1, "We don't do beamforming, so only one-user groups are supported");
00073             UserID user = *group.begin();
00074             wns::scheduler::ChannelQualityOnOneSubChannel cqi = 
00075                 colleagues.registry->estimateTxSINRAt(user);
00076             candis[user] = wns::CandI(cqi.carrier, cqi.interference);
00077 
00078         }
00079         MESSAGE_BEGIN(VERBOSE, logger, m, colleagues.registry->getNameForUser(colleagues.registry->getMyUserID()));
00080 
00081         for (std::map<UserID, wns::CandI>::const_iterator iter = candis.begin();
00082              iter != candis.end(); ++iter)
00083             m << " Selecting TX grouping for "
00084               << colleagues.registry->getNameForUser(iter->first)
00085               << "\nAssumed TxPower: " << txPower
00086               << "\nEstimated Carrier: " <<  iter->second.C
00087               << "\nEstimated Interference: " << iter->second.I << "\n"
00088               << "\nEstimated SDMA intra-cell interference: " << iter->second.sdma.iIntra << "\n";
00089         MESSAGE_END();
00090         break;
00091     }
00092     case rx:
00093     {
00094         if (beamforming){
00095             std::vector<wns::node::Interface*> combination;
00096             combination.clear();
00097             wns::Power meanBsInterference = wns::Power::from_mW(0.0);
00098 
00099             for (UserSet::const_iterator user = group.begin();
00100                  user != group.end(); ++user) {
00101                 combination.push_back(user->getNode());
00102                 meanBsInterference += colleagues.registry->estimateRxSINROf(*user).interference;
00103             }
00104             assure(combination.size() == group.size(), "we estimate SINRs for a different set of users than we were asked to do");
00105             meanBsInterference /= static_cast<unsigned long int>(combination.size());
00106 
00107             candis = convertMap(friends.ofdmaProvider->calculateCandIsRx(combination, meanBsInterference));
00108         }
00109         else{ // no beamforming
00110 
00111             assure(group.size() == 1, "We don't do beamforming, so only one-user groups are supported");
00112             UserID user = *group.begin();
00113             wns::scheduler::ChannelQualityOnOneSubChannel cqi = 
00114                 colleagues.registry->estimateRxSINROf(user);
00115             candis[user] = wns::CandI(cqi.carrier, cqi.interference);
00116         }
00117 
00118         MESSAGE_BEGIN(VERBOSE, logger, m, colleagues.registry->getNameForUser(colleagues.registry->getMyUserID()));
00119         for (std::map<UserID, wns::CandI>::const_iterator iter = candis.begin();
00120              iter != candis.end(); ++iter)
00121             m << " Selecting RX grouping for "
00122               << colleagues.registry->getNameForUser(iter->first)
00123               << "\nEstimated Carrier: " <<  iter->second.C
00124               << "\nEstimated Interference: " << iter->second.I << "\n";
00125         MESSAGE_END();
00126 
00127         break;
00128     }
00129     default:
00130         assure(0, "Wrong mode, can  either be RX or TX");
00131     }
00132 
00133     return candis;
00134 }
00135 
00136 
00137 float
00138 TreeBasedGrouper::getTPfromTreeLevelByMode(const TreeLevel level, ModeType mode)
00139 {
00140     float throughput = 0.0;
00141 
00142     // a tree level consists of a number of UserSets
00143     for (TreeLevel::const_iterator iter = level.begin();
00144          iter != level.end(); ++iter)
00145     {
00146         UserSet group = *iter;
00147         std::map<UserID, wns::CandI> candis = getCandIsForGroup(group, mode);
00148 
00149         for (std::map<UserID, wns::CandI>::const_iterator iter2 = candis.begin();
00150              iter2 != candis.end(); ++iter2) {
00151             wns::Ratio sinr(iter2->second.C / iter2->second.I);
00152             //float dataRate = colleagues.registry->getPhyModeForSIR( iter2->second.C / iter2->second.I ).second;
00153             if (colleagues.phyModeMapper->sinrIsAboveLimit(sinr)) {
00154                 double tp = colleagues.phyModeMapper->getBestPhyMode(sinr)->getDataRate();
00155                 throughput += tp;
00156             } else // user without service, we don't allow this
00157                 return 0.0;
00158         }
00159     }
00160 
00161     return throughput;
00162 }
00163 
00164 Grouping
00165 TreeBasedGrouper::convertTreeLevelToGrouping(TreeLevel level, ModeType mode)
00166 {
00167     Grouping grouping;
00168     int groupCount = 0;
00169 
00170 
00171     // for all user groups in that level
00172     for (TreeLevel::const_iterator iter = level.begin();
00173          iter != level.end(); ++iter) {
00174         UserSet users = *iter;
00175         groupCount++;
00176 
00177         std::vector<wns::node::Interface*> usersInGroup;
00178         usersInGroup.clear();
00179 
00180         // calculate the pattern for every user in the group:
00181         for (UserSet::const_iterator iter2 = users.begin();
00182              iter2 != users.end(); ++iter2)
00183             usersInGroup.push_back(iter2->getNode());
00184 
00186         // for every user generate a pattern that has the other group members as
00187         // undesired interferers
00188         for (unsigned int d = 0; d < usersInGroup.size(); ++d) {
00189             std::vector<wns::node::Interface*> undesireds;
00190             undesireds.clear();
00191             for (unsigned int u = 0; u < usersInGroup.size(); ++u)
00192                 if (d != u)
00193                     undesireds.push_back(usersInGroup[u]);
00194             // calculate users pattern with his co-scheduled users as undesireds
00195             if(mode == tx){
00196                 grouping.patterns[UserID(usersInGroup[d])] = friends.ofdmaProvider->
00197                     calculateAndSetBeam(usersInGroup[d], undesireds,  x_friendliness);
00198             }
00199             else{
00200                 // according to the estimation of C and I
00201                 // values in getCandIsForGroup, the mean
00202                 // interference level of the SSs is taken into
00203                 // account
00204                 wns::Power meanBsInterference = wns::Power::from_mW(0.0);
00205                 for (UserSet::const_iterator user = users.begin();
00206                      user != users.end(); ++user) {
00207                     meanBsInterference += colleagues.registry->estimateRxSINROf(*user).interference;
00208                 }
00209                 meanBsInterference /= static_cast<unsigned long int>(users.size());
00210 
00211                 grouping.patterns[UserID(usersInGroup[d])] = friends.ofdmaProvider->
00212                     calculateAndSetBeam(usersInGroup[d], undesireds, meanBsInterference);
00213 //              grouping.patterns[usersInGroup[d]] = friends.ofdmaProvider->
00214 //                          calculateAndSetBeam(usersInGroup[d], undesireds,
00215 //                          colleagues.registry->estimateRxSINROf(usersInGroup[d])->interference;
00216             }
00217 
00218             assure(grouping.patterns[UserID(usersInGroup[d])] !=
00219                    wns::service::phy::ofdma::PatternPtr(), "Invalid pattern returned");
00220         }
00221         // calculate the SINR values for every user in the group
00222         Group newGroup = getCandIsForGroup(users, mode);
00223         // save it in grouping
00224         grouping.groups.push_back(newGroup);
00225         // and update the group look-up-table
00226         for (std::vector<wns::node::Interface*>::const_iterator iter2 = usersInGroup.begin();
00227              iter2 != usersInGroup.end();
00228              ++iter2)
00229             grouping.userGroupNumber[UserID(*iter2)] = groupCount;
00230     } // for all user groups in level
00231     return grouping;
00232 }
00233 
00234 
00235 
00236 Grouping
00237 TreeBasedGrouper::getTxGrouping(const UserSet activeUsers, int maxBeams) {
00238     assure(colleagues.registry, "Registry not set");
00239     assure(friends.ofdmaProvider, "OFDMAprovider not set");
00240 
00241     return treeAlgorithm(activeUsers, maxBeams, tx);
00242 }
00243 
00244 Grouping
00245 TreeBasedGrouper:: getRxGrouping(const UserSet activeUsers, int maxBeams) {
00246     assure(colleagues.registry, "Registry not set");
00247     assure(friends.ofdmaProvider, "OFDMAprovider not set");
00248 
00249     return treeAlgorithm(activeUsers, maxBeams, rx);
00250 }
00251 
00252 
00253 
00254 

Generated on Sat May 26 03:31:49 2012 for openWNS by  doxygen 1.5.5