//
// 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 = 16; //samples
    uint sampledimension = 8; //sample dimension
    bool init_random = true;

    NICE::Matrix T(samplecount, sampledimension);

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


    T.set(0.0);
    if (init_random)
        srand48(time(NULL));

    // generate random matrix
    for (uint i = 0 ; i < T.rows() ; i++)
        for (uint j = 0 ; j < T.cols() ; j++)
        {
            T(i, j) = drand48();
        }
//cout<<T<<endl;
    PCA *ftransform = new PCA(sampledimension);
#ifdef NICE_USELIB_ICE
#ifdef NICE_USELIB_TRLAN
	for (int mode = 0;mode <= 1;mode++)
    {
        ftransform->calculateBasis(T, sampledimension, mode); //fastes available method
        NICE::Matrix basis, featurematrix;
        featurematrix = T;
        basis = ftransform->getBasis();
        //cout<<basis<<endl;
        //orthogonality test
        for (int k = 0;k < basis.rows() - 1;k++)
        {
            NICE::Vector b1, b2;
            b1 = basis.getRow(k);
            b2 = basis.getRow(k + 1);
            double sp = b1.scalarProduct(b2);
            CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, sp, 1e-4);
        }
        //transform features and test

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

        //cout<<featurematrix<<endl;
        //Covariance Test
        NICE::Matrix covariance;
        covariance = featurematrix.transpose() * featurematrix;
        ////cout<<covariance<<endl;
        for (uint i = 0;i < covariance.rows();i++)
        {
            for (uint j = 0;j < covariance.cols();j++)
            {
                if (i == j)
                {
                    CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN((double)samplecount, covariance(i, j), 1e-4);
                }
                else
                {
                    CPPUNIT_ASSERT_DOUBLES_EQUAL_NOT_NAN(0.0, covariance(i, j), 1e-4);
                }
            }
        }
    }
#endif
#endif

}