/*
 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 *  Copyright (C) 2008-2008 - INRIA - Allan SIMON
 *
 *  This file must be used under the terms of the CeCILL.
 *  This source file is licensed as described in the file COPYING, which
 *  you should have received as part of this distribution.  The terms
 *  are also available at
 *  http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
 *
 */

#include <stdlib.h>
#include <stdio.h>
#include <assert.h>
#include <math.h>
#include "matrixTrace.h"

#define LINES 10
static void straceaTest ( void ) {
    
    float in[] = 
 {0.41574033396318555f,0.49111106572672725f,0.44963645050302148f,0.83262220909819007f,
 0.64995764615014195f,0.49560560984537005f,0.61533244187012315f,0.52116033947095275f,
 0.31538392649963498f,0.50222720531746745f,
0.15958226565271616f,0.34022171795368195f,0.96781380381435156f,0.74247795902192593f,
 0.23031901288777590f,0.18889334425330162f,0.89581834804266691f,0.45098419673740864f,
 0.34899875614792109f,0.05404338985681534f,
0.38831026805564761f,0.99661536002531648f,0.64890601998195052f,0.01946402387693524f,
 0.55043680546805263f,0.56412307033315301f,0.87217613449320197f,0.39612928451970220f,
 0.74138183100149035f,0.01639390224590898f,
0.94154607132077217f,0.02153958659619093f,0.25446669198572636f,0.80160319153219461f,
 0.30389970541000366f,0.85622101929038763f,0.83897679112851620f,0.72408697474747896f,
 0.97027219459414482f,0.60508118104189634f,
0.47229793528094888f,0.68768908223137259f,0.19239750178530812f,0.25545394374057651f,
 0.03710305178537965f,0.07947642868384719f,0.20409553544595838f,0.67240559635683894f,
 0.12765105674043298f,0.29538751533254981f,
0.85336526390165091f,0.00449241511523724f,0.68614923674613237f,0.26881096139550209f,
 0.17038810532540083f,0.61961987055838108f,0.31665382627397776f,0.23861460387706757f,
 0.38288621511310339f,0.64512947760522366f,
0.12077391659840941f,0.63978545414283872f,0.42314558057114482f,0.75584907690063119f,
 0.56986862560734153f,0.22410399885848165f,0.70068256510421634f,0.71248416090384126f,
 0.48824774986132979f,0.94497666554525495f,
0.89993809349834919f,0.5416147718206048f,0.67344415932893753f,0.43475896771997213f,
 0.00364112667739391f,0.85820947308093309f,0.20731051638722420f,0.32864938955754042f,
 0.51919496990740299f,0.5638650292530656f,
0.43849021615460515f,0.22476492030546069f,0.82706967229023576f,0.64259665226563811f,
 0.44915470527485013f,0.71145519940182567f,0.52225506165996194f,0.48377691349014640f,
 0.09068560274317861f,0.97863480402156711f,
0.89760566223412752f,0.73640052601695061f,0.93608058523386717f,0.69578680582344532f,
 0.05768106970936060f,0.80260276049375534f,0.94164209719747305f,0.76627670042216778f,
 0.68338975030928850f,0.93453497067093849f}
;
    
    float Result = 4.9177467138506472f ;
    
    float out = 0.0f ;
    
    out = stracea ( in , LINES ) ;
    
    assert(fabsf(out - Result) / fabsf( out )< 1e-07);
    
}

