#include <stdio.h>
#include <gsl/gsl_multifit.h>
#include <assert.h>
#include <iostream>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <string>
#include <vector>

/** thanks to Jolkdarr, le samedi 18 septembre 2004 à 12:36:37 for 
 * http://www.commentcamarche.net/forum/affich-1009440-lire-une-matrice-dans-un-fichier-texte-en-c**/

using namespace std;


class ligne_matrice : public string
{
};

inline
istream& operator>>(istream& In, ligne_matrice& L)
{
	return getline(In, L);
}




/**    

 *
 *  ***/
	int
main (int argc,char*argv[])
{
	char inputFile[5000];
	char sinksFile[5000];
	char outputFile[5000];
	int n;
	int d;
	int D;
	int skipped;skipped=0;
	if (argc<5) {printf("I need four arguments: librks $numberOfSinks inputset sinks outputset [$numberOfSkippedSinks]\nThe possible fifth argument is an integer: the number of sinks that should be skipped.\n");exit(-1);}
	sscanf(argv[1],"%d ",&D);
	sscanf(argv[2],"%s ",&inputFile);
	sscanf(argv[3],"%s ",&sinksFile);
	sscanf(argv[4],"%s ",&outputFile);
	if (argc>5)
	{sscanf(argv[5],"%d ",&skipped);fprintf(stderr,"%d sinks skipped\n",skipped);
	} else fprintf(stderr,"no sink skipped\n");fflush(stderr);

	std::vector<std::vector<double> > matrix;
	std::vector<double> theTargets;
/************** reading matrix in stdin ***********************/
	{
	ifstream FichierMatrice(inputFile,ios::in);
	if (!FichierMatrice)
	{
		cerr << "Ouverture du fichier impossible" << endl;
		exit(1);
	}

	double val;double target;char c;int idx;
	unsigned int Lignes = 0;
	unsigned int Colonnes = 0;
	

	// lecture de chaque ligne :
	ligne_matrice Ligne;
	while (FichierMatrice >> Ligne)
	{
		std::vector<double> line;
		Lignes++;
		Colonnes = 0;
		istringstream S(Ligne, ios_base::in);
		S >> target;
		theTargets.push_back(target);
		//cout << "target:" << target << "             ";
		// lecture de chaque element :
 		while (S >> idx)
 		{
 			Colonnes++;
   			//cout <<  "(" << idx << ")  ";
			assert(Colonnes==idx);
			S >> c;
			//cout << "#" << c << "#";
			S >> val;
   			//cout <<  " " << val << "   ";
			line.push_back(val);
 		}
 		matrix.push_back(line);
 	//	cout << endl << "Ligne " << Lignes << " contient " << Colonnes << " colonnes." << endl;		
	}

	n= matrix.size();
	d= matrix[0].size();
	fprintf(stderr,"%d lines, %d columns\n",n,d); 
	}
/************** matrix read ***********************************/


	std::vector<std::vector<double> > sinksMatrix;
/************** reading sinks matrix in stdin ***********************/
	{
	ifstream FichierMatrice(sinksFile,ios::in);
	if (!FichierMatrice)
	{
		cerr << "Ouverture du fichier impossible" << endl;
		exit(1);
	}

	double val;double target;char c;int idx;
	unsigned int Lignes = 0;
	unsigned int Colonnes = 0;
	
	// lecture de chaque ligne :
	ligne_matrice Ligne;

	for (int z=0;z<skipped;z++)
	{
		FichierMatrice >> Ligne;

		cerr << "skipping " << Ligne << endl;
	}

	while ((FichierMatrice >> Ligne)&&(sinksMatrix.size()<D))
	{
		std::vector<double> line;
		Lignes++;
		Colonnes = 0;
		istringstream S(Ligne, ios_base::in);
		//cout << "target:" << target << "             ";
		// lecture de chaque element :
 		while ((S >> val)&&(d>=Colonnes))
 		{
 			Colonnes++;
			line.push_back(val);
 		}
 		sinksMatrix.push_back(line);
 	//	cout << endl << "Ligne " << Lignes << " contient " << Colonnes << " colonnes." << endl;		
	}

	assert(D== sinksMatrix.size());
	fprintf(stderr,"%d sinks, %d columns\n",D,sinksMatrix[0].size()); 
	}
/************** matrix read ***********************************/







	FILE * outputFileH=fopen(outputFile,"w");
	for (int i=0;i<n;i++)
	{
		fprintf(outputFileH,"%g ",theTargets[i]);
	//	printf("point %d / %d:",i,n);fflush(stdout);
		for (int k=0;k<D;k++)
		{
			double sum=0.;
			for (int j=0;j<d;j++)
				sum+=matrix[i][j]*sinksMatrix[k][j];
			fprintf(outputFileH," %d:%g %d:%g ",k*2+1,cos(sum)/sqrt(D),k*2+2,sin(sum)/sqrt(D));
		}
		fprintf(outputFileH,"\n");
	}
	fclose(outputFileH);









}







