/*
 *  Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
 *  Copyright (C) 2006-2008 - INRIA - Bruno JOFRET
 *
 *  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 "variance.h"
#include "assert.h"

static int floatVariance(void){

	int i;
	
	
	/*test 1 */
	{
		float matrice[20]={1.0f,5.0f,9.0f,4.0f,8.0f,2.0f,6.0f,1.0f,5.0f,9.0f,3.0f,7.0f,2.0f,6.0f,1.0f,4.0f,8.0f,3.0f,7.0f,2.0f};
		float out, *outColumns, *outRows;
		float result= 7.5026315789473692063893f;
		float resultColumns[5]= {1.6666666666666667406815f ,1.6666666666666667406815f   ,12.916666666666666074548f   ,1.6666666666666667406815f   ,16.666666666666667850905f};
		float resultRows[4]={10.300000000000000710543f  ,  10.300000000000000710543f  ,  6.7000000000000001776357f ,   6.7000000000000001776357f};
	
	
	
		outColumns= malloc((uint)5*sizeof(float));
		outRows= malloc((uint)4*sizeof(float));
	
		out = svariancea(matrice,20);
		srowvariancea(matrice,5,4,outRows);
		scolumnvariancea(matrice,5,4,outColumns);
	
	
		printf("Variance \n");
		printf("%f\n",out);
		printf("Row Variance \n");
		for (i=0;i<4;i++) printf("%f\n",outRows[i]);	
		printf("Column Variance \n");
		for (i=0;i<5;i++) printf("%f\n",outColumns[i]);
	
	
		assert(fabs(out-result)/fabs(out) <1e-06);
		for (i=0;i<4;i++)assert(fabs(outRows[i]-resultRows[i])/fabs(outRows[i]) <1e-06);
	
		for (i=0;i<5;i++)assert(fabs(outColumns[i]-resultColumns[i])/fabs(outColumns[i]) <1e-06);
		
		free(outColumns);
		free(outRows);
	}
	
	
	/* test 2 */
	
	{
		float mtovar[70]={0.2113248654641211032867f,0.7560438541695475578308f,0.0002211346291005611420f,
	 0.3303270917385816574097f,0.6653811042197048664093f,0.6283917883411049842835f,
	 0.8497452358715236186981f,
	0.6857310198247432708740f,0.8782164813019335269928f,0.0683740368112921714783f,
	 0.5608486062847077846527f,0.6623569373041391372681f,0.7263506767340004444122f,
	 0.1985143842175602912903f,
	0.5442573162727057933807f,0.2320747897028923034668f,0.2312237196601927280426f,
	 0.2164632631465792655945f,0.8833887814544141292572f,0.6525134947150945663452f,
	 0.3076090742833912372589f,
	0.9329616213217377662659f,0.2146007861010730266571f,0.3126419968903064727783f,
	 0.3616361008025705814362f,0.2922266637906432151794f,0.5664248815737664699554f,
	 0.4826471973210573196411f,
	0.3321718913502991199493f,0.5935094701126217842102f,0.5015341597609221935272f,
	 0.4368587583303451538086f,0.2693124809302389621735f,0.6325744865462183952332f,
	 0.4051954015158116817474f,
	0.9184707831591367721558f,0.0437334333546459674835f,0.4818508932366967201233f,
	 0.2639556000940501689911f,0.4148103706538677215576f,0.2806498021818697452545f,
	 0.1280058464035391807556f,
	0.7783128595910966396332f,0.2119030449539422988892f,0.1121354666538536548615f,
	 0.6856895955279469490051f,0.1531216683797538280487f,0.6970850601792335510254f,
	 0.8415518426336348056793f,
	0.4062024755403399467468f,0.4094825475476682186127f,0.8784125801175832748413f,
	 0.1138359685428440570831f,0.1998337740078568458557f,0.5618660743348300457001f,
	 0.5896177329123020172119f,
	0.6853979662992060184479f,0.8906224733218550682068f,0.5042212805710732936859f,
	 0.3493615407496690750122f,0.3873778772540390491486f,0.9222898678854107856751f,
	 0.9488184261135756969452f,
	0.3435337245464324951172f,0.3760118731297552585602f,0.7340940563008189201355f,
	 0.2615761472843587398529f,0.4993493836373090744019f,0.2638578419573605060577f,
	 0.5253563085570931434631f};
		float out2, *outColumns2, *outRows2;
	 	float result2=     0.0651863337585355667736f  ;
		float resultColumns2[7]= {0.0650391675869589902526f  ,
	    0.0913789208052724344356f  ,
	    0.0837863718398224738282f  ,
	    0.0281545517812518443501f  ,
	    0.0549594706400152802073f  ,
	    0.0389978730537587012228f  ,
	    0.0796657637071630925218f  ,
	 };
		float resultRows2[10]={0.0988544518240001696130f  ,  0.0874673050908554156058f  ,  0.0678199050579095519264f,    0.0591380787668954188696f   , 0.0175386373980947855855f ,0.0831815708684833926556f  ,  0.1035239817400336881370f,   0.0657802543744439444096f  ,  0.0667446022405332184402f  ,  0.0287884625084994134891f};
	
	
		outColumns2= malloc((uint)7*sizeof(float));
		outRows2= malloc((uint)10*sizeof(float));
	
	
	
		out2 = svariancea(mtovar,70);
		srowvariancea(mtovar,7,10,outRows2);
		scolumnvariancea(mtovar,7,10,outColumns2);
	
	
		printf("Variance 2 \n");
		printf("%f\n",out2);
		printf("Row Variance 2 \n");
		for (i=0;i<10;i++) printf("%f\n",outRows2[i]);	
		printf("Column Variance 2 \n");
		for (i=0;i<7;i++) printf("%f\n",outColumns2[i]);
	
		assert(fabs(out2-result2)/fabs(out2) <1e-06);
		for (i=0;i<10;i++)assert(fabs(outRows2[i]-resultRows2[i])/fabs(outRows2[i]) <1e-06);
	
		for (i=0;i<7;i++)assert(fabs(outColumns2[i]-resultColumns2[i])/fabs(outColumns2[i]) <1e-06);
		
		free(outColumns2);
		free(outRows2);	
	
	}
	
	
	return 0;
}