static void dtraceaTest ( void ) {
    
    double in[] = 
 {0.41574033396318555,0.49111106572672725,0.44963645050302148,0.83262220909819007,
 0.64995764615014195,0.49560560984537005,0.61533244187012315,0.52116033947095275,
 0.31538392649963498,0.50222720531746745,
0.15958226565271616,0.34022171795368195,0.96781380381435156,0.74247795902192593,
 0.23031901288777590,0.18889334425330162,0.89581834804266691,0.45098419673740864,
 0.34899875614792109,0.05404338985681534,
0.38831026805564761,0.99661536002531648,0.64890601998195052,0.01946402387693524,
 0.55043680546805263,0.56412307033315301,0.87217613449320197,0.39612928451970220,
 0.74138183100149035,0.01639390224590898,
0.94154607132077217,0.02153958659619093,0.25446669198572636,0.80160319153219461,
 0.30389970541000366,0.85622101929038763,0.83897679112851620,0.72408697474747896,
 0.97027219459414482,0.60508118104189634,
0.47229793528094888,0.68768908223137259,0.19239750178530812,0.25545394374057651,
 0.03710305178537965,0.07947642868384719,0.20409553544595838,0.67240559635683894,
 0.12765105674043298,0.29538751533254981,
0.85336526390165091,0.00449241511523724,0.68614923674613237,0.26881096139550209,
 0.17038810532540083,0.61961987055838108,0.31665382627397776,0.23861460387706757,
 0.38288621511310339,0.64512947760522366,
0.12077391659840941,0.63978545414283872,0.42314558057114482,0.75584907690063119,
 0.56986862560734153,0.22410399885848165,0.70068256510421634,0.71248416090384126,
 0.48824774986132979,0.94497666554525495,
0.89993809349834919,0.5416147718206048,0.67344415932893753,0.43475896771997213,
 0.00364112667739391,0.85820947308093309,0.20731051638722420,0.32864938955754042,
 0.51919496990740299,0.5638650292530656,
0.43849021615460515,0.22476492030546069,0.82706967229023576,0.64259665226563811,
 0.44915470527485013,0.71145519940182567,0.52225506165996194,0.48377691349014640,
 0.09068560274317861,0.97863480402156711,
0.89760566223412752,0.73640052601695061,0.93608058523386717,0.69578680582344532,
 0.05768106970936060,0.80260276049375534,0.94164209719747305,0.76627670042216778,
 0.68338975030928850,0.93453497067093849}
;
    
    double Result = 4.9177467138506472 ;
    
    double out = 0 ;
    
    out = dtracea ( in , LINES ) ;
    
    assert(fabs(out - Result) / fabs( out )< 1e-16);
}



static void ctraceaTest ( void ) {
   int i = 0 ;
    
   float tin[] =
{0.41574033396318555f,0.49111106572672725f,0.44963645050302148f,0.83262220909819007f,
 0.64995764615014195f,0.49560560984537005f,0.61533244187012315f,0.52116033947095275f,
 0.31538392649963498f,0.50222720531746745f,
0.15958226565271616f,0.34022171795368195f,0.96781380381435156f,0.74247795902192593f,
 0.23031901288777590f,0.18889334425330162f,0.89581834804266691f,0.45098419673740864f,
 0.34899875614792109f,0.05404338985681534f,
0.38831026805564761f,0.99661536002531648f,0.64890601998195052f,0.01946402387693524f,
 0.55043680546805263f,0.56412307033315301f,0.87217613449320197f,0.39612928451970220f,
 0.74138183100149035f,0.01639390224590898f,
0.94154607132077217f,0.02153958659619093f,0.25446669198572636f,0.80160319153219461f,
 0.30389970541000366f,0.85622101929038763f,0.83897679112851620f,0.72408697474747896f,
 0.97027219459414482f,0.60508118104189634f,
0.47229793528094888f,0.68768908223137259f,0.19239750178530812f,0.25545394374057651f,
 0.03710305178537965f,0.07947642868384719f,0.20409553544595838f,0.67240559635683894f,
 0.12765105674043298f,0.29538751533254981f,
0.85336526390165091f,0.00449241511523724f,0.68614923674613237f,0.26881096139550209f,
 0.17038810532540083f,0.61961987055838108f,0.31665382627397776f,0.23861460387706757f,
 0.38288621511310339f,0.64512947760522366f,
0.12077391659840941f,0.63978545414283872f,0.42314558057114482f,0.75584907690063119f,
 0.56986862560734153f,0.22410399885848165f,0.70068256510421634f,0.71248416090384126f,
 0.48824774986132979f,0.94497666554525495f,
0.89993809349834919f,0.5416147718206048f,0.67344415932893753f,0.43475896771997213f,
 0.00364112667739391f,0.85820947308093309f,0.20731051638722420f,0.32864938955754042f,
 0.51919496990740299f,0.5638650292530656f,
0.43849021615460515f,0.22476492030546069f,0.82706967229023576f,0.64259665226563811f,
 0.44915470527485013f,0.71145519940182567f,0.52225506165996194f,0.48377691349014640f,
 0.09068560274317861f,0.97863480402156711f,
0.89760566223412752f,0.73640052601695061f,0.93608058523386717f,0.69578680582344532f,
 0.05768106970936060f,0.80260276049375534f,0.94164209719747305f,0.76627670042216778f,
 0.68338975030928850f,0.93453497067093849f}
;
    floatComplex in [LINES*LINES] ;
    
    floatComplex Result = FloatComplex ( 4.9177467138506472f,  4.9177467138506472f);
    
    floatComplex out ;
    
    for ( i = 0 ; i < LINES*LINES  ; i++ )
	  in[i] = FloatComplex ( tin[i] , tin[i] ) ;
    
    out = ctracea ( in , LINES ) ;
    
     assert ( fabs(  creals(out) - creals (Result) )/ fabs (creals (out))  < 1e-07 );
	 assert ( fabs(  cimags(out) - cimags (Result) )/ fabs (cimags (out))  < 1e-07 );
    
}





