Go to the documentation of this file.00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033 #include "cmtkTypedArraySimilarity.h"
00034
00035 namespace
00036 cmtk
00037 {
00038
00041
00042
00043 TypedArraySimilarity::ReturnType
00044 TypedArraySimilarity::GetMutualInformation
00045 ( const std::vector<const TypedArray*>& data0,
00046 const std::vector<const TypedArray*>& data1,
00047 const bool normalized )
00048 {
00049 const size_t N = data0[0]->GetDataSize();
00050 const size_t dim0 = data0.size();
00051 const size_t dim1 = data1.size();
00052 const size_t dim = dim0 + dim1;
00053
00054 double* pts = Memory::AllocateArray<double>( N*dim );
00055
00056 Types::DataItem tmp;
00057
00058
00059 for ( size_t nidx = 0; nidx < N; ++nidx )
00060 {
00061 for ( size_t lidx = 0; lidx < dim0; ++lidx )
00062 {
00063 data0[lidx]->Get(tmp,nidx);
00064 pts[lidx * N + nidx] = tmp;
00065 }
00066 for ( size_t lidx = 0; lidx < dim1; ++lidx )
00067 {
00068 data1[lidx]->Get(tmp,nidx);
00069 pts[(dim0 + lidx) * N + nidx] = tmp;
00070 }
00071 }
00072
00073
00074
00075 std::vector<double> mean(dim,0.0);
00076
00077 for (size_t i=0; i<dim; i++)
00078 {
00079 for (size_t j=0; j<N; j++)
00080 {
00081 mean[i] += pts[i*N+j];
00082 }
00083 }
00084 for (size_t i=0; i<dim; i++)
00085 {
00086 mean[i] /= N;
00087 }
00088
00089 for (size_t i=0; i<dim; i++)
00090 {
00091 for (size_t j=0; j<N; j++)
00092 {
00093 pts[i*N+j] -= mean[i];
00094 }
00095 }
00096
00097
00098
00099 Matrix2D<Types::DataItem> cM( dim, dim );
00100
00101 double sum;
00102 size_t iN, jN;
00103
00104 for (size_t i=0; i<dim; i++)
00105 {
00106 for (size_t j=i; j<dim; j++)
00107 {
00108 sum = 0.0;
00109 iN = i*N;
00110 jN = j*N;
00111
00112 for (size_t k=0; k<N; k++)
00113 {
00114 sum += pts[iN+k]*pts[jN+k];
00115 }
00116 cM[i][j] = sum/N;
00117 cM[j][i] = cM[i][j];
00118 }
00119 }
00120 const double dt3 = MathUtil::CholeskyDeterminant(cM, dim);
00121
00122
00123
00124 Matrix2D<Types::DataItem> mcM0( dim0, dim0 );
00125
00126
00127 for (size_t i=0; i<dim0; i++)
00128 {
00129 for (size_t j=0; j<dim0; j++)
00130 {
00131 mcM0[i][j] = cM[i][j];
00132 }
00133 }
00134
00135 const double dt1 = MathUtil::CholeskyDeterminant(mcM0, dim0);
00136
00137
00138 Matrix2D<Types::DataItem> mcM1( dim1, dim1 );
00139
00140
00141 for (size_t i=0; i<dim1; i++)
00142 {
00143 for (size_t j=0; j<dim1; j++)
00144 {
00145 mcM1[i][j] = cM[i+dim0][j+dim0];
00146 }
00147 }
00148
00149 const double dt2 = MathUtil::CholeskyDeterminant(mcM1, dim1);
00150
00151 const double alpha = 1.41893853320467;
00152
00153 const double v1 = dim0*alpha + .5*log(dt1);
00154 const double v2 = dim1*alpha + .5*log(dt2);
00155 const double v3 = dim *alpha + .5*log(dt3);
00156
00157 if ( normalized )
00158 return (v1+v2)/v3;
00159 else
00160 return v1+v2-v3;
00161 }
00162
00163 }