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
00048 std::cerr << "cooccuranceMatrix must be square" << std::endl;
00049 throw "bye";
00050 }
00051
00052
00053 Vector::VectorTem<Real64> descriptor(2 * n);
00054
00055
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
00070
00071
00072 delete normalizationFactors;
00073
00074
00075 Mat* identity = MatCreate<Mat>(n, n);
00076 SetVal(identity, 0.0);
00077
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
00085 for(int k = 0; k < ITERATION_COUNT; k++)
00086 {
00087 Mat* currentPower = MatMul(previousPower, p);
00088
00089 Add(a, a, currentPower);
00090 delete previousPower;
00091 previousPower = currentPower;
00092 }
00093
00094 delete previousPower;
00095 MulVal(a, a, 1.0 / (ITERATION_COUNT + 1));
00096
00097
00098
00099
00100 Mat* stationarySum = MatSumAxis0(a);
00101
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
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
00116
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 }
00190 }
00191 }
00192
00193 #endif