home *** CD-ROM | disk | FTP | other *** search
/ AI Game Programming Wisdom / AIGameProgrammingWisdom.iso / SourceCode / 11 Learning / 08 Manslow / CUnconditionalDistribution.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  2001-10-01  |  5.3 KB  |  179 lines

  1. //Tanks
  2. //Copyright John Manslow
  3. //29/09/2001
  4.  
  5. ////////////////////////////////////////////////////
  6. //Remove this include if not compiling under windows
  7. #include "stdafx.h"
  8. #define new DEBUG_NEW
  9. ////////////////////////////////////////////////////
  10. #include "CUnconditionalDistribution.h"
  11. #include "stdlib.h"
  12. #include "math.h"
  13. #include "stdio.h"
  14. #include "assert.h"
  15. #include "fstream.h"
  16. #include "time.h"
  17.  
  18. CUnconditionalDistribution::CUnconditionalDistribution(
  19.                                                             const unsigned long ulNewNumberOfBins
  20.                                                                                         )
  21. {
  22.     TRACE("\t\tCreating unconditional distribution...");
  23.  
  24.     //Record the structure of the model (the number of bins it uses)
  25.     assert(!(ulNewNumberOfBins<1));
  26.     ulNumberOfBins=ulNewNumberOfBins;
  27.  
  28.     //Allocate memory to store the bin probabilities
  29.     AllocateMemory();
  30.  
  31.     //Reset the probabilities to default values
  32.     Reset();
  33.  
  34.     //Set these character pointers to NULL so we know they're not used yet
  35.     pTrainingStartTime=NULL;
  36.     pTrainingStartDate=NULL;
  37.  
  38.     TRACE("successful.\n");
  39. }
  40.  
  41. void CUnconditionalDistribution::AllocateMemory(void)
  42. {
  43.     //Allocate memory to store the bin probabilities
  44.     pdBinProbabilities=new double[ulNumberOfBins];
  45. }
  46.  
  47. void CUnconditionalDistribution::DeallocateMemory(void)
  48. {
  49.     //Deallocate the storage used for the bin probabilities
  50.     delete []pdBinProbabilities;
  51.  
  52.     //If we've recorded the time and date of the start of training, delete them too
  53.     if(pTrainingStartTime)
  54.     {
  55.         delete []pTrainingStartTime;
  56.     }
  57.     if(pTrainingStartDate)
  58.     {
  59.         delete []pTrainingStartDate;
  60.     }
  61. }
  62.  
  63. CUnconditionalDistribution::~CUnconditionalDistribution()
  64. {
  65.     TRACE("\t\tDestroying unconditional distribution...");
  66.     DeallocateMemory();
  67.     TRACE("successful.\n");
  68. }
  69.  
  70. void CUnconditionalDistribution::Reset(void)
  71. {
  72.     unsigned long i;
  73.  
  74.     //Initialise the bin probabilities to be equal (and sum to unity)
  75.     for(i=0;i<ulNumberOfBins;i++)
  76.     {
  77.         pdBinProbabilities[i]=1.0/double(ulNumberOfBins);
  78.     }
  79.  
  80.     //Record that we have no data points (implicitly) "stored" in the distribution
  81.     ulNumberOfDataPoints=0;
  82. }
  83.  
  84. //This function "trains" the unconditional distribution model by computing the probabilities associated with
  85. //each bin. These probabilities are simply the proportions of the example patterns that lie in each bin. The
  86. //function is designed so that all data points do not have to be added in one go. The function can be repeatedly
  87. //called as additional data becomes available. In this application, only a single call to this function is required.
  88. void CUnconditionalDistribution::dTrainingStep(
  89.                             const unsigned long ulNumberOfPatternsInTrainingSet,
  90.                             const double * const pdTrainingTargets
  91.                             )
  92. {
  93.     unsigned long i,j;
  94.     unsigned long ulNumberOfDataPointsAdded=0;
  95.  
  96.     //Make sure we deallocate memory pointed to by these pointers (if any) before we 
  97.     //reassign them
  98.     if(pTrainingStartTime)
  99.     {
  100.         delete []pTrainingStartTime;
  101.     }
  102.     if(pTrainingStartDate)
  103.     {
  104.         delete []pTrainingStartDate;
  105.     }
  106.  
  107.     //Record time and date that training started.
  108.     pTrainingStartTime=new char[256];
  109.     _strtime(pTrainingStartTime);
  110.     pTrainingStartDate=new char[256];
  111.     _strdate(pTrainingStartDate);
  112.  
  113.     //Transform the bin probabilities back into the number of samples in each bin by multiplying the bin
  114.     //probabilities by the number of examples "stored" in the model
  115.     for(i=0;i<ulNumberOfBins;i++)
  116.     {
  117.         pdBinProbabilities[i]*=double(ulNumberOfDataPoints);
  118.     }
  119.  
  120.     //Increment the counts associated with any bin that contains new examples
  121.     for(i=0;i<ulNumberOfPatternsInTrainingSet;i++)
  122.     {
  123.         for(j=0;j<ulNumberOfBins;j++)
  124.         {
  125.             if(pdTrainingTargets[i]>=double(j)/double(ulNumberOfBins) 
  126.                 && pdTrainingTargets[i]<double(j+1)/double(ulNumberOfBins))
  127.             {
  128.                 //This pattern (the ith example) is in this (the jth) bin, so increment the counter of the 
  129.                 //number of patterms in this bin
  130.                 pdBinProbabilities[j]++;
  131.                 ulNumberOfDataPointsAdded++;
  132.             }
  133.         }
  134.     }
  135.  
  136.     //Keep track of the number of examples that have been added to the distribution
  137.     ulNumberOfDataPoints+=ulNumberOfDataPointsAdded;
  138.  
  139.     //Normalise the bin counts to convert them back into probabilities
  140.     for(i=0;i<ulNumberOfBins;i++)
  141.     {
  142.         pdBinProbabilities[i]/=double(ulNumberOfDataPoints);
  143.     }
  144. }
  145.  
  146. //This function generates an output from the model by taking a random sample from it.
  147. double CUnconditionalDistribution::dGetOutputs(void)
  148. {
  149.     //Stoirage for the sample
  150.     double dOutput;
  151.  
  152.     //Select a target cumulative probability. A sample will be generated from the bin that contains this cumulative
  153.     //probability
  154.     double dTargetProbability=double(rand())/double(RAND_MAX);
  155.  
  156.     //Prepare to count through the bins in turn
  157.     unsigned long ulCurrentBin=0;
  158.  
  159.     //The cumulative probability
  160.     double dAccumulator=pdBinProbabilities[ulCurrentBin];
  161.  
  162.     //While we've not yet found the target bin 
  163.     while(dTargetProbability>dAccumulator)
  164.     {
  165.         //Move onto the next bin
  166.         ulCurrentBin++;
  167.  
  168.         //Accumulate the probabilities
  169.         dAccumulator+=pdBinProbabilities[ulCurrentBin];
  170.     }
  171.  
  172.     //Now that we've found the correct bin, we generate a specific output by choosing a sample from a uniform
  173.     //distribution over the support of the bin (i.e. somewhere between the lefthand and righthand edge of the bin)
  174.     dOutput=double(ulCurrentBin)/double(ulNumberOfBins)+double(rand())/double(RAND_MAX)*(1.0/double(ulNumberOfBins));
  175.  
  176.     //Return the sample
  177.     return dOutput;
  178. }
  179.