/****************** example of learning set *************
-14.2881 1:-2.1539 2:-0.8064 3:0.3599 4:1.5678 5:0.5909 
-10.7168 1:-1.6868 2:0.0412 3:0.2989 4:0.5506 5:1.6265 
-1.5478 1:-0.3365 2:1.2474 3:-0.0712 4:-1.5367 5:-0.0756 
8.5313 1:0.9037 2:-1.8271 3:1.1505 4:-0.6216 5:-0.7890 
2.0340 1:0.0534 2:-0.4400 3:1.0541 4:1.1224 5:0.6182 
3.6371 1:0.3744 2:1.4763 3:-0.8212 4:-0.3231 5:-0.4993 
-2.3663 1:-0.3824 2:0.8704 3:-1.2390 4:-0.7142 5:-0.7766 
1.9105 1:0.1738 2:-1.8403 3:0.7640 4:0.1848 5:1.0354 
3.9771 1:0.4907 2:-0.5790 3:-0.6055 4:-0.7748 5:-0.3977 
3.7776 1:0.3897 2:-0.0589 3:-0.4941 4:0.0731 5:0.5806 
-1.5231 1:-0.3566 2:0.3767 3:-0.2675 4:0.3015 5:-0.1446 
2.8262 1:0.2873 2:-0.6907 3:-0.9488 4:0.8091 5:-1.3417 
-8.4526 1:-1.2431 2:1.0786 3:0.2947 4:-0.6611 5:0.8423 
2.9257 1:0.2429 2:-1.6150 3:0.0550 4:-0.2680 5:0.0342 
5.0362 1:0.7817 2:0.2338 3:-0.8249 4:0.1973 5:0.4454 
5.3026 1:0.6739 2:0.7902 3:0.8861 4:-0.2399 5:-0.9348 
-2.7011 1:-0.4794 2:-0.5980 3:-0.7799 4:1.5365 5:-0.7841 
-10.1263 1:-1.5086 2:0.9077 3:0.0606 4:0.7004 5:-0.1054 
2.3707 1:0.1921 2:0.1228 3:1.1855 4:0.2055 5:0.2334 
-7.3536 1:-1.2079 2:0.0329 3:0.6672 4:-0.3958 5:0.5004 
-9.7055 1:-1.5694 2:2.1112 3:0.1536 4:-0.9531 5:0.1273 
-7.9449 1:-1.2742 2:-0.1371 3:-0.3349 4:0.3963 5:-1.5565 
10.7669 1:1.4268 2:-0.4322 3:0.0162 4:1.1060 5:-0.6829 
2.6779 1:0.1457 2:1.1740 3:0.5556 4:0.4947 5:-0.0532 
-6.4095 1:-1.3206 2:-0.8965 3:1.3677 4:-1.4986 5:-0.4771 
2.2105 1:0.1829 2:0.1457 3:-0.8484 4:0.6594 5:-0.1846 
-6.7094 1:-1.2310 2:1.6252 3:1.0419 4:1.1846 5:1.3666 
9.1894 1:1.0182 2:1.5991 3:0.4533 4:0.0958 5:0.2646 
2.0337 1:0.3371 2:1.4003 3:-0.9491 4:-0.7593 5:0.2459 
-7.2570 1:-1.0910 2:-0.2912 3:1.2008 4:0.2384 5:0.7812 
18.1661 1:2.4201 2:-2.2921 3:0.9369 4:-0.0146 5:-0.4881 
3.7458 1:0.5748 2:1.1791 3:-0.2726 4:-0.3721 5:1.9824 
0.8661 1:-0.0993 2:1.0121 3:0.4311 4:0.2627 5:0.9958 
4.7447 1:0.7544 2:-0.0165 3:1.5366 4:0.9906 5:-0.3432 
4.3992 1:0.4946 2:0.6354 3:0.1391 4:1.9843 5:1.4446 
-0.0941 1:-0.1147 2:0.9284 3:0.4452 4:1.1170 5:0.5737 
-4.0578 1:-0.7570 2:0.0238 3:-1.4696 4:1.4182 5:0.9135 
5.3070 1:0.6835 2:0.2403 3:-0.7808 4:-0.4376 5:-1.9839 
6.6623 1:0.9085 2:0.5257 3:1.0482 4:0.2890 5:-0.1438 
4.4416 1:0.7135 2:0.0165 3:-1.1667 4:-0.7540 5:0.0439 
-3.6725 1:-0.7476 2:0.9952 3:-0.9166 4:-1.0452 5:-1.3816 
-0.9815 1:-0.4563 2:-0.4585 3:1.8102 4:-0.5970 5:0.6710 
-2.9490 1:-0.5859 2:-0.6639 3:-0.7555 4:0.8469 5:-0.3758 
3.9295 1:0.6190 2:-0.5269 3:-0.5739 4:-0.9378 5:-1.3872 
12.2029 1:1.5079 2:0.1130 3:-1.3663 4:-0.3483 5:0.3997 
7.1899 1:1.0230 2:-0.7200 3:-1.7784 4:1.1260 5:-0.1766 
9.9616 1:1.0496 2:0.8701 3:0.4646 4:-0.1699 5:-1.4635 
-17.6241 1:-2.4989 2:1.5232 3:1.5566 4:0.4926 5:0.2047 
-7.1149 1:-1.0837 2:-0.6059 3:0.1088 4:-0.2093 5:-0.4709 
12.3284 1:1.6331 2:-0.8860 3:0.7226 4:1.6387 5:-1.1022 
***************************/

