Commit fde49f246b2dbed746bddfad3212797d1697d511

Authored by David Mayerich
1 parent 89676102

integrated Rupali's changes - replaced OpenCV matrix math with LAPACK

Showing 1 changed file with 67 additions and 25 deletions   Show diff stats
src/main.cu
... ... @@ -50,6 +50,43 @@ typedef struct {
50 50 }gnome;
51 51 gnome gnom;
52 52  
  53 +//computing matrix determinant using LU decomposition
  54 +template<typename T>
  55 +T mtxdeterminant(T* M, size_t r, size_t c) {
  56 + //----DETERMINANT using LU decomposition using LAPACK
  57 + /* DGETRF computes an LU factorization of a general M-by-N matrix A using partial pivoting with row interchanges.
  58 + The factorization has the form
  59 + A = P * L * U
  60 + where P is a permutation matrix, L is lower triangular with unit diagonal elements (lower trapezoidal if m > n), and U is upper triangular (upper trapezoidal if m < n).*/
  61 + int* ipiv = (int*)malloc(sizeof(int) * r);
  62 + memset(ipiv, 0, r * sizeof(int));
  63 + LAPACKE_sgetrf(LAPACK_COL_MAJOR, (int)r, (int)c, M, (int)r, ipiv);
  64 +
  65 + //determinant of U
  66 + T product = 1;
  67 + for (size_t i = 0; i < r; i++) {
  68 + for (size_t j = 0; j < r; j++) {
  69 + if (i == j) {
  70 + product = product * M[i * r + j];
  71 + }
  72 + }
  73 + }
  74 +
  75 + //determinant of P
  76 + int j;
  77 + double detp = 1.;
  78 + for (j = 0; j < r; j++) {
  79 + if (j + 1 != ipiv[j]) {
  80 + // j+1 : following feedback of ead : ipiv is from Fortran, hence starts at 1.
  81 + // hey ! This is a transpose !
  82 + detp = -detp;
  83 + }
  84 + }
  85 + T detSw = product * detp * 1; //det(U)*det(P)*det(L)
  86 + if (ipiv != NULL) std::free(ipiv);
  87 + return detSw;
  88 +
  89 +}
