00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045 #include <PostureTransition.h>
00046 #include <stdio.h>
00047 #include <string.h>
00048 #include <FWMath.h>
00049 #include <assert.h>
00050
00056 PostureTransition::PostureTransition(int numPosture)
00057 {
00058 numPos = numPosture;
00059 defaultMatrixID = 0;
00060 }
00061
00066 int PostureTransition::addMatrix(std::string name, double** matrix, bool thisDefault)
00067 {
00068
00069
00070 TransMatrixList::const_iterator matrixIt;
00071 for (matrixIt = matrixList.begin(); matrixIt != matrixList.end(); matrixIt++)
00072 {
00073 if ((*matrixIt)->name == name )
00074 {
00075 std::string str = "There are multiple matrices with the same name: " + name + " in the configuration file!";
00076 opp_error (str.c_str());
00077 }
00078 }
00079
00080
00081
00082 if ( !isMarkovian(matrix) )
00083 {
00084 std::string str = "Given transition matrix " + name + " is not Markovian!";
00085 opp_error (str.c_str());
00086 }
00087
00088 TransMatrix* mat = new TransMatrix;
00089
00090 mat->name = name;
00091 mat->matrix = new double* [numPos];
00092 for (int i=0;i<numPos;++i)
00093 {
00094 mat->matrix[i] = new double [numPos];
00095 for (int j=0;j<numPos;++j)
00096 mat->matrix[i][j] = matrix[i][j];
00097 }
00098
00099 matrixList.push_back(mat);
00100
00101 if (thisDefault)
00102 defaultMatrixID = matrixList.size()-1;
00103
00104 return 0;
00105 }
00106
00112 int PostureTransition::addSteadyState(std::string name, double* iVector)
00113 {
00114
00115 TransMatrixList::const_iterator matrixIt;
00116 for (matrixIt = matrixList.begin(); matrixIt != matrixList.end(); matrixIt++)
00117 {
00118 if ((*matrixIt)->name == name )
00119 {
00120 std::string str = "There are multiple matrices with the same name: " + name + " in the configuration file!";
00121 opp_error (str.c_str());
00122 }
00123 }
00124
00125
00126 if ( !isMarkovian(iVector) )
00127 {
00128 std::string str = "Given steady state vector " + name + " cannot be true!";
00129 opp_error (str.c_str());
00130 }
00131
00132
00133 double *steady = new double[numPos];
00134 for (int i=0; i < numPos; ++i)
00135 steady[i] = iVector[i];
00136
00137 TransMatrix* mat = new TransMatrix;
00138 mat->name = name;
00139 mat->matrix = extractMatrixFromSteadyState(steady);
00140
00141 matrixList.push_back(mat);
00142
00143 return 0;
00144 }
00145
00150 int PostureTransition::addAreaType(std::string name)
00151 {
00152
00153
00154 AreaTypeList::const_iterator areaIt;
00155 for (areaIt = areaTypeList.begin(); areaIt != areaTypeList.end(); areaIt++)
00156 {
00157 if ((*areaIt)->name == name )
00158 {
00159 std::string str = "There are multiple area types with the same name: " + name + " in the configuration file!";
00160 opp_error (str.c_str());
00161 }
00162 }
00163
00164 AreaType* area = new AreaType;
00165 area->name = name;
00166 areaTypeList.push_back(area);
00167 return areaTypeList.size()-1;
00168 }
00169
00173 bool PostureTransition::setAreaBoundry(int id, Coord lowBound, Coord highBound)
00174 {
00175 AreaBound* bound=new AreaBound;
00176 bound->low = lowBound;
00177 bound->high = highBound;
00178
00179 areaTypeList.at(id)->boundries.push_back(bound);
00180
00181 return true;
00182 }
00183
00188 int PostureTransition::addTimeDomain(std::string name)
00189 {
00190
00191 TimeDomainList::const_iterator timeIt;
00192 for (timeIt = timeDomainList.begin(); timeIt != timeDomainList.end(); timeIt++)
00193 {
00194 if ((*timeIt)->name == name )
00195 {
00196 std::string str = "There are multiple time domains with the same name: " + name + " in the configuration file!";
00197 opp_error (str.c_str());
00198 }
00199 }
00200
00201 TimeDomainType* time = new TimeDomainType;
00202 time->name = name;
00203 timeDomainList.push_back(time);
00204 return timeDomainList.size()-1;
00205 }
00206
00210 bool PostureTransition::setTimeBoundry(int id, simtime_t lowBound, simtime_t highBound)
00211 {
00212 TimeBound* bound=new TimeBound;
00213 bound->low = lowBound;
00214 bound->high = highBound;
00215
00216 timeDomainList.at(id)->boundries.push_back(bound);
00217
00218 return true;
00219 }
00220
00227 bool PostureTransition::addCombination(std::string areaName,std::string timeName,std::string matrixName)
00228 {
00229 int thisID;
00230 CombinationType* comb = new CombinationType;
00231 comb->areaID = -1;
00232 comb->timeID = -1;
00233 comb->matrixID = -1;
00234
00235
00236 thisID = 0;
00237 AreaTypeList::const_iterator areaIt;
00238 for (areaIt = areaTypeList.begin(); areaIt != areaTypeList.end(); areaIt++)
00239 {
00240 if (areaName == (*areaIt)->name )
00241 {
00242 comb->areaID = thisID;
00243 break;
00244 }
00245 ++thisID;
00246 }
00247
00248
00249 if (comb->areaID == -1 && !areaName.empty())
00250 {
00251 std::string str = "Undefined area type name is given in a combinations: " + areaName + ", " + timeName + ", " + matrixName;
00252 opp_error (str.c_str());
00253 }
00254
00255
00256
00257 thisID = 0;
00258 TimeDomainList::const_iterator timeIt;
00259 for (timeIt = timeDomainList.begin(); timeIt != timeDomainList.end(); timeIt++)
00260 {
00261 if (timeName == (*timeIt)->name )
00262 {
00263 comb->timeID = thisID;
00264 break;
00265 }
00266 ++thisID;
00267 }
00268 if (comb->timeID == -1 && !timeName.empty())
00269 {
00270 std::string str = "Undefined time domain name is given in a combinations: " + areaName + ", " + timeName + ", " + matrixName;
00271 opp_error (str.c_str());
00272 }
00273
00274
00275 if (comb->areaID == -1 && comb->timeID == -1)
00276 opp_error ("Both area type and time domain is unspecified in a combination." );
00277
00278
00279 thisID = 0;
00280 TransMatrixList::const_iterator matrixIt;
00281 for (matrixIt = matrixList.begin(); matrixIt != matrixList.end(); matrixIt++)
00282 {
00283 if (matrixName == (*matrixIt)->name )
00284 {
00285 comb->matrixID = thisID;
00286 break;
00287 }
00288 ++thisID;
00289 }
00290 if (comb->matrixID == -1)
00291 opp_error ("Undefined matrix name is given in the combinations" );
00292
00293 combinationList.push_back(comb);
00294
00295 return true;
00296 }
00297
00303 double** PostureTransition::getMatrix(simtime_t iTime, Coord iLocation)
00304 {
00305 int timeID,locationID,matrixID;
00306
00307 timeID = findTimeDomain(iTime);
00308 locationID = findAreaType(iLocation);
00309
00310
00311 matrixID = defaultMatrixID;
00312
00313 CombinationList::const_iterator combIt;
00314 for (combIt = combinationList.begin(); combIt != combinationList.end(); combIt++)
00315 {
00316 if ( (*combIt)->timeID == timeID && (*combIt)->areaID == locationID)
00317 {
00318 matrixID = (*combIt)->matrixID;
00319 break;
00320 }
00321 }
00322
00323 EV << "The corresponding Markov matrix for time" << iTime.dbl() <<" and location " << iLocation.info() << " is: " << matrixList.at(matrixID)->name << endl;
00324
00325 return matrixList.at(matrixID)->matrix;
00326 }
00327
00332 int PostureTransition::findTimeDomain(simtime_t iTime)
00333 {
00334 int timeID=0;
00335 TimeDomainList::const_iterator timeIt;
00336 for (timeIt = timeDomainList.begin(); timeIt != timeDomainList.end(); timeIt++)
00337 {
00338 std::vector<TimeBound*> boundList = (*timeIt)->boundries;
00339
00340 std::vector<TimeBound*>::const_iterator bound;
00341 for (bound = boundList.begin(); bound != boundList.end(); bound++)
00342 {
00343 if ( iTime >= (*bound)->low && iTime < (*bound)->high)
00344 return timeID;
00345 }
00346 ++timeID;
00347 }
00348 EV << "Time domain not found" << endl;
00349 return -1;
00350 }
00351
00356 int PostureTransition::findAreaType(Coord iLocation)
00357 {
00358 int locationID=0;
00359 AreaTypeList::const_iterator areaIt;
00360 for (areaIt = areaTypeList.begin(); areaIt != areaTypeList.end(); areaIt++)
00361 {
00362 std::vector<AreaBound*> boundList = (*areaIt)->boundries;
00363
00364 std::vector<AreaBound*>::const_iterator bound;
00365 for (bound = boundList.begin(); bound != boundList.end(); bound++)
00366 {
00367 if ( iLocation.isInBoundary( (*bound)->low ,(*bound)->high ) )
00368 return locationID;
00369 }
00370 ++locationID;
00371 }
00372 EV << "Area Type not found" << endl;
00373 return -1;
00374 }
00375
00380 bool PostureTransition::isMarkovian(double** matrix)
00381 {
00382 double sumCol;
00383 for (int j=0;j<numPos;++j)
00384 {
00385 sumCol = 0;
00386 for (int i=0;i<numPos;++i)
00387 {
00388 if (matrix[i][j] < 0 || matrix[i][j] > 1)
00389 return false;
00390 sumCol += matrix[i][j];
00391 }
00392
00393 if (!FWMath::close(sumCol , 1.0 ))
00394 return false;
00395 }
00396
00397 return true;
00398 }
00399
00404 bool PostureTransition::isMarkovian(double* vec)
00405 {
00406 double sumCol=0;
00407 for (int i=0;i<numPos;++i)
00408 {
00409 if (vec[i] < 0 || vec[i]> 1)
00410 return false;
00411 sumCol += vec[i];
00412 }
00413
00414 if ( !FWMath::close(sumCol , 1.0 ) )
00415 return false;
00416 else
00417 return true;
00418 }
00419
00423 void PostureTransition::multMatrix(double** mat1, double** mat2,double** res)
00424 {
00425
00426 int i,j,l;
00427 for(i=0; i < numPos; i++)
00428 {
00429 for(j=0; j < numPos ; j++)
00430 {
00431 res[i][j]=0;
00432 for(l=0; l < numPos ; l++)
00433 res[i][j] += mat1[i][l] * mat2[l][j];
00434 }
00435 }
00436
00437 }
00438
00442 void PostureTransition::addMatrix(double** mat1, double** mat2,double** res)
00443 {
00444 int i,j;
00445 for(i=0; i < numPos; i++)
00446 {
00447 for(j=0; j < numPos ; j++)
00448 res[i][j] = mat1[i][j] + mat2[i][j];
00449 }
00450
00451 }
00452
00456 void PostureTransition::subtractMatrix(double** mat1, double** mat2,double** res)
00457 {
00458 int i,j;
00459 for(i=0; i < numPos; i++)
00460 {
00461 for(j=0; j < numPos ; j++)
00462 res[i][j] = mat1[i][j] - mat2[i][j];
00463 }
00464
00465 }
00466
00470 void PostureTransition::multVector(double* vec,double** res)
00471 {
00472 int i,j;
00473 for(i=0; i < numPos; i++)
00474 {
00475 for(j=0; j < numPos ; j++)
00476 res[i][j] = vec[i] * vec[j];
00477 }
00478
00479 }
00480
00485 double** PostureTransition::extractMatrixFromSteadyState(double* vec)
00486 {
00487 int i,j;
00488 double** dafaultMat;
00489
00490
00491 double** mat= new double* [numPos];
00492 double** temp1= new double* [numPos];
00493 double** temp2= new double* [numPos];
00494 double** temp3= new double* [numPos];
00495 double** identity = new double* [numPos];
00496 int** change = new int* [numPos];
00497 for (int i=0;i<numPos;++i)
00498 {
00499 mat[i] = new double [numPos];
00500 temp1[i] = new double [numPos];
00501 temp2[i] = new double [numPos];
00502 temp3[i] = new double [numPos];
00503 identity[i] = new double [numPos];
00504 change[i] = new int [numPos];
00505
00506 }
00507
00508 for(i=0; i < numPos; i++)
00509 for(j=0; j < numPos ; j++)
00510 if (i==j)
00511 identity[i][j] = 1;
00512 else
00513 identity[i][j] = 0;
00514
00515
00516 double* sum= new double [numPos];
00517 int* changeSum= new int [numPos];
00518
00519
00520 dafaultMat = matrixList.at(defaultMatrixID)->matrix;
00521
00522
00523 for (int numTry=0;numTry<400;++numTry)
00524 {
00525 subtractMatrix(identity,dafaultMat,temp1);
00526 multVector(vec,temp2);
00527 multMatrix(temp1,temp2,temp3);
00528 addMatrix(dafaultMat,temp3,mat);
00529
00530
00531 for(i=0; i < numPos; i++)
00532 for(j=0; j < numPos ; j++)
00533 change[i][j] = 1;
00534
00535 for(j=0; j < numPos; j++)
00536 for(i=0; i < numPos ; i++)
00537 {
00538 if ( mat[i][j] < 0 ){
00539 mat[i][j] = 0;
00540 change[i][j]=0;
00541 }
00542 if ( mat[i][j] > 1 ){
00543 mat[i][j] = 1;
00544 change[i][j]=0;
00545 }
00546 }
00547
00548
00549 for(j=0; j < numPos; j++)
00550 {
00551 sum[j] = 0;
00552 changeSum[j]=0;
00553 for(i=0; i < numPos ; i++)
00554 {
00555 sum[j] += mat[i][j];
00556 changeSum[j] += change[i][j];
00557 }
00558 }
00559
00560 for(j=0; j < numPos; j++)
00561 for(i=0; i < numPos ; i++)
00562 {
00563 if (change[i][j] == 1)
00564 mat[i][j] = mat[i][j]+ (1-sum[j])/changeSum[j];
00565 }
00566
00567 dafaultMat = mat;
00568 }
00569
00570 for(j=0; j < numPos; j++)
00571 for(i=0; i < numPos ; i++)
00572 {
00573 if ( mat[i][j] < 0 )
00574 mat[i][j] = 0;
00575 if ( mat[i][j] > 1 )
00576 mat[i][j] = 1;
00577 }
00578
00579
00580 EV << "Generated Markov matrix from the steady state: "<< endl;
00581 for (int k=0;k < numPos; ++k)
00582 {
00583 for (int f=0; f<numPos ;++f)
00584 EV << mat[k][f]<<" ";
00585 EV << endl;
00586 }
00587
00588 for (int i=0;i<numPos;++i)
00589 {
00590 delete temp1[i]; delete temp2[i]; delete temp3[i];
00591 delete identity[i];
00592 delete change[i];
00593 }
00594 delete temp1; delete temp2; delete temp3;
00595 delete identity;
00596 delete change;
00597 delete sum;
00598 delete changeSum;
00599
00600
00601 return mat;
00602 }