Main Page   Namespace List   Compound List   File List   Compound Members   File Members  

copy-ocsBitString.cc

Go to the documentation of this file.
00001 // $Id: ocsBitString.cc,v 1.15 2001/08/30 18:05:34 zweck Exp $
00002 
00003 //###################################################################
00004 //
00005 //           Optical Communication Systems Simulator
00006 //
00007 //       Copyright (2000):
00008 //       Optical Fiber Communications Laboratory (OFCL)
00009 //       Computer Science & Electrical Engineering Department (CSEE)
00010 //       University of Maryland Baltimore County (UMBC)
00011 //
00012 //###################################################################
00013 
00014 // ## Written by John Zweck, Oct 12, 2000
00015 // ## by adapting and extending code written by Ivan Lima
00016 
00017 
00018 #include "ocsBitString.hh"
00019 
00020 #include <strstream>
00021 
00022 extern ofstream LogFile;
00023 
00024 // ###########################################
00025 
00026 BitString::BitString(ifstream * InFile, RanNumGen *RNG2 )
00027 {
00028 
00029   // Written by John Zweck.
00030   // Substantially rewritten on Feb 17th 2001 by JZ
00031 
00032   // IF YOU MODIFY THIS CONSTRUCTOR YOU MAY ALSO NEED TO MODIFY
00033   // BitString::BitString(BitString & oBitString1) 
00034   // BitString & BitString::operator=(BitString & RHS_BitString)
00035   //BitString(BitString & BitString1,BitString & BitString2,RanNumGen *RNG3);
00036   // It is assumed that the InFile has already been opened
00037   // by the OptSignal constructor which  calls this constructor
00038 
00039 DebugLevel = ReadInt("DebugLevel"," ",0,-1,LOWER_ONLY,InFile);
00040 
00041 RNG = RNG2;
00042 
00043 NumChannels = ReadInt("NumChannels"," ",0,-1,LOWER_ONLY,InFile);
00044 StringLength = ReadInt("StringLength"," ",1,-1,LOWER_ONLY,InFile);
00045 
00046 TypeBitString = typeBitString(ReadInt("TypeBitString"," ",0,6,
00047                                        LOWER_AND_UPPER,InFile));
00048 
00049 BitStringArray  = new int[StringLength*NumChannels];
00050 
00051 if(!BitStringArray)
00052    {
00053      cerr << "Malloc error in BitString::BitString" << endl
00054           << "ABORTING NOW!!" << endl;
00055      exit(1);
00056 
00057    }
00058 
00059 
00060 if(DebugLevel >= 1)
00061    {
00062      LogFile << "TypeBitString = " << WriteTypeBitString() << endl;
00063    }
00064 
00065 if(DebugLevel >= 2)
00066    {
00067      LogFile << "NumChannels = " << NumChannels << endl;
00068      LogFile << "StringLength = " << StringLength << endl;
00069      LogFile << "DebugLevel = " << DebugLevel << endl;
00070    }
00071 
00072  switch(TypeBitString)
00073    {
00074      case ALL_ZEROS:
00075        for(int ch = 0; ch < NumChannels; ch++)
00076          SetAllZeros(ch);
00077        break;
00078 
00079      case ALL_ONES:
00080        for(int ch = 0; ch < NumChannels; ch++)
00081          SetAllOnes(ch);
00082        break;
00083 
00084      case SINGLE_ONE:
00085        for(int ch = 0; ch < NumChannels; ch++)
00086          SetSingleOne(ch);
00087        break;
00088 
00089      case USER_DEFINED:
00090        SetUserDefined(InFile);
00091        break;
00092 
00093    case RANDOM_SIMPLE: case RANDOM_EQUAL_ZEROS_ONES: case PSEUDO_RANDOM:
00094         GetRandomString();
00095         break;
00096 
00097    default:
00098        cerr << "BitString::BitString switch error" << endl
00099             << "ABORTING NOW!!" << endl;
00100        exit(1);
00101 
00102    } // ## end switch(TypeBitString)
00103 
00104  if(DebugLevel >= 3)
00105    WriteBitString();
00106 
00107 } // ## end constructor
00108 
00109 // ###########################################
00110 
00111 BitString::BitString(BitString & oBitString1) // Copy Constructor
00112 {
00113   // NOTE: The BitStringChann1 is not being copied as it's 
00114   // not used after apply copy constructor and moreover
00115   // is soon to be a defunct parameter 
00116 
00117   NumChannels = oBitString1.NumChannels;
00118   StringLength = oBitString1.StringLength;
00119   TypeBitString = oBitString1.TypeBitString;
00120   DebugLevel = oBitString1.DebugLevel;
00121   RNG = oBitString1.RNG;  // We want to keep the same RanNumGen
00122 
00123   BitStringArray = new int[StringLength*NumChannels];
00124 
00125   for(int ch = 0; ch < NumChannels; ch++)
00126     for(int ii = 0; ii < StringLength; ii++)
00127       SetBit(ch,ii,oBitString1.GetBit(ch,ii));
00128 
00129 }// end Copy Constructor
00130 
00131 // ###########################################
00132 
00133 BitString & BitString::operator=(BitString & RHS_BitString)
00134 {
00135 
00136   // This assignment operator assumes that the StringLength
00137   // and NumChannelsof the BitStrings on both sides of this function are
00138   // the same.
00139 
00140   /*
00141   cout << "NumChannels1 = " << NumChannels << endl;
00142   cout << "NumChannels2 = " << RHS_BitString.GetNumChannels() << endl;
00143   cout << "StringLength1 = " << StringLength << endl;
00144   cout << "StringLength2 = " << RHS_BitString.GetStringLength() << endl;
00145   */
00146 
00147  if( // NumChannels != RHS_BitString.GetNumChannels() ||
00148      StringLength != RHS_BitString.GetStringLength() )
00149     {
00150       LogFile << "Error in application of BitString::operator=" << endl 
00151               << flush;
00152 
00153       exit(1);
00154     }
00155   
00156 
00157   RNG = RHS_BitString.RNG;  // We want to keep the same RanNumGen
00158   
00159   TypeBitString = RHS_BitString.TypeBitString;
00160 
00161   DebugLevel = RHS_BitString.DebugLevel;
00162 
00163   for(int ch = 0; ch < NumChannels; ch++)
00164     for(int ii = 0; ii < StringLength; ii++)
00165       SetBit(ch,ii,RHS_BitString.GetBit(ch,ii));
00166 
00167   return *this;
00168 
00169 }// end assigment operator
00170 
00171 // ###########################################
00172 
00173 BitString::BitString(BitString & BitString1,BitString & BitString2,
00174                      RanNumGen *RNG3)
00175 {
00176 
00177 
00178   RNG = RNG3;
00179 
00180   if(BitString1.GetStringLength() != BitString2.GetStringLength())
00181     {
00182       cerr << "BitString::BitString(BitString1,BitString2,RNG3):" << endl
00183            << "Incompatable parameters" << endl
00184           << "Aborting now!!" << endl;
00185      exit(1);
00186     }
00187 
00188   NumChannels = BitString1.NumChannels+BitString2.NumChannels;
00189   StringLength = BitString1.StringLength;
00190   TypeBitString = BitString1.TypeBitString;
00191   DebugLevel = BitString1.DebugLevel;
00192   
00193 
00194   BitStringArray = new int[StringLength*NumChannels];
00195 
00196   int ch,mm;
00197 
00198  for(ch=0;ch<BitString1.NumChannels;ch++)
00199    { 
00200      for(mm=0;mm<StringLength;mm++)
00201        SetBit(ch,mm,BitString1.GetBit(ch,mm));
00202    }
00203 
00204  for(ch=BitString1.NumChannels;ch<NumChannels;ch++)
00205   {
00206    for(mm=0;mm<StringLength;mm++)
00207      SetBit(ch,mm,BitString2.GetBit(ch-BitString1.NumChannels,mm));
00208    
00209   }
00210 
00211  if(DebugLevel >=3)
00212    { 
00213     BitString1.WriteBitString();
00214     BitString2.WriteBitString();
00215     WriteBitString();
00216    }
00217 
00218 } // ## end Sum BitString constructor
00219 
00220 
00221 
00222 //#############################################
00223 //## Allocate the bit string array
00224 //#  It is necessary to make conversions from
00225 //#  WDM to single channel in the demuxer
00226 //#  Thus, it should be used with attention.
00227 //## By: Ivan Lima (7/9/01)
00228 void BitString::AllocateBitStringArray(int NumChannels2)
00229 {
00230    NumChannels = NumChannels2;
00231    BitStringArray = new int[StringLength*NumChannels];
00232 }
00233 
00234 
00235 // ####################################################
00236 
00237 void AddBitStrings(BitString * BitString1,
00238                    BitString * BitString2,
00239                    BitString * BitString3)
00240 {
00241 
00242    if(BitString3->NumChannels != BitString1->NumChannels + 
00243                                 BitString2->NumChannels)
00244     {
00245       cerr << "BitString::AddBitStrings: Incompatable parameters. ABORT!"
00246            << endl;
00247       exit(1);
00248     }
00249 
00250 
00251   int ch,mm;
00252 
00253  for(ch=0;ch<BitString1->NumChannels;ch++)
00254    { 
00255      for(mm=0;mm<BitString3->StringLength;mm++)
00256        BitString3->SetBit(ch,mm,BitString1->GetBit(ch,mm));
00257    }
00258 
00259  for(ch=BitString1->NumChannels;ch<BitString3->NumChannels;ch++)
00260   {
00261    for(mm=0;mm<BitString3->StringLength;mm++)
00262      BitString3->SetBit(ch,mm,
00263                  BitString2->GetBit(ch-BitString1->NumChannels,mm));
00264    
00265   }
00266 
00267  /*
00268     BitString1->WriteBitString();
00269     BitString2->WriteBitString();
00270     BitString3->WriteBitString();
00271  */
00272 
00273 } // ## end AddBitStrings
00274 
00275 // ############################################
00276 
00277 BitString::~BitString()
00278 {
00279 
00280   delete [] BitStringArray;
00281 
00282 }
00283 
00284 // #########################################
00285 
00286 string BitString::WriteTypeBitString(void)
00287 {
00288 
00289   string Type;
00290 
00291   switch(TypeBitString)
00292    {
00293 
00294     case ALL_ZEROS: Type = "ALL_ZEROS"; break;
00295     case ALL_ONES:  Type = "ALL_ONES"; break;
00296     case SINGLE_ONE: Type = "SINGLE_ONE"; break;
00297     case RANDOM_SIMPLE: Type = "RANDOM_SIMPLE"; break;
00298     case RANDOM_EQUAL_ZEROS_ONES: Type = "RANDOM_EQUAL_ZEROS_ONES"; break;
00299     case PSEUDO_RANDOM: Type = "PSEUDO_RANDOM"; break;
00300     case USER_DEFINED: Type = "USER_DEFINED"; break;
00301     default:
00302        cerr << "Invalid TypeBitString in BitString::WriteTypeBitString"
00303             << endl
00304             << "ABORTING NOW!!" << endl;
00305 
00306        exit(1);
00307 
00308    }// ## end switch
00309 
00310   return Type;
00311 
00312 }
00313 
00314 // ##############################################
00315 
00316 void BitString::SetBit(int ChannelArrayIndex, int BitSlot, int BitValue)
00317 {
00318  //## Written by John Zweck Oct 11, 2000
00319 
00320   // ## FIX: Add bounds checking!!
00321 
00322   BitStringArray[BitSlot + ChannelArrayIndex*StringLength] = BitValue;
00323 
00324 }
00325 
00326 // ###################################################
00327 
00328 int BitString::GetBit(int ChannelArrayIndex, int BitSlot)
00329 {
00330   //## Written by John Zweck Oct 11, 2000
00331 
00332  // ## FIX: Add bounds checking!!
00333 
00334  return BitStringArray[BitSlot + ChannelArrayIndex*StringLength];
00335 
00336 }
00337 
00338 // ###############################################################
00339 
00340 
00341 void BitString::SetRandomString(int ChannelArrayIndex)
00342 {
00343   // Generates a random string  
00344   // Created by Ivan Lima
00345   // Adapted by John Zweck, Nov 8, 2000
00346   // Further adapted by John Zweck, Feb 17th, 2001
00347 
00348   switch(TypeBitString)
00349     {
00350 
00351     case RANDOM_SIMPLE:
00352 
00353       for ( int ii = 0; ii < StringLength ; ii++ ) 
00354         {
00355          if (RNG->GetRanNum() <= 0.5) 
00356            SetBit(ChannelArrayIndex,ii,0);         
00357          else
00358            SetBit(ChannelArrayIndex,ii,1);
00359   
00360         } // end for-loops
00361 
00362       break;
00363 
00364     case RANDOM_EQUAL_ZEROS_ONES:
00365 
00366     {
00367 
00368       // Aside; We need the {} block to get around a scoping
00369       // problem within the switch.
00370 
00371       double * RanNumArray;
00372 
00373       RanNumArray = new double[StringLength];
00374 
00375       for(int ii = 0; ii < StringLength; ii++)
00376         RanNumArray[ii] = RNG->GetRanNum();
00377 
00378       StatisticsOfArray Stats(StringLength,RanNumArray);
00379 
00380       for ( int ii = 0; ii < StringLength ; ii++ ) 
00381         {
00382          if (RanNumArray[ii] <= Stats.GetMedian()) 
00383            SetBit(ChannelArrayIndex,ii,0);         
00384          else
00385            SetBit(ChannelArrayIndex,ii,1);
00386   
00387         } // end for-loop
00388 
00389        delete [] RanNumArray;
00390     }
00391 
00392       break;
00393 
00394     case PSEUDO_RANDOM:
00395 
00396 
00397       cerr << "BitString::SetRandomString" << endl
00398            << "Option PSEUDO_RANDOM not implemented yet" << endl
00399            << "ABORTING NOW!!" <<  endl;
00400 
00401       exit(1);
00402 
00403       break;
00404 
00405     default: 
00406 
00407       cerr << "BitString::SetRandomString" << endl
00408            << "Invalid switch option" << endl
00409            << "ABORTING NOW!!" <<  endl;
00410 
00411       exit(1);
00412 
00413     } // ## end switch
00414 
00415 
00416 } //## end SetRandomString(int ChannelArrayIndex)
00417 
00418 // ###############################################################
00419 
00420 void BitString::SetPseudoRandomString(int ChannelArrayIndex)
00421 {
00422   //  Written by Brian Marks
00423   //  Last modified 17/05/2001
00424   // 
00425   //  Generates a PseudoRandom Bit String for the channel ChannelArrayIndex.
00426   //  Currently, this routine only supports bit strings of the length of a 
00427   //  power of 2, and currently only between 2^3 and 2^16 inclusively.  
00428   //  Pseudorandom strings shorter than this length do not make much sense, 
00429   //  and it would be straight forward to add the capability to make strings
00430   //  longer than this.  However, do we ever need to simulate more than 65536
00431   //  bits anyway?  
00432   //
00433   //  Truthfully, this routine creates a so-called DeBruijn string, which 
00434   //  accounts for all patterns of length PatternLength (n in 2^n) =including=
00435   //  the pattern of all 0s.  This is done by setting the seed for the 
00436   //  random pattern to [1 0 0 ... 0].  
00437   //  FIX: Add capability of arbitrary seed for 2^n-1 PRBS.
00438  
00439   int PatternLength;
00440   int next;
00441   
00442   //  The following creates the mask for XOR addition to find successive
00443   //  bits in the sequence.  That is, this represents the primitive polynomials
00444   //  of various orders to generate the sequence for various PatternLength.
00445   int mask[16][16] = { {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},        
00446                         // n = 1?
00447                        {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},        
00448                         // n = 2?
00449                        {0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},        
00450                         // x^3 + x^2 + 1
00451                        {1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},  
00452                         // x^4 + x + 1
00453                        {0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},        
00454                         // x^5 + x^2 + 1
00455                        {1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0},        
00456                         // x^6 + x + 1
00457                        {0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0},  
00458                         // x^7 + x^6 + 1
00459                        {0, 1, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0},
00460                         // x^8 + x^4 + x^3 + x^2 + 1
00461                        {0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0},        
00462                         // x^9 + x^5 + 1
00463                        {0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0}, 
00464                         // x^10 + x^3 + 1
00465                        {0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0},
00466                         // x^11 + x^2 + 1
00467                        {1, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0},
00468                         // x^12 + x^6 + x^4 + x + 1
00469                        {1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0},
00470                         // x^13 + x^4 + x^3 + x + 1
00471                        {1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0},
00472                         // x^14 + x^10 + x^6 + x + 1
00473                        {1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0},
00474                         // x^15 + x + 1
00475                        {1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1}
00476                         // x^16 + x^12 + x^3 + x + 1            
00477                        };
00478                        
00479                        
00480   
00481   PatternLength = (int)rint(log(StringLength) / log(2.0));
00482   
00483   int seed[PatternLength];
00484 
00485 
00486   //  This sets the seed to [1 0 0 ... 0] for the DeBruijn pattern.  
00487   for ( int ii = 0; ii < PatternLength; ii++ )
00488     seed[ii] = 0; 
00489   seed[0] = 1;
00490   
00491   
00492   if (abs((log(StringLength) / log(2.0)) - PatternLength) > 1.0e-14)
00493   {
00494     cerr << "BitString::SetPseudoRandomString" << endl
00495          << "Requires string length of a power of 2." << endl
00496          << "ABORTING NOW!!" << endl;
00497  
00498     exit(1);
00499   }
00500 
00501   if (PatternLength < 3 || PatternLength > 16) 
00502   {
00503     cerr << "BitString::SetPseudoRandomString" << endl
00504          << "Currently only supports patterns of length between 3"
00505          << " and 16" << endl
00506          << "(StringLength between 8 and 65536)" << endl
00507          << "ABORTING NOW!!" << endl;
00508          
00509          exit(1);
00510   }  
00511   
00512   //  For the DeBruijn pattern, the first bit is always 0, followed by the seed.
00513   SetBit(ChannelArrayIndex, StringLength-1, 0);
00514   for ( int ii = 0; ii < PatternLength; ii++ )
00515     SetBit(ChannelArrayIndex, StringLength-2-ii, seed[PatternLength-1-ii]);
00516    
00517   for ( int ii = StringLength - PatternLength - 2; ii >= 0; ii-- )
00518     {
00519         // The following does the XOR addition to find the next bit
00520         next = 0;
00521         for ( int jj = 0; jj < PatternLength; jj++ )
00522           next += (mask[PatternLength-1][jj] * seed[jj]);
00523         next = next % 2;
00524         
00525         // The following does a one-bit shift register in the seed
00526         for ( int jj = PatternLength-1; jj > 0; jj-- )
00527           seed[jj] = seed[jj-1];
00528         seed[0] = next;
00529                 
00530         SetBit(ChannelArrayIndex, ii, next);
00531     }  // end for-loop
00532         
00533 
00534 }  // end SetPseudoRandomString(int ChannelArrayIndex)
00535 
00536 // ###############################################################
00537 
00538 void BitString::GetRandomString(void)
00539 {
00540   // Written by John Zweck, Nov 8, 2000
00541 
00542   // This method can be used in a Monte Carlo simulation application
00543   // to get a new random string for the next MC experiment.
00544   // It will only do this if TypeBitString is one of the  RANDOM 
00545   // types. Otherwise it will not change the bit string at all.
00546 
00547   // It is also used by the BitString constructor.
00548 
00549    switch(TypeBitString)
00550    {
00551      case ALL_ZEROS: case ALL_ONES: case SINGLE_ONE: case USER_DEFINED:
00552        // Do nothing!
00553 
00554        break;
00555        
00556      case PSEUDO_RANDOM:
00557      
00558  // KLUDGY:  Sets PRBSs in every channel.  This might not be what you want.
00559 
00560        for(int ch=0; ch<NumChannels; ch++)
00561          SetPseudoRandomString(ch);
00562        break;
00563 
00564      case RANDOM_SIMPLE: case RANDOM_EQUAL_ZEROS_ONES:
00565      
00566   
00567        for(int ch=0; ch<NumChannels;ch++)
00568            SetRandomString(ch);
00569 
00570        break;
00571 
00572     default:
00573        cerr << "BitString::BitString switch error" << endl
00574             << "ABORTING NOW!!" << endl;
00575        exit(1);
00576 
00577    } //## end switch
00578 
00579 } // ## end GetRandomString
00580 
00581 // ######################################################
00582 
00583 void BitString::SetAllZeros(int ChannelArrayIndex)
00584 {
00585   for ( int ii = 0; ii < StringLength ; ii++ ) 
00586     SetBit(ChannelArrayIndex,ii,0); 
00587  
00588 }
00589 
00590 // ####################################################
00591 
00592 void BitString::SetAllOnes(int ChannelArrayIndex)
00593 {
00594   for ( int ii = 0; ii < StringLength ; ii++ ) 
00595     SetBit(ChannelArrayIndex,ii,1); 
00596  
00597 }
00598 
00599 // ####################################################
00600   
00601 void BitString::SetSingleOne(int ChannelArrayIndex)
00602 {
00603 
00604   SetAllZeros(ChannelArrayIndex);
00605 
00606   if(StringLength%2 == 0) // StringLength is even
00607     {
00608       SetBit(ChannelArrayIndex,StringLength/2 - 1,1);   
00609 
00610       if(DebugLevel >=3)
00611         LogFile << "BitString::SetSingleOne" << endl
00612                 << "The Single One is in bit with index "
00613                 << StringLength/2 - 1
00614                 << endl;
00615     }
00616   else // StringLength is odd
00617    {
00618       SetBit(ChannelArrayIndex,(StringLength-1)/2,1);   
00619 
00620       if(DebugLevel >=3)
00621         LogFile << "BitString::SetSingleOne" << endl
00622                 << "The Single One is in bit with index "
00623                 << (StringLength-1)/2
00624                 << endl;
00625     }
00626 
00627 } // ## end SetSingleOne
00628   
00629 // ##########################################################
00630 
00631 void BitString::SetUserDefined(ifstream * InFile)
00632 {
00633 
00634   // Written by John Zweck, Oct 2000, Feb 17th 2001.
00635 
00636 char C_String[20]; 
00637 string BitStringName;
00638 
00639 string BitString;
00640 string BitStringPreviousChannel;
00641 
00642 for(int ch = 0;ch < NumChannels; ch++)
00643    {
00644      
00645      // To create a string object from a string and an int
00646      // it seems simplest to use the sprintf function for
00647      // C Strings and then initialize the string using the
00648      // C String.
00649 
00650      sprintf(C_String,"BitStringChann%d",ch+1);
00651      BitStringName = C_String;
00652 
00653      BitStringPreviousChannel =  BitString;
00654  
00655      BitString = ReadString(BitStringName,InFile);
00656      
00657      if(BitString == " " && ch == 0)
00658        {
00659          LogFile << "ERROR: Input File for Optical Signal must" << endl
00660                  << "include parameter $BitStringChann1" << endl
00661                  << "ABORTING NOW" << endl;
00662          exit(1);
00663        }
00664 
00665 
00666      if(DebugLevel >=2)
00667        {
00668           LogFile << endl
00669              << "BitString read from input file in Physical Channel "
00670              << GetChannelPhysicalIndex(ch) << " = " 
00671              << BitString << endl;
00672        }
00673 
00674      if(BitString == " " && ch > 0)
00675        {
00676          BitString =  BitStringPreviousChannel;
00677          
00678          if(DebugLevel >=3)
00679            {
00680          LogFile << endl 
00681                  << "WARNING: BitStringChann" << ch+1 << " not specified." 
00682                  << endl
00683                  << "So using BitString from BitStringChann" << ch << endl;
00684            }
00685 
00686        }
00687 
00688   
00689      int InputStringLength =  BitString.length();
00690           
00691      if(InputStringLength > StringLength)
00692         {
00693               LogFile << "Bit String in channel " << ch+1 
00694                       << " is longer than StringLength" << endl
00695                       << "ABORTING NOW" << endl;
00696               exit(1);
00697         }
00698 
00699 
00700      for(int ii=0; ii < StringLength; ii++)
00701         SetBit(ch,ii,0);
00702 
00703      int left_ii = 0;
00704      int right_ii = StringLength - 1;
00705 
00706      if(InputStringLength != StringLength)
00707         {
00708 
00709           if(DebugLevel >=2)
00710            {
00711                  LogFile << endl
00712                       << "WARNING: In channel " << ch+1 
00713                       << " input string length" << endl
00714                       << "is less than StringLength, so pad  with 0's" 
00715                       << endl;
00716             }
00717 
00718           left_ii = int(floor((StringLength - InputStringLength)/2));
00719           right_ii = left_ii + InputStringLength - 1;
00720 
00721           if(DebugLevel >=3)
00722             {
00723               LogFile << "The first bit in the input file BitString becomes "
00724                       << "bit " << left_ii << endl;
00725 
00726                LogFile << "The last bit in the input file BitString becomes "
00727                    << "bit " << right_ii << endl;
00728             }
00729 
00730           if(left_ii < 0 || left_ii >= StringLength ||
00731              right_ii < 0 || right_ii >= StringLength)
00732              {
00733                     LogFile << "Error in bit string constructor" << endl
00734                             <<  "ABORTING NOW" << endl;
00735                     exit(1);
00736 
00737              }
00738         } //## end if(InputStringLength != StringLength)
00739            
00740          
00741      string temp; 
00742 
00743      for(int ii=left_ii; ii <= right_ii ; ii++)
00744          {
00745 
00746            temp = BitString[ii-left_ii]; 
00747 
00748            // The comparison BitString[ii] == "1" was disallowed
00749            // by the compiler as BitString[ii] is a pointer.
00750 
00751            if(temp == "1")
00752               SetBit(ch,ii,1);
00753            else
00754             {
00755               if(temp == "0")
00756                  SetBit(ch,ii,0);
00757               else
00758                {
00759                  LogFile << endl 
00760                          << "Bit " << ii << " = " << BitString[ii] << endl
00761                          << "WARNING: Bit String must be a string" << endl
00762                          <<  "of 0's and 1's"
00763                          << endl << "ABORTING NOW!!" << endl;
00764                   exit(1);
00765                 } // end else
00766              } // end else
00767 
00768        } // ##end for(int ii=left_ii; ii <= right_ii ; ii++)
00769       
00770    } // end for ch loop
00771 
00772 } // ## end SetUserDefined
00773 
00774 // #######################################################
00775 
00776 void BitString::SetStringToSingleMarkPerChannel(void)
00777 {
00778 
00779   int ch,i;
00780 
00781 for(ch=0;ch<NumChannels;ch++)
00782 for(i=0;i<StringLength;i++)
00783    SetBit(ch,i,0);
00784 
00785 for(ch=0;ch<NumChannels;ch++)
00786    SetBit(ch,(StringLength-1)/2,1);
00787 
00788 }
00789 
00790 // #########################################################
00791 
00792 void BitString::ReduceToSingleChannelBitString(int ChannelArrayIndex)
00793 {
00794 
00795   // An OptDemuxer extracts a single channel signal from a WDM Signal.
00796   // The following method is used by the Demuxer to extract the BitString
00797   // of the extracted single channel signal  from the BitString of the
00798   // WDM Signal
00799   // Before calling this method we assume that the BitString object
00800   // is a multi-channel. The method changes the BitString to be 
00801   // single channel. 
00802   // In particular the parameter NumChannels is changed from 
00803   // NumChannels to 1 within this method.
00804 
00805   // Store the single channel BitString we want to extract
00806   // in a temporary array
00807 
00808   int *TempBitStringArray;
00809 
00810   TempBitStringArray = new int[StringLength];
00811 
00812   for(int ii = 0; ii < StringLength; ii++)
00813     TempBitStringArray[ii] = GetBit(ChannelArrayIndex,ii);
00814 
00815   // Delete the BitStringArray
00816 
00817   /*
00818   delete [] BitStringArray;
00819   BitStringArray = NULL;
00820   */
00821 
00822   // Set NumChannels
00823 
00824   //  NumChannels = 1;
00825 
00826   // Allocate memory for new BitString array
00827 
00828   /*
00829   BitStringArray = new int[StringLength];
00830   */
00831 
00832   // Initialize the values of the new BitStringArray
00833 
00834   // The reason I do this is its a quick and dirty way to ensure that
00835   // the  method will still work if change
00836   // the way  BitStringArray stores the bits.
00837 
00838     for(int ii = 0; ii < StringLength; ii++)
00839       SetBit(0,ii,TempBitStringArray[ii]);
00840  
00841 }
00842 
00843 // ######################################################
00844 
00845 void BitString::ReduceToSingleChannelBitString(BitString * SCBitString)
00846 {
00847 
00848   // An OptDemuxer extracts a single channel signal from a WDM Signal.
00849   // The following method is used by the Demuxer to extract the BitString
00850   // of the extracted single channel signal  from the BitString SCBitString.
00851   // Before calling this method we assume that the BitString object
00852   // is a multi-channel. The method changes the BitString to be 
00853   // single channel. 
00854   // In particular the parameter NumChannels is changed from 
00855   // NumChannels to 1 within this method.
00856 
00857   // Store the single channel BitString we want to extract
00858   // in a temporary array
00859 
00860 
00861   // Initialize the values of the new BitStringArray
00862 
00863   // The reason I do this is its a quick and dirty way to ensure that
00864   // the  method will still work if change
00865   // the way  BitStringArray stores the bits.
00866 
00867     for(int ii = 0; ii < StringLength; ii++)
00868       SetBit(0,ii,SCBitString->GetBit(0,ii));
00869  
00870 }
00871 
00872 // ######################################################
00873 
00874 string BitString::ReadString(string ParameterName, ifstream * InFile) 
00875 {
00876 
00877   int ParameterRead = 0;
00878   string ParameterValue;
00879   string NameBuffer;
00880 
00881   string ParameterNameDollar = "$"+ParameterName;
00882 
00883   InFile->clear(); // Resets ifstream state to good
00884   
00885   // In order for an input operation to actually do something its
00886   // state must be "good". When the end of file is reached the 
00887   // state is set to "eof" which is not good! (This will have happened
00888   // if the ReadInt function has been previously called.)
00889   // The clear() function resets the state to "good"
00890 
00891 
00892   InFile->seekg(0); // Resets the file pointer to the start of the file.
00893 
00894 
00895   while (*InFile >> NameBuffer)
00896     {
00897     if (ParameterNameDollar==NameBuffer) 
00898      {
00899          *InFile >> ParameterValue; 
00900 
00901          // FIX: Check that have really read value in correctly!
00902 
00903          ParameterRead = 1;
00904      }  // end if   
00905       
00906     } // end while
00907 
00908 
00909   if(!ParameterRead)
00910     {
00911 
00912       // Since this routine is used to input BitStrings
00913       // if the required BitString is not present we 
00914       // return the NULL string and let the BitString
00915       // constructor work out what to do.
00916 
00917        ParameterValue = " ";
00918     }
00919   else
00920    LogFile << ParameterName << " = " << ParameterValue << " " << endl;
00921 
00922 
00923   return ParameterValue;
00924 
00925 } // end ReadString();
00926 
00927 // #########################################################
00928 
00929 int BitString::GetChannelArrayIndex(int ChannelPhysicalIndex)
00930 {
00931 
00932   //## Written by John Zweck Oct 11, 2000
00933   //## 
00934   //## ChannelPhysicalIndex runs 
00935   //## -N/2,..... N/2 - 1 for N = NumChannels even and
00936   //## - (N-1)/2, ... (N-1)/2 for N odd
00937   //##
00938   //## ChannelArrayIndex runs 0,1,...,N-1
00939 
00940   // FIX Add bounds checker!!
00941 
00942   if(NumChannels %2 == 0) // NumChannels even 
00943     return ChannelPhysicalIndex + NumChannels/2;
00944   else // NumChannels odd
00945     return ChannelPhysicalIndex + (NumChannels-1)/2;
00946 
00947 } // ## end GetChannelArrayIndex
00948 
00949 // ##############################################
00950 
00951 int BitString::GetChannelPhysicalIndex(int ChannelArrayIndex)
00952 {
00953 
00954   //## Written by John Zweck Oct 11, 2000
00955   //## 
00956   //## ChannelPhysicalIndex runs 
00957   //## -N/2,..... N/2 - 1 for N = NumChannels even and
00958   //## - (N-1)/2, ... (N-1)/2 for N odd
00959   //##
00960   //## ChannelArrayIndex runs 0,1,...,N-1
00961 
00962   // FIX Add bounds checker!
00963 
00964   if(NumChannels %2 == 0) // NumChannels even 
00965     return ChannelArrayIndex - NumChannels/2;
00966   else // NumChannels odd
00967     return ChannelArrayIndex - (NumChannels-1)/2;
00968 
00969 }
00970 
00971 // ################################################
00972 
00973 void BitString::WriteBitString(void)
00974 {
00975 
00976   cout << "########################" << endl;
00977 
00978 
00979   for(int ch=0;ch<NumChannels;ch++)
00980     {
00981      for(int bit = 0; bit < StringLength; bit++)
00982        cout << GetBit(ch,bit);
00983 
00984      cout << endl;
00985 
00986     }
00987 
00988 }
00989 
00990 // ##################################
00991 
00992 
00993 
00994 
00995 
00996 
00997 
00998 
00999 

Generated at Mon Jun 9 20:08:09 2003 for OCS by doxygen1.2.3 written by Dimitri van Heesch, © 1997-2000