53 90  
54 91 void gpuComputeEignS( size_t g, size_t fea){
55 92 //eigen value computation will return r = (nC-1) eigen vectors so new projected data will have dimension of r rather than f
... ... @@ -87,7 +124,7 @@ void gpuComputeEignS( size_t g, size_t fea){
87 124 int *IPIV = (int*) malloc(sizeof(int) * f);
88 125 //computing inverse of matrix Sw
89 126 memset(IPIV, 0, f * sizeof(int));
90   - LAPACKE_sgetrf(LAPACK_COL_MAJOR, (int)f, (int)f, gSw_a, (int)f, IPIV);
  127 + LAPACKE_sgetrf(LAPACK_COL_MAJOR, (int)f, (int)f, gSw_a, (int)f, IPIV);
91 128 // DGETRI computes the inverse of a matrix using the LU factorization computed by DGETRF.
92 129 LAPACKE_sgetri(LAPACK_COL_MAJOR, (int)f, gSw_a, (int)f, IPIV);
93 130  
... ... @@ -146,23 +183,22 @@ void gpuComputeEignS( size_t g, size_t fea){
146 183 mtxMul(tempgSw, &gnom.lda[g * r * f], &gnom.Sw[g * f * f], r, f, f,f);
147 184 float* nSw = (float*)calloc(r * r, sizeof(float));
148 185 mtxMultranspose(nSw, tempgSw, &gnom.lda[g * r * f], r, f, r, f);
149   - if(debug){
150   - std::cout<<"From Eigen function: projected Sb sn Sw"<<std::endl;
  186 +
  187 + //determinant of Sb and Sw
  188 + float detSw = mtxdeterminant(nSw, r, r);
  189 + float detSb = mtxdeterminant(nSb, r, r);
  190 +
  191 + if (debug) {
  192 + std::cout << "From Eigen function: projected Sb sn Sw" << std::endl;
151 193 displayS(nSb, r); //display Sb
152 194 displayS(nSw, r); //display Sw
153   - std::cout<<std::endl;
  195 + std::cout << std::endl;
  196 + std::cout <<"det(Sb)= "<< detSb<< std::endl;
  197 + std::cout << "det(Sw)= " << detSw << std::endl;
154 198 }
155 199  
156   - ///DETERMINANT CURRENTLY REQUIRES OPENCV
157   - std::cout<<"ERROR: This code requires a fix to remove an OpenCV dependence."<<std::endl;
158   - mtxOutputFile("newSw.csv", nSw, r, r);
159   - exit(1);
160   - //FIX BY REPLACING THE FOLLOWING THREE LINES OF CODE USING LAPACK
161   - //cv::Mat newSw = cv::Mat((int)r, (int)r, CV_32FC1, nSw); //within scatter of gnome g in the population
162   - //cv::Mat newSb = cv::Mat((int)r, (int)r, CV_32FC1, nSb); //within scatter of gnome g in the population
163   -
164 200 //fisher's ratio from ratio of projected sb and sw
165   - float fisherRatio = 0;// = cv::determinant(newSb) /cv::determinant(newSw);
  201 + float fisherRatio = detSb /detSw;
166 202 gnom.S[g] = 1/fisherRatio;
167 203 if (debug) {
168 204 std::cout<<"Score["<<g<<"]: "<< gnom.S[g]<<std::endl;
... ... @@ -172,6 +208,7 @@ void gpuComputeEignS( size_t g, size_t fea){
172 208 std::cout << ga.P[ga.f * g + i] << ", ";
173 209 std::cout << std::endl;
174 210 }
  211 +
175 212  
176 213  
177 214 if(IPIV!= NULL) std::free(IPIV);
... ... @@ -430,27 +467,30 @@ int main(int argc, char* argv[]){
430 467  
431 468  
432 469 //fitness values of best gnome is
433   - csv<<"best gnome's fitness value is "<<best_S[ga.gnrtn-1]<<std::endl; //output fitness value of best gnome in last generation
434   - //output gnome i.e. band index of selected featurs
  470 + csv<<"fitness value for best gnome: "<<best_S[ga.gnrtn-1]<<std::endl; //output fitness value of best gnome in last generation
  471 + /*//output gnome i.e. band index of selected featurs
435 472 csv<<(bestgnome.at(0)); //output feature subset
436 473 for(size_t i = 1; i < ga.f; i++)
437 474 csv<<","<<(bestgnome.at(i));
438   - csv<<std::endl;
  475 + csv<<std::endl;*/
439 476  
440   - //output LDA basis of size r X f, r is nC - 1 as LDA projection is rank limited by number of classes - 1
441   - for (size_t i = 0; i < nC-1; i++){
442   - csv<<lda[ldaindx + i * ga.f ];
443   - for (size_t j = 1; j < ga.f; j++){
444   - csv<<","<<lda[ldaindx + i * ga.f +j];
445   - }
446   - csv << std::endl;
447   - }
448 477 //output actual wavelenths corresponding to those band indices
  478 + csv << "selected wavenumbers:"<<std::endl;
449 479 csv << (wavelengths[bestgnome.at(0)]);
450 480 for (size_t i = 1; i < ga.f; i++)
451   - csv << "," << (wavelengths[bestgnome.at(i)]);
  481 + csv << ", " << (wavelengths[bestgnome.at(i)]);
452 482 csv << std::endl;
453 483  
  484 + //output LDA basis of size r X f, r is nC - 1 as LDA projection is rank limited by number of classes - 1
  485 + csv << "LDA basis:" << std::endl;
  486 + for (size_t i = 0; i < nC - 1; i++) {
  487 + csv << lda[ldaindx + i * ga.f];
  488 + for (size_t j = 1; j < ga.f; j++) {
  489 + csv << ", " << lda[ldaindx + i * ga.f + j];
  490 + }
  491 + csv << std::endl;
  492 + }
  493 +
454 494  
455 495 if (args["trim"].is_set()) {
456 496 csv << "trim info" << std::endl;
... ... @@ -489,6 +529,8 @@ int main(int argc, char* argv[]){
489 529 ////output actual wavelenths corresponding to those trim indices
490 530 ////these wavenumber are grouped in pairs, check each pair, if duplicated numbers are there in pair delete one and keep other as band to trim, if 2nd wavnumber is smaller than 1st in a pair ignore that pair
491 531 ////e.g [1, 228, 230, 230, 232, 350,352, 351, 353, 1200] pairas [1(start)-228,230-230, 232-350, 352-351, 353-1200(end)], trimming wavenumbers are [1-228, 230, 233-350, 353-1200]
  532 +
  533 +
492 534 csv << (wavelengths[finaltrim_ind.at(0)]);
493 535 for (size_t i = 1; i < ga.f * + 2 ; i++)
494 536 csv << "," << (wavelengths[finaltrim_ind.at(i)]);
... ...