Home || Architecture || Video Search || Visual Search || Scripts || Applications || Important Messages || OGL || Src

MarkovStationaryFeature.h

Go to the documentation of this file.
00001 #ifndef Impala_Core_Feature_MarkovStationaryFeature_h
00002 #define Impala_Core_Feature_MarkovStationaryFeature_h
00003 
00004 #include "Core/Array/Add.h"
00005 #include "Core/Array/MulVal.h"
00006 #include "Core/Vector/VectorTem.h"
00007 #include "Core/Vector/Sum.h"
00008 #include "Core/Matrix/Mat.h"
00009 #include "Core/Matrix/MatFunc.h"
00010 #include "Core/Matrix/MatSum.h"
00011 #include "Core/Matrix/MatCopy.h"
00012 #include "Core/Matrix/MatMul.h"
00013 #include "Core/Matrix/GetDiagonal.h"
00014 
00015 namespace Impala
00016 {
00017 namespace Core
00018 {
00019 namespace Feature
00020 {
00021 
00022 
00023 void
00024 Dump(Matrix::Mat* matrix)
00025 {
00026     using namespace Matrix;
00027     for(int i = 0; i < MatNrRow(matrix); i++)
00028     {
00029         for(int j = 0; j < MatNrCol(matrix); j++)
00030         {
00031             std::cout << *MatE(matrix, i, j) << " ";
00032         }
00033         std::cout << std::endl;
00034     }
00035 }
00036 
00037 
00038 inline Vector::VectorTem<Real64>
00039 MarkovStationaryFeature(Matrix::Mat* cooccuranceMatrix)
00040 {
00041     using namespace Matrix;
00042     const int ITERATION_COUNT = 100;
00043 
00044     int n = MatNrRow(cooccuranceMatrix);
00045     if(MatNrCol(cooccuranceMatrix) != n)
00046     {
00047         // it cannot be!
00048         std::cerr << "cooccuranceMatrix must be square" << std::endl;
00049         throw "bye";
00050     }
00051 
00052     /* descriptor storage */
00053     Vector::VectorTem<Real64> descriptor(2 * n);
00054 
00055     /* normalize the co-ocurrance matrix */
00056     Mat* p = MatCreate<Mat>(n, n);
00057     Mat* normalizationFactors = MatSumAxis1(cooccuranceMatrix);
00058     for(int vj = 0; vj < n; vj++)
00059     {
00060         if(*MatE(normalizationFactors, vj, 0) == 0.0)
00061         {
00062             *MatE(normalizationFactors, vj, 0) = 1.0;
00063         }
00064         for(int i = 0; i < n; i++) 
00065         {
00066             *MatE(p, vj, i) = *MatE(cooccuranceMatrix, vj, i) / *MatE(normalizationFactors, vj, 0);
00067         }
00068     }
00069     //Dump(cooccuranceMatrix);
00070     //Dump(normalizationFactors);
00071     //Dump(p);
00072     delete normalizationFactors;
00073 
00074     /* we now have a transition matrix in p */
00075     Mat* identity = MatCreate<Mat>(n, n);
00076     SetVal(identity, 0.0);
00077     // set to identity matrix
00078     for(int i = 0; i < n; i++) 
00079     {
00080         *MatE(identity, i, i) = 1.0;
00081     }
00082     Mat* a = MatCopy(identity);
00083     Mat* previousPower = identity;
00084     // identity will be deleted in the loop as previousPower
00085     for(int k = 0; k < ITERATION_COUNT; k++)
00086     {
00087         Mat* currentPower = MatMul(previousPower, p);
00088         // perform matrix addition
00089         Add(a, a, currentPower);
00090         delete previousPower;
00091         previousPower = currentPower;
00092     }
00093     //std::cout << "previous:" << std::endl; Dump(previousPower);
00094     delete previousPower;
00095     MulVal(a, a, 1.0 / (ITERATION_COUNT + 1));
00096     //std::cout << "a_n:" << std::endl; Dump(a);
00097     
00098     /* construct the stationary disribution by taking the averages of the
00099        rows of a (all rows of a should be equal upon convergence) */
00100     Mat* stationarySum = MatSumAxis0(a);
00101     //Dump(stationarySum);
00102     for(int i = 0; i < n; i++)
00103     {
00104         descriptor[n + i] = *MatE(stationarySum, 0, i) / n;
00105     }
00106     delete a;
00107     delete stationarySum;
00108 
00109     /* construct initial distribution by normalizing the self-transition */
00110     Vector::VectorTem<Real64> diagonal = GetDiagonal(cooccuranceMatrix);
00111     Real64 normalizationFactor = Sum(diagonal);
00112     if(normalizationFactor == 0.0) normalizationFactor = 1.0;
00113     Vector::VectorTem<Real64> initialDistribution = diagonal * (1.0 / normalizationFactor);
00114     
00115     /* combine initial distribution and stationary distribution into a single
00116        vector */    
00117     for(int i = 0; i < n; i++)
00118     {
00119         descriptor[i] = initialDistribution[i];
00120     }
00121     delete p;
00122     
00123     return descriptor;
00124 }
00125 
00126 
00127 inline Vector::VectorTem<Real64>
00128 MarkovStationaryFeatureTimed(Matrix::Mat* m)
00129 {
00130     ILOG_VAR(Sandbox.koen.MarkovStationaryFeature);
00131     Timer timer;
00132     Vector::VectorTem<Real64> temp = MarkovStationaryFeature(m);
00133     ILOG_INFO("MSF in " << timer.SplitTimeStr());
00134     return temp;
00135 }
00136 
00137 
00138 void
00139 testMSF()
00140 {
00141     ILOG_VAR(Impala.Core.Feature.testMSF);
00142     using namespace Matrix;
00143     Mat* a = 0;
00144     a = MatCreate<Mat>(8, 8);
00145     
00146             *MatE(a, 0, 0) = 1;
00147             *MatE(a, 0, 1) = 2;
00148             *MatE(a, 0, 2) = 3;
00149             *MatE(a, 0, 3) = 4;
00150             *MatE(a, 0, 4) = 5;
00151             *MatE(a, 1, 0) = 4;
00152             *MatE(a, 1, 1) = 3;
00153             *MatE(a, 1, 2) = 2;
00154             *MatE(a, 1, 3) = 9;
00155             *MatE(a, 1, 4) = 0;
00156 
00157     a = MatCreate<Mat>(3, 3);
00158             *MatE(a, 0, 0) = 160;
00159             *MatE(a, 0, 1) = 30;
00160             *MatE(a, 0, 2) = 10;
00161             *MatE(a, 1, 0) = 30;
00162             *MatE(a, 1, 1) = 340;
00163             *MatE(a, 1, 2) = 30;
00164             *MatE(a, 2, 0) = 10;
00165             *MatE(a, 2, 1) = 30;
00166             *MatE(a, 2, 2) = 160;
00167 
00168     a = MatCreate<Mat>(3, 3);
00169             *MatE(a, 0, 0) = 160;
00170             *MatE(a, 0, 1) = 40;
00171             *MatE(a, 0, 2) = 0;
00172             *MatE(a, 1, 0) = 40;
00173             *MatE(a, 1, 1) = 340;
00174             *MatE(a, 1, 2) = 40;
00175             *MatE(a, 2, 0) = 0;
00176             *MatE(a, 2, 1) = 40;
00177             *MatE(a, 2, 2) = 160;
00178 
00179     ILOG_INFO("MSF start");
00180     Vector::VectorTem<Real64> descriptor = MarkovStationaryFeature(a);
00181     for(int i = 0; i < descriptor.Size(); i++)
00182     {
00183         std::cout << descriptor[i] << " ";
00184     }
00185     std::cout << std::endl;
00186     ILOG_INFO("MSF stop");
00187 }
00188 
00189 } // namespace Koen
00190 } // namespace Sandbox
00191 } // namespace Impala
00192 
00193 #endif

Generated on Fri Mar 19 09:31:07 2010 for ImpalaSrc by  doxygen 1.5.1