// file: $USFS/class/image_analysis/v3.0/imaga_he_06.cc
//

// system include files
//
#include <string.h>

// isip include files
//
#include "image_analysis.h"
#include <integral_constants.h>

#define SWAP(a, b) { float_8 temp = (a); (a) = (b); (b) = temp;}

// method: pca_inverse_cc
//
// arguments:
//  float_8** tmp_data_a: (input) data whose inverse has to be found
//
// return: a logical_1 value indicating status
//
// this method computes an sbe from the weighted distance measure
//
logical_1 Image_analysis::pca_inverse_cc(float_8** tmp_data_a) {

  // declare local variables
  //
  int* indxc;
  int* indxr;
  int* ipiv;

  int i, j, k, l ,ll;
  int icol = 0, irow = 0;
  float big, dum, pivinv;

  int_4 n = pca_t_values_read_d;

  // allocating the memory
  //
  indxc = new int[n];
  indxr = new int[n];
  ipiv = new int[n];

  memset((void*)indxc, (int)0, n);
  memset((void*)indxr, (int)0, n);
  memset((void*)ipiv, (int)0, n);
  
  for (j=0; j < n; j++) {
    ipiv[j] = 0;
  }
  
  for(i=0; i < n; i++) {
    big = 0.0;
    
    for (j=0; j < n; j++) {
      if (ipiv[j] != 1) {
	for (k=0; k < n; k++) {
	  if (ipiv[k] == 0) {
	    if (fabs(tmp_data_a[j][k]) >= big) {
	      big = fabs(tmp_data_a[j][k]);
	      irow = j;
	      icol = k;
	    }
	  }
	  else if (ipiv[k] > 1) {
	    fprintf(stdout, "GAUSSJ: Singular Matrix-1");
	    exit(1);
	  }
	}
      }
    }
    ++(ipiv[icol]);
    
    if (irow != icol) {
      for (l=0; l < n; l++) {
	SWAP(tmp_data_a[irow][l], tmp_data_a[icol][l]);
      }
    }
    
    indxr[i] = irow;
    indxc[i] = icol;
    
    if (tmp_data_a[icol][icol] == 0.0) {
      fprintf(stdout,"GAUSSJ: Singular Matrix-2");
      exit(2);
    }
    
    pivinv = 1.0 / tmp_data_a[icol][icol];
    tmp_data_a[icol][icol] = 1.0;
    
    for (l=0; l < n; l++) {
      tmp_data_a[icol][l] *= pivinv;
    }
    
    for (ll=0; ll < n; ll++) {
      if (ll != icol) {
	dum = tmp_data_a[ll][icol];
	tmp_data_a[ll][icol] = 0.0;
	for (l=0; l < n; l++) {
	  tmp_data_a[ll][l] -= tmp_data_a[icol][l]*dum;
	}
      }
    }
  }
  
  for (l=(n-1); l>=0; l--) {
    if (indxr[l] != indxc[l]) {
      for (k=0; k < n; k++) {
	SWAP(tmp_data_a[k][indxr[l]], tmp_data_a[k][indxc[l]]);
      }
    }
  }

  delete[] ipiv;
  delete[] indxr;
  delete[] indxc;
	
  // exit gracefully
  //
  return ISIP_TRUE;
}