static void ztraceaTest ( void ) {
 
  int i = 0 ; 
  
 double tin[] = 
 {0.41574033396318555,0.49111106572672725,0.44963645050302148,0.83262220909819007,
 0.64995764615014195,0.49560560984537005,0.61533244187012315,0.52116033947095275,
 0.31538392649963498,0.50222720531746745,
0.15958226565271616,0.34022171795368195,0.96781380381435156,0.74247795902192593,
 0.23031901288777590,0.18889334425330162,0.89581834804266691,0.45098419673740864,
 0.34899875614792109,0.05404338985681534,
0.38831026805564761,0.99661536002531648,0.64890601998195052,0.01946402387693524,
 0.55043680546805263,0.56412307033315301,0.87217613449320197,0.39612928451970220,
 0.74138183100149035,0.01639390224590898,
0.94154607132077217,0.02153958659619093,0.25446669198572636,0.80160319153219461,
 0.30389970541000366,0.85622101929038763,0.83897679112851620,0.72408697474747896,
 0.97027219459414482,0.60508118104189634,
0.47229793528094888,0.68768908223137259,0.19239750178530812,0.25545394374057651,
 0.03710305178537965,0.07947642868384719,0.20409553544595838,0.67240559635683894,
 0.12765105674043298,0.29538751533254981,
0.85336526390165091,0.00449241511523724,0.68614923674613237,0.26881096139550209,
 0.17038810532540083,0.61961987055838108,0.31665382627397776,0.23861460387706757,
 0.38288621511310339,0.64512947760522366,
0.12077391659840941,0.63978545414283872,0.42314558057114482,0.75584907690063119,
 0.56986862560734153,0.22410399885848165,0.70068256510421634,0.71248416090384126,
 0.48824774986132979,0.94497666554525495,
0.89993809349834919,0.5416147718206048,0.67344415932893753,0.43475896771997213,
 0.00364112667739391,0.85820947308093309,0.20731051638722420,0.32864938955754042,
 0.51919496990740299,0.5638650292530656,
0.43849021615460515,0.22476492030546069,0.82706967229023576,0.64259665226563811,
 0.44915470527485013,0.71145519940182567,0.52225506165996194,0.48377691349014640,
 0.09068560274317861,0.97863480402156711,
0.89760566223412752,0.73640052601695061,0.93608058523386717,0.69578680582344532,
 0.05768106970936060,0.80260276049375534,0.94164209719747305,0.76627670042216778,
 0.68338975030928850,0.93453497067093849};
    
    doubleComplex in [LINES*LINES] ;
    
    doubleComplex Result = DoubleComplex ( 4.9177467138506472,  4.9177467138506472);
    
    doubleComplex out ;
    
    
    
    for ( i = 0 ; i < LINES*LINES  ; i++ )
	  in[i] = DoubleComplex ( tin[i] , tin[i] ) ;
    
    out = ztracea ( in , LINES ) ;
    
     assert ( fabs(  zreals(out) - zreals (Result) )/ fabs (zreals (out))  < 1e-16 );
	 assert ( fabs(  zimags(out) - zimags (Result) )/ fabs (zimags (out))  < 1e-16 );   
    
}

static int testTrace(void) {

  printf("\n>>>> Matrix Trace Tests\n");
  straceaTest();
  dtraceaTest();
  ctraceaTest();
  ztraceaTest();

  return 0;
}



int main(void) {
  assert(testTrace() == 0);
  return 0;
}