00001 #ifndef Impala_Core_Matrix_MatCovariance_h
00002 #define Impala_Core_Matrix_MatCovariance_h
00003
00004 #include "Core/Matrix/MatSet.h"
00005 #include "Core/Matrix/MatDiv.h"
00006 #include "Core/Matrix/VecFunc.h"
00007
00008 namespace Impala
00009 {
00010 namespace Core
00011 {
00012 namespace Matrix
00013 {
00014
00015
00025 template<class ArrayT>
00026 inline ArrayT*
00027 MatCovariance(ArrayT* m, ArrayT* meanOut = 0)
00028 {
00029 typedef typename ArrayT::ArithType ArithT;
00030 typedef typename ArrayT::StorType StorT;
00031
00032 int nr = MatNrRow(m);
00033 int nc = MatNrCol(m);
00034 ArrayT* cov = MatCreate<ArrayT>(nc, nc);
00035 MatSet(cov, 0);
00036 ArrayT* mean = VecCreate<ArrayT>(nc) ;
00037 MatSet(mean, 0);
00038
00039 for (int k=0; k<nr; k++)
00040 {
00041 StorT* meanPtr = VecE(mean, 0);
00042 StorT* mkPtr = MatE(m, k, 0);
00043 for (int i=0; i<nc; i++)
00044 {
00045 ArithT mkiVal = mkPtr[i];
00046 meanPtr[i] += mkiVal;
00047 StorT* coviPtr = MatE(cov, i, 0);
00048 for (int j=i; j<nc; j++)
00049 {
00050 coviPtr[j] += mkiVal * mkPtr[j];
00051 }
00052 }
00053 }
00054
00055 MatDiv(mean, nr);
00056
00057 for (int i=0; i<nc; i++)
00058 {
00059 StorT* coviPtr = MatE(cov, i, 0);
00060 StorT* meanPtr = VecE(mean, 0);
00061 ArithT meani = meanPtr[i];
00062 for (int j=i; j<nc; j++)
00063 {
00064 ArithT res = coviPtr[j] / nr - meani * meanPtr[j];
00065 coviPtr[j] = res;
00066 *MatE(cov, j, i) = res;
00067 }
00068 }
00069
00070 if (meanOut != 0)
00071 MatSet(meanOut, mean);
00072 delete mean;
00073
00074 return cov;
00075 }
00076
00086 template<class ArrayT>
00087 inline ArrayT*
00088 MatCovarianceExact(ArrayT* m, ArrayT* meanOut = 0)
00089 {
00090 typedef typename ArrayT::ArithType ArithT;
00091 typedef typename ArrayT::StorType StorT;
00092
00093 int nr = MatNrRow(m);
00094 int nc = MatNrCol(m);
00095 ArrayT* cov = MatCreate<ArrayT>(nc, nc);
00096 MatSet(cov, 0);
00097 ArrayT* mean = VecCreate<ArrayT>(nc) ;
00098 MatSet(mean, 0);
00099
00100 int k;
00101 for ( k=0; k<nr; k++)
00102 {
00103 StorT* meanPtr = VecE(mean, 0);
00104 StorT* mkPtr = MatE(m, k, 0);
00105 for (int i=0; i<nc; i++)
00106 {
00107 ArithT mkiVal = mkPtr[i];
00108 meanPtr[i] += mkiVal;
00109
00110
00111
00112
00113
00114
00115 }
00116 }
00117
00118 MatDiv(mean, nr);
00119
00120 for ( k=0; k<nr; k++) {
00121 StorT* meanPtr = VecE(mean, 0);
00122 StorT* mkPtr = MatE(m, k, 0);
00123 for (int i=0; i<nc; i++)
00124 {
00125
00126 StorT* coviPtr = MatE(cov, i, 0);
00127 for (int j=i; j<nc; j++)
00128 {
00129 coviPtr[j] += (mkPtr[i] - meanPtr[i]) * (mkPtr[j] - meanPtr[j]);
00130 }
00131 }
00132 }
00133
00134 for (int i=0; i<nc; i++) {
00135 StorT* coviPtr = MatE(cov, i, 0);
00136
00137
00138 for (int j=i; j<nc; j++)
00139 {
00140 ArithT res = coviPtr[j] / (nr - 1);
00141 coviPtr[j] = res;
00142 *MatE(cov, j, i) = res;
00143 }
00144 }
00145
00146 if (meanOut != 0)
00147 MatSet(meanOut, mean);
00148 delete mean;
00149
00150 return cov;
00151 }
00152
00153 }
00154 }
00155 }
00156
00157 #endif