00001 #ifndef UMatrix_H
00002 #define UMatrix_H
00003
00004 #include "defs.h"
00005 #include "Mapcode.h"
00006
00007 class UMatrix {
00008 public:
00009 TMatrix umatrix( const Mapcode* mapcode, int mode, bool normalized );
00010
00011
00012 private:
00013 Value_Type calc_min( TVecValue a );
00014
00015 Value_Type calc_max( TVecValue a );
00016
00017 Value_Type calc_median( TVecValue a );
00018
00019 Value_Type calc_mean( TVecValue a );
00020
00021 Value_Type calc_uvalue( TVecValue a, int mode );
00022
00023 TMatrix hexa_umatrix( const Mapcode * mapcode, int mode, bool normalized );
00024
00025 TMatrix rect_umatrix( const Mapcode * mapcode, int mode, bool normalized );
00026
00027 TMatrix normalizeU( TMatrix U, int uy, int ux );
00028
00029 };
00030
00031 TMatrix
00032 UMatrix::normalizeU( TMatrix U, int uy, int ux ) {
00033 int i, j;
00034 Value_Type min, max;
00035 min = U[1][1]; max = U[1][1];
00036 for (j=1; j<=uy; j++ ) for (i=1; i<= ux; i++)
00037 if ( U[j][i] < min )
00038 min = U[j][i];
00039 else if ( U[j][i] > max )
00040 max = U[j][i];
00041 for (j=1; j<=uy; j++ ) for (i=1; i<= ux; i++)
00042 U[j][i] = ( U[j][i] - min )/max;
00043
00044 return U;
00045 };
00046
00047 Value_Type
00048 UMatrix::calc_min( TVecValue a ) {
00049 if (a.empty())
00050 return 0;
00051 sort( a.begin(), a.end() );
00052 return a[0];
00053 }
00054
00055 Value_Type
00056 UMatrix::calc_max( TVecValue a ) {
00057 if (a.empty())
00058 return 0;
00059 sort( a.begin(), a.end() );
00060 return a[a.size()-1];
00061 }
00062
00063 Value_Type
00064 UMatrix::calc_median( TVecValue a ) {
00065 if (a.empty())
00066 return 0;
00067 sort( a.begin(), a.end() );
00068 if ( fmod( a.size(), 2 ) == 0 )
00069 return (a[a.size()/2] + a[(a.size()+1)/2])/2;
00070 else
00071 return a[(a.size()+1)/2];
00072 }
00073
00074 Value_Type
00075 UMatrix::calc_mean( TVecValue a ) {
00076 if (a.empty())
00077 return 0;
00078
00079 Value_Type sum = 0.0;
00080 TVecValue::iterator i;
00081 for (i= a.begin(); i< a.end(); i++ ) sum += *i;
00082 return (sum/a.size());
00083 }
00084
00085 Value_Type
00086 UMatrix::calc_uvalue( TVecValue a, int mode ) {
00087 switch(mode) {
00088 case MEDIAN_VALUE : return calc_median( a ); break;
00089 case MIN_VALUE : return calc_min( a ); break;
00090 case MAX_VALUE : return calc_max( a ); break;
00091 case MEAN_VALUE : return calc_mean( a ); break;
00092 default : return 0;
00093 }
00094 };
00095
00096 TMatrix
00097 UMatrix::hexa_umatrix( const Mapcode * mapcode, int mode, bool normalized ) {
00098 int i, j;
00099 TVecValue a;
00100 int y = mapcode->getDimensions( 0 );
00101 int x = mapcode->getDimensions( 1 );
00102 int ux = 2*x - 1;
00103 int uy = 2*y - 1;
00104
00105 int d = mapcode->getNumVar();
00106 TMatrix codebook = mapcode->getCodebook();
00107 int ma;
00108 TMatrix umatrix;
00109
00110 if ( (ux == 1) || ( uy == 1 ) ) {
00111 ma = ux; if ( uy > ma ) ma = uy;
00112 umatrix = create_matrix( 1, 1, 1, ma );
00113 }
00114 else
00115 umatrix = create_matrix( 1, uy, 1, ux );
00116
00117
00118 for (i=1; i<= uy; i++) for (j=1; j<= ux; j++)
00119 umatrix[i][j] = 0.0;
00120
00121
00122 for (j=1; j<=y; j++)
00123 for (i=1; i<=x; i++) {
00124 if ( i < x )
00125 umatrix[2*j-1][2*i] = dist(codebook[(i-1)*y+j], codebook[(i)*y+j], d);
00126 if ( j < y ) {
00127 umatrix[2*j][2*i-1] = dist(codebook[(i-1)*y+j], codebook[(i-1)*y+j+1], d);
00128 if ((fmod(j,2)==0) && (i < x))
00129 umatrix[2*j][2*i] = dist(codebook[(i-1)*y+j], codebook[(i)*y+j+1], d);
00130 else if ( (fmod(j,2) == 1) && ( i > 1 ) )
00131 umatrix[2*j][2*i-2] = dist(codebook[(i-1)*y+j], codebook[(i-2)*y+j+1], d);
00132 }
00133 }
00134
00135 a.clear();
00136 if ( (ux == 1) || ( uy == 1 ) ) {
00137 ma = ux; if ( uy > ma ) ma = uy;
00138 for (i=1; i<= ma; i+=2 )
00139 if ( (i>1)&& (i<ma )) {
00140 a.push_back( umatrix[1][i-1] );
00141 a.push_back( umatrix[1][i+1] );
00142 umatrix[1][i] = calc_uvalue( a, mode );
00143 }
00144 else if (i==1)
00145 umatrix[1][i] = umatrix[1][i+1];
00146 else
00147 umatrix[1][i] = umatrix[1][i-1];
00148 }
00149 else {
00150 for (j=1; j<= uy; j+=2)
00151 for (i=1; i<= ux; i+=2 ) {
00152 a.clear();
00153 if ((i>1)&&(j>1)&&(i<ux)&&(j<uy)) {
00154 a.push_back( umatrix[j][i-1] );
00155 a.push_back( umatrix[j][i+1] );
00156 a.push_back( umatrix[j-1][i] );
00157 a.push_back( umatrix[j+1][i] );
00158 if ( fmod(j-1,4)==0 ) {
00159 a.push_back( umatrix[j-1][i-1] );
00160 a.push_back( umatrix[j+1][i-1] );
00161 }
00162 else {
00163 a.push_back( umatrix[j-1][i+1] );
00164 a.push_back( umatrix[j+1][i+1] );
00165 }
00166 }
00167 else if ((j==1)&&(i>1)&&(i<ux)) {
00168 a.push_back( umatrix[j][i-1] );
00169 a.push_back( umatrix[j][i+1] );
00170 a.push_back( umatrix[j+1][i-1] );
00171 a.push_back( umatrix[j+1][i] );
00172 }
00173 else if ((j==uy)&&(i>1)&&(i<ux)) {
00174 a.push_back( umatrix[j][i-1] );
00175 a.push_back( umatrix[j][i+1] );
00176 a.push_back( umatrix[j-1][i] );
00177 if (fmod(j-1,4)==0)
00178 a.push_back( umatrix[j-1][i-1] );
00179 else
00180 a.push_back( umatrix[j-1][i+1] );
00181 }
00182 else if ((i==1)&&(j>1)&&(j<uy)) {
00183 a.push_back( umatrix[j][i+1] );
00184 a.push_back( umatrix[j-1][i] );
00185 a.push_back( umatrix[j+1][i] );
00186 if ( fmod(j-1,4) != 0 ) {
00187 a.push_back( umatrix[j-1][i+1] );
00188 a.push_back( umatrix[j+1][i+1] );
00189 }
00190 }
00191 else if ((i==ux)&&(j>1)&&(j<uy)) {
00192 a.push_back( umatrix[j][i-1] );
00193 a.push_back( umatrix[j-1][i] );
00194 a.push_back( umatrix[j+1][i] );
00195 if (fmod(j-1,4) == 0 ) {
00196 a.push_back( umatrix[j-1][i-1] );
00197 a.push_back( umatrix[j+1][i-1] );
00198 }
00199 }
00200 else if ((i==1)&&(j==1)) {
00201 a.push_back( umatrix[j][i+1] );
00202 a.push_back( umatrix[j+1][i] );
00203 }
00204 else if ((i==ux)&&(j==1)) {
00205 a.push_back( umatrix[j][i-1] );
00206 a.push_back( umatrix[j+1][i-1] );
00207 a.push_back( umatrix[j+1][i] );
00208 }
00209 else if ((i==1)&&(j==uy)) {
00210 a.push_back( umatrix[j][i+1] );
00211 a.push_back( umatrix[j-1][i] );
00212 if ( fmod(j-1,4) != 0 )
00213 a.push_back( umatrix[j-1][i+1] );
00214 }
00215 else if ((i==ux)&&(j==uy)) {
00216 a.push_back( umatrix[j][i-1] );
00217 a.push_back( umatrix[j-1][i] );
00218 if ( fmod(j-1,4) == 0 )
00219 a.push_back( umatrix[j-1][i-1] );
00220 }
00221
00222 umatrix[j][i] = calc_uvalue( a, mode );
00223
00224 }
00225
00226 }
00227
00228 return umatrix;
00229 }
00230
00231 TMatrix
00232 UMatrix::rect_umatrix( const Mapcode * mapcode, int mode, bool normalized ) {
00233 int i, j;
00234 TVecValue a;
00235 int y = mapcode->getDimensions( 0 );
00236 int x = mapcode->getDimensions( 1 );
00237 int ux = 2*x - 1;
00238 int uy = 2*y - 1;
00239
00240 int d = mapcode->getNumVar();
00241
00242 int ma;
00243 TMatrix codebook = mapcode->getCodebook();
00244 TMatrix umatrix;
00245
00246 if ( (ux == 1) || ( uy == 1 ) ) {
00247 ma = ux; if ( uy > ma ) ma = uy;
00248 umatrix = create_matrix( 1, 1, 1, ma );
00249 }
00250 else
00251 umatrix = create_matrix( 1, uy, 1, ux );
00252
00253
00254 for (i=1; i<= uy; i++) for (j=1; j<= ux; j++) umatrix[i][j] = 0.0;
00255
00256 for (j=1; j<=y; j++)
00257 for (i=1; i<=x; i++ ) {
00258 if (i< x )
00259 umatrix[2*j-1][2*i] = dist(codebook[(i-1)*y+j], codebook[(i)*y+j], d);
00260 if ( j < y )
00261 umatrix[2*j][2*i-1] = dist(codebook[(i-1)*y+j], codebook[(i-1)*y+j+1], d);
00262 if ((j<y) && (i<x))
00263 umatrix[2*j][2*i] = (dist(codebook[(i-1)*y+j], codebook[(i)*y+j+1], d) + dist(codebook[(i-1)*y+j+1], codebook[(i)*y+j], d))/(2*sqrt(2));
00264 }
00265
00266 if ( (ux == 1) || ( uy == 1 ) ) {
00267 ma = ux; if ( uy > ma ) ma = uy;
00268 for (i=1; i<= ma; i+=2 )
00269 if ( (i>1)&& (i<ma )) {
00270 a.push_back( umatrix[1][i-1] );
00271 a.push_back( umatrix[1][i+1] );
00272 umatrix[1][i] = calc_uvalue( a, mode );
00273 }
00274 else if (i==1)
00275 umatrix[1][i] = umatrix[1][i+1];
00276 else
00277 umatrix[1][i] = umatrix[1][i-1];
00278 }
00279 else {
00280 for (j=1; j<= uy; j+=2)
00281 for (i=1; i<= ux; i+=2 ) {
00282 if ((i>1)&&(j>1)&&(i<ux)&&(j<uy)) {
00283 a.push_back( umatrix[j][i-1] );
00284 a.push_back( umatrix[j][i+1] );
00285 a.push_back( umatrix[j-1][i] );
00286 a.push_back( umatrix[j+1][i] );
00287 }
00288 else if ((j==1)&&(i>1)&&(i<ux)) {
00289 a.push_back( umatrix[j][i-1] );
00290 a.push_back( umatrix[j][i+1] );
00291 a.push_back( umatrix[j+1][i] );
00292 }
00293 else if ((j==uy)&&(i>1)&&(i<ux)) {
00294 a.push_back( umatrix[j][i-1] );
00295 a.push_back( umatrix[j][i+1] );
00296 a.push_back( umatrix[j-1][i] );
00297 }
00298 else if ((i==1)&&(j>1)&&(j<uy)) {
00299 a.push_back( umatrix[j][i+1] );
00300 a.push_back( umatrix[j-1][i] );
00301 a.push_back( umatrix[j+1][i] );
00302 }
00303 else if ((i==ux)&&(j>1)&&(j<uy)) {
00304 a.push_back( umatrix[j][i-1] );
00305 a.push_back( umatrix[j-1][i] );
00306 a.push_back( umatrix[j+1][i] );
00307 }
00308 else if ((i==1)&&(j==1)) {
00309 a.push_back( umatrix[j][i+1] );
00310 a.push_back( umatrix[j+1][i] );
00311 }
00312 else if ((i==ux)&&(j==1)) {
00313 a.push_back( umatrix[j][i-1] );
00314 a.push_back( umatrix[j+1][i] );
00315 }
00316 else if ((i==1)&&(j==uy)) {
00317 a.push_back( umatrix[j][i+1] );
00318 a.push_back( umatrix[j-1][i] );
00319 }
00320 else if ((i==ux)&&(j==uy)) {
00321 a.push_back( umatrix[j][i-1] );
00322 a.push_back( umatrix[j-1][i] );
00323 }
00324 umatrix[j][i] = calc_uvalue( a, mode );
00325 }
00326 }
00327
00328 if ( normalized )
00329 return normalizeU( umatrix, uy, ux );
00330 else
00331 return umatrix;
00332 }
00333
00334 TMatrix
00335 UMatrix::umatrix( const Mapcode* mapcode, int mode, bool normalized ) {
00336 switch( mapcode->getLattice() ) {
00337 case RECT : return rect_umatrix( mapcode, mode, normalized ); break;
00338 case HEXA : return hexa_umatrix( mapcode, mode, normalized ); break;
00339 default : return 0;
00340 }
00341 }
00342
00343 #endif