static int floatComplexVariance(void){
	int i;
	
	/* test 1 */
	{
		float inR[6]={0.9677053210325539112091f,0.5068534435704350471497f,0.523297640960663557053f,0.5596947595477104187012f,
		0.5617307000793516635895f,0.468176002614200115204f};
		float inI[6]={0.7794546722434461116791f,0.7901071812957525253296f,0.9808542062528431415558f,0.8187066102400422096252f,
		0.4256872381083667278290f,0.2461560554802417755127f};
		float varianceR=- 0.0428404140538702279950f;
		float varianceI=0.0257955584577409802183f;
		float rowVarianceR[3]={0.106135488505625180666f,- 0.0124835463256454722719f,- 0.01173948205902856229f};
		float rowVarianceI[3]={- 0.0049092287964376275095f,- 0.0059017052806824826100f,0.0167959854763351026929f};
		float colVarianceR[2]={- 0.0183554755457089394111f,- 0.1019751767306446843531f};
		float colVarianceI[2]={0.0109267784648201249365f,0.0249829946888768111846f};
		floatComplex *in, *rowVariance, *colVariance;
		floatComplex out, *outRow, *outCol;
		
		in= malloc ((uint)6*sizeof(floatComplex));
		outRow= malloc ((uint)3*sizeof(floatComplex));
		outCol= malloc ((uint)2*sizeof(floatComplex));
		
		in=FloatComplexMatrix(inR,inI,6);
		rowVariance=FloatComplexMatrix(rowVarianceR,rowVarianceI,3);
		colVariance=FloatComplexMatrix(colVarianceR,colVarianceI,2);
		
		
		out=cvariancea(in,6);
		printf("Variance \n");
		printf("%f + %f *i\n",creals(out),cimags(out));
		
		assert(fabs(creals(out)-varianceR)/fabs(creals(out)) <1e-6);
		assert(fabs(cimags(out)-varianceI)/fabs(cimags(out)) <1e-6);
		
		
		
		
		
		crowvariancea(in,2,3,outRow);
		printf("Row Variance \n");
		for (i=0;i<3;i++)	printf("%1.20f + %1.20f *i\n",creals(outRow[i]),cimags(outRow[i]));	
			
			
		for (i=0;i<3;i++){
			assert(fabs(creals(outRow[i])-rowVarianceR[i])/fabs(creals(outRow[i])) <1e-6);
			assert(fabs(cimags(outRow[i])-rowVarianceI[i])/fabs(cimags(outRow[i])) <3e-6);
		}
		
		
		
		ccolumnvariancea(in,2,3,outCol);		
		printf("Column Variance \n");
		for (i=0;i<2;i++) printf("%f + %f *i\n",creals(outCol[i]),cimags(outCol[i]));
				
		
		for (i=0;i<2;i++){
			assert(fabs(creals(outCol[i])-colVarianceR[i])/fabs(creals(outCol[i])) <1e-6);			
			assert(fabs(cimags(outCol[i])-colVarianceI[i])/fabs(cimags(outCol[i])) <3e-6);			
		}
		
		free(in);
		free(outCol);
		free(outRow);
		
		
	}
	
	
	printf("\n");
	printf("\n");
	printf("\n");
	printf("\n");
	
	
	/* test 2 */
	{
		float inR[70]={0.0453502028249204158783f,0.2029444333165884017944f,0.7844273825176060199738f,
 0.2637536162510514259338f,0.4383276398293673992157f,0.866485897451639175415f,
 0.3792142109014093875885f,0.7668716078624129295349f,0.6006621322594583034515f,
 0.7856735605746507644653f,
0.7387115550227463245392f,0.5544260339811444282532f,0.9929149555973708629608f,
 0.9757428467273712158203f,0.3709622272290289402008f,0.3032238213345408439636f,
 0.9519520117901265621185f,0.7127858083695173263550f,0.119237006176263093948f,
 0.5009163180366158485413f,
0.3290053526870906352997f,0.4808946810662746429443f,0.3303695977665483951569f,
 0.6304475357756018638611f,0.2117190784774720668793f,0.4486023131757974624634f,
 0.5914509710855782032013f,0.6806742670014500617981f,0.0739296111278235912323f,
 0.9433694705367088317871f,
0.1286330693401396274567f,0.2019080771133303642273f,0.1969303428195416927338f,
 0.8928690161556005477905f,0.4617918957956135272980f,0.6251291716471314430237f,
 0.7059706593863666057587f,0.7018169648945331573486f,0.4087999747134745121002f,
 0.0636221384629607200623f,
0.0657393387518823146820f,0.5331004131585359573364f,0.0331581872887909412384f,
 0.3157835649326443672180f,0.3785823243670165538788f,0.4619523435831069946289f,
 0.6287369825877249240875f,0.2878515301272273063660f,0.3292048736475408077240f,
 0.4719233047217130661011f,
0.3353769634850323200226f,0.5553069720044732093811f,0.1196080814115703105927f,
 0.7613999657332897186279f,0.4790988476015627384186f,0.2816969295963644981384f,
 0.2380097783170640468597f,0.3294205460697412490845f,0.2306728032417595386505f,
 0.2136296601966023445129f,
0.4054998042993247509003f,0.3095371201634407043457f,0.6762971603311598300934f,
 0.970691631548106670380f,0.5441796570084989070892f,0.0204747971147298812866f,
 0.8941364963538944721222f,0.3490363890305161476135f,0.1105365152470767498016f,
 0.2023377753794193267822f};
		float inI[70]={1.0377217042259871959686f,1.9830380710773169994354f,-0.6786614381708204746246f,
 -1.7368789152242243289948f,0.6849579229019582271576f,-1.9756898251362144947052f, 0.9018773441202938556671f,0.4113956945948302745819f,0.0771432374604046344757f,
 -2.6145569621585309505463f,
-0.8694803346879780292511f,1.1954508102498948574066f,1.0175080369226634502411f,
 -1.86952689336612820625f,1.6495719677768647670746f,-1.1282413271255791187286f,
 1.7159116868861019611359f,1.3512618443928658962250f,1.6467350018210709095001f,
 -4.3247690196149051189423f,
-1.1214177873916923999786f,0.3549467395059764385223f,1.5090364827774465084076f,
 0.0271988785825669765472f,-0.3927204073406755924225f,-2.2866433826275169849396f,
 2.4531399612314999103546f,1.2140426929108798503876f,0.1123848785646259784699f,
 -1.2278760573826730251312f,
0.5748759503476321697235f,0.1001535071991384029388f,0.7154782521538436412811f,
 -0.3598340046592056751251f,0.1114491275511682033539f,-1.0214430955238640308380f,
 1.8411546354182064533234f,1.3313704966567456722260f,0.107393887359648942947f,
 -2.1405860441736876964569f,
-0.1921784919686615467072f,-0.0941377175040543079376f,-0.3007089742459356784821f,
 -1.6332105011679232120514f,-0.9827875629998743534088f,-4.0793808070011436939240f,
 1.6021160488016903400421f,0.5996482106857001781464f,-1.0103867049328982830048f,
 -1.9795853956602513790131f,
-0.7019297261722385883331f,0.1910370937548577785492f,0.5148729826323688030243f,
 -1.2210475285537540912628f,1.4409833527170121669769f,-2.0624672439880669116974f,
 2.2999203805811703205109f,1.6434787488542497158051f,-0.0813916879706084728241f,
 -4.3653216282837092876434f,
0.0896512451581656932831f,1.4530082489363849163055f,-0.1911182911135256290436f,
 -1.5278804996050894260406f,-0.8655951828695833683014f,-2.6959278550930321216583f,
 1.089711368549615144730f,0.2611377011053264141083f,-0.0787748913280665874481f,
 -1.675187868531793355942f};
 		float varianceR=- 2.3201230329620456949158f;
		float varianceI=0.0135359053960125846894f;
		float rowVarianceR[7]={- 2.1748250359163439071608f,- 4.0055927597555047725564f,- 1.9380991813636070375537f,- 1.211164632384367667584f,
		- 2.3819157100812309302285f,- 3.865411523472068289209f,- 1.5488286339908912125907f};
		float rowVarianceI[7]={- 0.5161401892195496277083f,- 0.0302397956223948334575f,0.0072526988331105511632f,0.2035074619460965072992f,
		- 0.0227578793067023492369f,0.0176453877563822227048f,0.2048099414748655033858f};
		float colVarianceR[10]={ - 0.5673920596394929072304f, 
						  - 0.6095831761740567733554f,  
						  - 0.4837275005370789138226f,
						  - 0.4518709923747168399899f,
						  - 1.1155710732654480210613f,
						  - 0.9922425930742954092168f,
						  - 0.2615272073355465187738f,
						  - 0.2448899237808548345896f,
						  - 0.5783271525148965253038f,
						  - 1.4662540245146995498970f };
		float colVarianceI[10]={ - 0.2519451287679840834066f,
						  - 0.1132720366896080160801f,
						  - 0.0393753052279357945720f , 
						  0.0678956480014177715665f  ,
						  0.0165011281984272333012f  ,
						  0.1043646242921155153915f  ,
						  - 0.0697520473529744805541f , 
						  0.0395755738577838397929f  ,
						  - 0.0906906077772287183558f , 
						  0.2030521845859689644698f  };
		floatComplex *in, *rowVariance, *colVariance;
		floatComplex out, *outRow, *outCol;
		
		in= malloc ((uint)70*sizeof(floatComplex));
		outRow= malloc ((uint)7*sizeof(floatComplex));
		outCol= malloc ((uint)10*sizeof(floatComplex));
		
		in=FloatComplexMatrix(inR,inI,70);
		rowVariance=FloatComplexMatrix(rowVarianceR,rowVarianceI,7);
		colVariance=FloatComplexMatrix(colVarianceR,colVarianceI,10);
		
		
		out=cvariancea(in,70);
		printf("Variance 2 \n");
		printf("%f + %f *i\n",creals(out),cimags(out));
		
		assert(fabs(creals(out)-varianceR)/fabs(creals(out)) <1e-6);
		assert(fabs(cimags(out)-varianceI)/fabs(cimags(out)) <3e-6);
		
		
		
		
		
		crowvariancea(in,10,7,outRow);
		printf("Row Variance 2 \n");
		for (i=0;i<7;i++)	printf("%1.20f + %1.20f *i\n",creals(outRow[i]),cimags(outRow[i]));	
			
			
		for (i=0;i<7;i++){
			assert(fabs(creals(outRow[i])-rowVarianceR[i])/fabs(creals(outRow[i])) <1e-6);
			assert(fabs(cimags(outRow[i])-rowVarianceI[i])/fabs(cimags(outRow[i])) <3e-6);
		}
		
		
		
		ccolumnvariancea(in,10,7,outCol);		
		printf("Column Variance 2 \n");
		for (i=0;i<10;i++) printf("%f + %f *i\n",creals(outCol[i]),cimags(outCol[i]));
				
		
		for (i=0;i<10;i++){
			assert(fabs(creals(outCol[i])-colVarianceR[i])/fabs(creals(outCol[i])) <1e-6);			
			assert(fabs(cimags(outCol[i])-colVarianceI[i])/fabs(cimags(outCol[i])) <3e-6);			
		}
		
		free(in);
		free(outCol);
		free(outRow);
	}
	
	return 0;
}





static int testFloatVariance   (void) {
  printf("\n\n\n\n*********************\n");
  printf("***** Float  Tests Nono****\n");
  printf("*********************\n");
	assert(floatVariance()==0);
	assert(floatComplexVariance()==0);


  return 0;
}

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