9 #include "PrincipalComponentAnalysis.h" 
   10 #include "jama/jama_eig.h" 
   11 #include "jama/jama_lu.h" 
   17   PrincipalComponentAnalysis::PrincipalComponentAnalysis(
const int n) {
 
   20     p_statistics.resize(n * n);
 
   21     for(
int i = 0; i < n; i++) {
 
   22       for(
int j = 0; j <= i; j++) {
 
   24         p_statistics[n*j+i] = p_statistics[n*i+j];
 
   28     p_hasTransform = 
false;
 
   32   PrincipalComponentAnalysis::PrincipalComponentAnalysis(TNT::Array2D<double> transform) {
 
   33     if(transform.dim1() != transform.dim2()) {
 
   34       std::string m = 
"Illegal transform matrix";
 
   35       throw IException(IException::Programmer, m, _FILEINFO_);
 
   38     p_dimensions = transform.dim1();
 
   39     p_transform = transform;
 
   42     p_hasTransform = 
true;
 
   48   void PrincipalComponentAnalysis::AddData(
const double *data, 
const unsigned int count) {
 
   52       std::string m = 
"Cannot add data to a PCA that has a defined transform matrix";
 
   53       throw IException(IException::Programmer, m, _FILEINFO_);
 
   57     for(
int i = 0; i < p_dimensions; i++) {
 
   58       for(
int j = 0; j <= i; j++) {
 
   59         p_statistics[p_dimensions*i+j]->AddData(&data[count*i], &data[count*j], count);
 
   65   void PrincipalComponentAnalysis::ComputeTransform() {
 
   67       std::string m = 
"This PCA already has a computed transform";
 
   68       throw IException(IException::Programmer, m, _FILEINFO_);
 
   71     TNT::Array2D<double> C(p_dimensions, p_dimensions);
 
   72     for(
int i = 0; i < p_dimensions; i++) {
 
   73       for(
int j = 0; j < p_dimensions; j++) {
 
   74         C[i][j] = (p_statistics[p_dimensions*i+j])->Correlation();
 
   78     JAMA::Eigenvalue<double> 
E(C);
 
   79     TNT::Array2D<double> D, V;
 
   83     p_transform = TNT::Array2D<double>(V.dim1(), V.dim2());
 
   89     for(
int i = 0; i < V.dim1(); i++) {
 
   90       for(
int j = 0; j < V.dim2(); j++) {
 
   91         p_transform[i][j] = V[i][V.dim2()-j-1];
 
   97     p_hasTransform = 
true;
 
  101   void PrincipalComponentAnalysis::ComputeInverse() {
 
  102     TNT::Array2D<double> id(p_transform.dim1(), p_transform.dim2(), 0.0);
 
  103     for(
int i = 0; i < p_transform.dim1(); i++) 
id[i][i] = 1;
 
  105     JAMA::LU<double> lu(p_transform);
 
  106     if(lu.det() == 0.0) {
 
  107       std::string m = 
"Cannot take the inverse of the transform matrix";
 
  108       throw IException(IException::Programmer, m, _FILEINFO_);
 
  111     p_inverse = lu.solve(
id);
 
  115   TNT::Array2D<double> PrincipalComponentAnalysis::Transform(TNT::Array2D<double> data) {
 
  116     if(data.dim1() != 1 || data.dim2() != p_dimensions) {
 
  117       QString m = 
"Transform input must be of dimension 1 x " +  QString::number(p_dimensions);
 
  118       throw IException(IException::Programmer, m, _FILEINFO_);
 
  122     return TNT::matmult(data, p_transform);
 
  126   TNT::Array2D<double> PrincipalComponentAnalysis::Inverse(TNT::Array2D<double> data) {
 
  127     if(data.dim1() != 1 || data.dim2() != p_dimensions) {
 
  128       QString m = 
"Transform input must be of dimension 1 x " +  QString::number(p_dimensions);
 
  129       throw IException(IException::Programmer, m, _FILEINFO_);
 
  133     return TNT::matmult(data, p_inverse);