ECOCPAK v0.9
|
00001 // Copyright (C) 2011 the authors listed below 00002 // http://ecocpak.sourceforge.net 00003 // 00004 // Authors: 00005 // - Dimitrios Bouzas (bouzas at ieee dot org) 00006 // - Nikolaos Arvanitopoulos (niarvani at ieee dot org) 00007 // - Anastasios Tefas (tefas at aiia dot csd dot auth dot gr) 00008 // 00009 // This file is part of the ECOC PAK C++ library. It is 00010 // provided without any warranty of fitness for any purpose. 00011 // 00012 // You can redistribute this file and/or modify it under 00013 // the terms of the GNU Lesser General Public License (LGPL) 00014 // as published by the Free Software Foundation, either 00015 // version 3 of the License or (at your option) any later 00016 // version. 00017 // (see http://www.opensource.org/licenses for more info) 00018 00019 00022 00023 00024 00025 // --- General Auxuliary Functions --- // 00026 00027 00028 00042 bool 00043 contains 00044 ( 00045 const ucolvec& A, 00046 const u32 n, 00047 const u32 i 00048 ) 00049 { 00050 for(u32 j = 0; j < n; j++) 00051 { 00052 if(A[j] == i) 00053 { 00054 return true; 00055 } 00056 00057 } 00058 00059 return false; 00060 } 00061 00062 00063 00078 ucolvec 00079 complement 00080 ( 00081 const ucolvec& A, 00082 const u32 sizeU 00083 ) 00084 { 00085 // allocate complement set 00086 ucolvec C = zeros<ucolvec>(sizeU - A.n_rows); 00087 00088 // allocate universal set 00089 ucolvec U = linspace<ucolvec>(0, sizeU - 1, sizeU); 00090 00091 u32 k = 0; 00092 for(u32 i = 0; i < sizeU; i++) 00093 { 00094 if(accu(A == U[i]) == 0) // no common indices 00095 { 00096 C[k] = U[i]; // update complementary set to A 00097 k++; 00098 } 00099 } 00100 00101 return C; 00102 } 00103 00104 00105 00122 vector<ClassData> 00123 create_class_vector 00124 ( 00125 const mat& samples, 00126 const icolvec& labels 00127 ) 00128 { 00129 // vector of ClassData objects that is to be returned 00130 vector<ClassData> cd; 00131 00132 // number of classes 00133 const u32 classes_n = max(labels); 00134 00135 vector<u32> classIndices[classes_n]; 00136 00137 const u32 n_rows = labels.n_rows; 00138 00139 // compute class indices of each sample 00140 for(u32 i = 0; i < n_rows; i++) 00141 { 00142 classIndices[labels[i] - 1].push_back(i); 00143 } 00144 00145 // for all classes 00146 for(u32 i = 0; i < classes_n; i++) 00147 { 00148 // temporary matrix that will hold the samples of class i + 1 00149 mat tmp = zeros< mat >(classIndices[i].size(), samples.n_cols); 00150 00151 // s denotes the number of samples of class i + 1 00152 const u32 s = classIndices[i].size(); 00153 00154 00155 for(u32 j = 0; j < s; j++ ) 00156 { 00157 // update temporary matrix with rows of initial samples matrix 00158 // that correspond to class i + 1 00159 tmp.row(j) = samples.row(classIndices[i].at(j)); 00160 } 00161 00162 // create ClassData object and push it back to the vector 00163 ClassData tmp_class(tmp, i + 1); 00164 cd.push_back(tmp_class); 00165 } 00166 00167 return cd; 00168 } 00169 00170 00171 00185 mat 00186 create_samples_matrix 00187 ( 00188 const vector<ClassData>& v 00189 ) 00190 { 00191 // matrix that will be created from the vector of ClassData objects 00192 mat samples; 00193 const u32 s = v.size(); 00194 00195 // for all ClassData objects 00196 for(u32 i = 0; i < s; i++) 00197 { 00198 // append the columns of each ClassData data matrix to the whole matrix 00199 samples = join_cols(samples, v[i].Data()); 00200 } 00201 00202 return samples; 00203 } 00204 00205 00206 00222 void 00223 create_samples_matrix 00224 ( 00225 const vector<ClassData>& v, 00226 mat& samples, 00227 icolvec& labels 00228 ) 00229 { 00230 const u32 s = v.size(); 00231 00232 // reset samples and labels in case they aren't empty 00233 samples.reset(); 00234 labels.reset(); 00235 00236 // for all ClassData objects 00237 for(u32 i = 0; i < s; i++) 00238 { 00239 // append the columns of each ClassData data matrix and 00240 // create label vector containing labels from 1 to s for the whole matrix 00241 samples = join_cols(samples, v[i].Data()); 00242 labels = join_cols(labels, (i + 1) * ones<icolvec>(v[i].Data().n_rows)); 00243 } 00244 00245 } 00246 00247 00248 00265 void 00266 create_samples_matrix 00267 ( 00268 const ClassData& first_class, 00269 const ClassData& second_class, 00270 mat& samples, 00271 icolvec& labels 00272 ) 00273 { 00274 // reset samples and labels in case they aren't empty 00275 samples.reset(); 00276 labels.reset(); 00277 00278 // create samples by joining samples of ClassData objects 00279 samples = join_cols(first_class.Data(), second_class.Data()); 00280 00281 // create labels that contain 1 and 2 for the two classes 00282 labels = join_cols(ones<icolvec>(second_class.Data().n_rows), 2 * ones<icolvec>(second_class.Data().n_rows)); 00283 } 00284 00285 00286 00306 void 00307 create_samples_matrix 00308 ( 00309 const vector<ClassData>& v, 00310 mat& samples, 00311 icolvec& labels, 00312 ucolvec& n_per_class 00313 ) 00314 { 00315 const u32 s = v.size(); 00316 00317 // reset samples and labels in case they aren't empt 00318 samples.reset(); 00319 labels.reset(); 00320 00321 n_per_class.set_size(s); 00322 00323 // for all ClassData objects 00324 for(u32 i = 0; i < s; i++) 00325 { 00326 // append columns of each ClassData data matrix 00327 samples = join_cols(samples, v[i].Data()); 00328 00329 // compute number of data samples per class 00330 n_per_class[i] = v[i].Data().n_rows; 00331 00332 // update the label vector 00333 labels = join_cols(labels, (i+1) * ones<icolvec>(v[i].Data().n_rows)); 00334 } 00335 00336 } 00337 00338 00339 00352 ClassData 00353 merge_classes_vector 00354 ( 00355 const vector<ClassData>& v 00356 ) 00357 { 00358 // matrix that will contain the whole data of all ClassData objects 00359 mat samples; 00360 00361 const u32 s = v.size(); 00362 00363 // for all ClassData objects 00364 for(u32 i = 0; i < s; i++) 00365 { 00366 // append data from each object 00367 samples = join_cols(samples, v[i].Data()); 00368 } 00369 00370 // create the new ClassData object with the whole data matrix 00371 ClassData c(samples, -2, false, -1); 00372 00373 return c; 00374 } 00375 00376 00377 00393 ClassData 00394 merge_selected_classes 00395 ( 00396 const vector<ClassData>& v, 00397 const ucolvec& s 00398 ) 00399 { 00400 const u32 bsSize = s.n_rows; 00401 00402 // matrix that will contain the whole data of all ClassData objects 00403 mat dat; 00404 00405 // for all ClassData object that belong to the subset of classes of the initial vector v 00406 for(u32 i = 0; i < bsSize; i++) 00407 { 00408 // append columns of data matrices that belong to the subset of ClassData objects 00409 dat = join_cols(dat, v[s[i]].Data()); 00410 } 00411 00412 // create a new ClassData object with the new data matrix 00413 ClassData c(dat, -2, false, -1); 00414 00415 return c; 00416 } 00417 00418 00419 00438 vector<ClassData> 00439 split_class 00440 ( 00441 const ClassData& c, 00442 const ucolvec& indices, 00443 const ucolvec& samples_per_cluster, 00444 const int are_valid 00445 ) 00446 { 00447 // vector of ClassData objects that will be returned 00448 vector< ClassData > v; 00449 00450 // number of sample attributes 00451 const u32 n_attr = c.Data().n_cols; 00452 00453 // allocate space for first class matrix 00454 mat tmp_mat_A = zeros<mat>(samples_per_cluster[0], n_attr); 00455 00456 // allocate space for second class matrix 00457 mat tmp_mat_B = zeros<mat>(samples_per_cluster[1], n_attr); 00458 00459 // auxuliary index counters 00460 u32 counter_a = 0; 00461 u32 counter_b = 0; 00462 00463 // number of samples to extract from initial class 00464 const u32 indices_n = indices.n_rows; 00465 00466 for(u32 i = 0; i < indices_n; i++) 00467 { 00468 if(indices[i] == 0) // first class 00469 { 00470 // update data matrix of first class 00471 tmp_mat_A.row(counter_a) = c.Data().row(i); 00472 00473 // increase number of elements in first class 00474 counter_a++; 00475 } 00476 else 00477 { 00478 // update data matrix of second class 00479 tmp_mat_B.row(counter_b) = c.Data().row(i); 00480 00481 // increase number of elements in second class 00482 counter_b++; 00483 } 00484 00485 } 00486 00487 // create new classes 00488 ClassData c1(tmp_mat_A, c.ClassLabel(), true, are_valid); 00489 ClassData c2(tmp_mat_B, c.ClassLabel(), true, are_valid); 00490 00491 // push newly created classes to output vector 00492 v.push_back(c1); 00493 v.push_back(c2); 00494 00495 return v; 00496 } 00497 00498 00499 00519 ucolvec 00520 complement_sffs 00521 ( 00522 const ucolvec& A, 00523 const u32 curSubsetSize 00524 ) 00525 { 00526 const u32 sizeU = A.n_rows; 00527 00528 // allocate complement set 00529 ucolvec C = zeros<ucolvec>(sizeU - curSubsetSize); 00530 00531 // allocate universal set 00532 ucolvec U = linspace<ucolvec>(0, sizeU - 1, sizeU); 00533 00534 u32 k = 0; 00535 for(u32 i = 0; i < sizeU; i++) 00536 { 00537 // if no element of A belongs to the universal set 00538 if(accu(A.rows(0, curSubsetSize - 1) == U[i]) == 0) 00539 { 00540 // the i-th element belongs to the complement of A 00541 C[k] = U[i]; 00542 k++; 00543 } 00544 } 00545 00546 return C; 00547 } 00548 00549 00550