//
// C++ Implementation: TestFTransform
//
// Description:
//
//
// Author: Michael Koch <Koch.Michael@uni-jena.de>, (C) 2009
//
// Copyright: See COPYING file that comes with this distribution
//
/**
 * @file TestFTransform.cpp
 * @brief TestFTransform
 * @author Michael Koch
 * @date Di Aug 4 2009
 */

#include "TestFTransform.h"
#include <string>

#include "core/basics/cppunitex.h"
#include "core/basics/numerictools.h"
#include "core/vector/Distance.h"

#include "vislearning/math/ftransform/FTransform.h"
#include "vislearning/math/ftransform/PCA.h"

using namespace std;
using namespace NICE;
using namespace OBJREC;

CPPUNIT_TEST_SUITE_REGISTRATION ( TestFTransform );

void TestFTransform::setUp()
{
}

void TestFTransform::tearDown()
{
}

void TestFTransform::TestFTransformComputation()
{
  uint samplecount = 13; //samples
  uint sampledimension = 4; //sample dimension

  NICE::Matrix T ( samplecount, sampledimension );
  NICE::Matrix goalBasis ( sampledimension, sampledimension );
  NICE::Matrix goalFeats ( samplecount, sampledimension );

  //trivial test
  CPPUNIT_ASSERT_EQUAL ( samplecount, ( uint ) T.rows() );
  CPPUNIT_ASSERT_EQUAL ( sampledimension, ( uint ) T.cols() );

  ifstream is ( "./pca.data" );
  for ( uint i = 0 ; i < T.rows() ; i++ )
    for ( uint j = 0 ; j < T.cols() ; j++ )
      is >> T ( i, j );

  for ( uint i = 0 ; i < goalBasis.rows() ; i++ )
    for ( uint j = 0 ; j < goalBasis.cols() ; j++ )
      is >> goalBasis ( i, j );

  for ( uint i = 0 ; i < goalFeats.rows() ; i++ )
    for ( uint j = 0 ; j < goalFeats.cols() ; j++ )
      is >> goalFeats ( i, j );
  is.close();


  PCA *ftransform = new PCA ( sampledimension );

  bool mode = false;
  ftransform->calculateBasis ( T, sampledimension, mode ); //fastes available method
  NICE::Matrix basis, featurematrix;
  featurematrix = T;
  //cout << featurematrix << endl;
  basis = ftransform->getBasis();
  //cout<<basis<<endl;
  //orthogonality test

  for ( uint i = 0 ; i < goalBasis.rows() ; i++ )
    for ( uint j = 0 ; j < goalBasis.cols() ; j++ )
    {
      CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN ( abs ( goalBasis ( i, j ) ), abs ( basis ( i, j ) ), 1e-4 );
    }
  //transform features and test

  for ( uint k = 0;k < T.rows();k++ )
  {
    NICE::Vector feature, feature_transformed;
    feature = T.getRow ( k );
    feature_transformed = ftransform-> getFeatureVector ( feature, false );
    for ( uint d = 0;d < feature_transformed.size();d++ )
    {
      featurematrix ( k, d ) = feature_transformed[d];
    }
  }

  for ( uint i = 0 ; i < goalFeats.rows() ; i++ )
    for ( uint j = 0 ; j < goalFeats.cols() ; j++ )
    {
      CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN ( abs ( goalFeats ( i, j ) ), abs ( featurematrix ( i, j ) ), 1e-2 );
    }
}