/***************************************************************************
 matrices.cpp  -  Librairie d'objets pour manipuler des matrices
 -------------------
 begin                : ven aug 14 10:25:55 CEST 2000
 copyright            : (C) 2000 by Olivier Langella CNRS UPR9034
 email                : Olivier.Langella@pge.cnrs-gif.fr
 ***************************************************************************/

/***************************************************************************
 *                                                                         *
 *   This program is free software; you can redistribute it and/or modify  *
 *   it under the terms of the GNU General Public License as published by  *
 *   the Free Software Foundation; either version 2 of the License, or     *
 *   (at your option) any later version.                                   *
 *                                                                         *
 ***************************************************************************/

#include "matrices.h"

namespace biolib {
namespace vecteurs {


Matrice::Matrice(const Matrice& original) {
	//constructeur de copie
	unsigned long i;

	//	if (_tab != 0) delete [] _tab;
	_oformat = 1;
	_nc = original._nc;
	_nl = original._nl;
	_t = _nc * _nl;

	_tab = new long double[_t];

	_titre = original._titre;
	_flag = original._flag;
	_tcol = original._tcol;
	_tlig = original._tlig;
	_miss = original._miss;
	_type = original._type;

	for (i = 0; i < _t; i++) {
		//nouvelle s�quence
		_tab[i] = original._tab[i];
	}

}

Matrice::Matrice() {

	//		_Pointeur = *( new (Pointeur<T>));
	_oformat = 1;
	_nc = 0;
	_nl = 0;
	_t = 0;
	_tab = 0;
	_type = 0;
	_miss = 0;
	_flag = 0;
}

Matrice::Matrice(unsigned long nl, unsigned long nc) {
	unsigned long i;

	_oformat = 1;
	_nc = nc;
	_nl = nl;
	_t = nc * nl;
	_tab = new long double[_t];
	_type = 1;

	_miss = 0;
	_flag = 0;
	_titre.resize(0);

	_tcol.reserve(_nc);
	_tlig.reserve(_nl);
	for (i = 0; i < _nc; i++)
		_tcol.push_back("");
	for (i = 0; i < _nl; i++)
		_tlig.push_back("");

	for (i = 0; i < _t; i++)
		_tab[i] = 0;

}

bool Matrice::SetType(int type) {

	switch (type) {
	case 1: //rectangulaire normale
		_type = type;
		break;
	case 2: //matrice triangulaire (distances)
		if (_nc == _nl) {
			unsigned long i, j;
			for (i = 0; i < _nc; i++) {
				for (j = 0; j < i; j++) {
					if (GetCase(i, j) != GetCase(j, i)) {
						qDebug() << "Matrices::Anomalie  "
								<< "failed to convert into symetric matrix (i,j)!=(j,i) "
								<< (float) GetCase(i, j) << " "
								<< (float) GetCase(j, i) << " i " << i << " j "
								<< j;
						return (false);
						//throw typename biolib::vecteurs::Matrice<T>::Anomalie(5);
					}
				}
			}
			_type = type;
		} else {
			qDebug() << "Matrices::Anomalie  "
					<< "failed to convert into symetric matrix nc!=nl " << _nc
					<< " " << _nl;
			return (false);
			//throw typename biolib::vecteurs::Matrice<T>::Anomalie(5); //Echec de conversion
		}
		break;
	default:
		break;
	}
	return (true);
}

const Matrice& Matrice::operator=(
		const Matrice &rval) {

	unsigned long i;

	if (_tab != 0)
		delete[] _tab;

	_type = rval._type;
	_flag = rval._flag;
	_nc = rval._nc;
	_nl = rval._nl;
	_t = rval._t;
	_tab = new long double[rval._t];

	_titre = rval._titre;

	_tlig = rval._tlig;
	_tcol = rval._tcol;

	for (i = 0; i < _t; i++)
		_tab[i] = rval._tab[i];

	return (*this);
}

const Matrice& Matrice::operator=(vector<long double> &rval) {

	int i;

	if (_tab != 0)
		delete[] _tab;

	_type = 1;
	_flag = 0;
	_nc = rval.size();
	_nl = 1;
	_t = _nc;
	_tab = new long double[_nc];

	//	_titre = rval._titre;

	//	_tlig = rval._tlig;
	//	_tcol = rval._tcol;

	for (i = 0; i < _t; i++)
		_tab[i] = rval[i];

	return (*this);
}

void Matrice::oExcel(ostream& fichier) {
	unsigned long i, j;

	//	fichier.setf(ios::scientific);
	//fichier << "coucou";
	// �criture du titre
	for (i = 0; i < _titre.size(); i++) {
		fichier << _titre[i];
		fichier << endl;
	}

	fichier << "#";
	if ((_flag == 2) || (_flag == 3)) {
		//�tiquettes des colonnes
		fichier << '\t' << _tcol[0];
		for (i = 1; i < _nc; i++)
			fichier << '\t' << _tcol[i];
	}
	fichier << endl;

	//�criture de la matrice
	for (i = 0; i < _nl; i++) {
		if ((_flag == 1) || (_flag == 3)) {
			//�tiquettes des lignes
			fichier << _tlig[i];
		}

		for (j = 0; j < _nc; j++) {
			//			fichier << '\t' << _tab [i * _nc + j];
			fichier << '\t' << GetCase(i, j);
		}
		fichier << endl;
	}

}

void Matrice::oGnumeric(ostream& fichier) {
	QString * p_output_xml = new QString("");
	QXmlStreamWriter xml_stream(p_output_xml);
	xml_stream.setAutoFormatting(true);
	xml_stream.writeStartDocument();

	xml_stream.writeNamespace("http://www.gnumeric.org/v10.dtd", "gmr");
	xml_stream.writeNamespace("http://www.w3.org/2001/XMLSchema-instance",
			"xsi");
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Workbook");
	xml_stream.writeAttribute("http://www.w3.org/2001/XMLSchema-instance",
			"schemaLocation", "http://www.gnumeric.org/v8.xsd");

	//fichier
	//		<< "<gmr:Workbook xmlns:gmr=\"http://www.gnumeric.org/v10.dtd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.gnumeric.org/v8.xsd\">"
	//		<< endl;

	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd",
			"Attributes");
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Attribute");
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"WorkbookView::show_horizontal_scrollbar");
	//fichier << "<gmr:Attributes>" << endl;
	//fichier << "   <gmr:Attribute>" << endl;
	//fichier << "<gmr:name>WorkbookView::show_horizontal_scrollbar</gmr:name>"
	//		<< endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "type", "4");
	//fichier << " <gmr:type>4</gmr:type>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "value",
			"TRUE");
	//fichier << "  <gmr:value>TRUE</gmr:value>" << endl;
	xml_stream.writeEndElement();
	//	fichier << " </gmr:Attribute>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Attribute");
	//fichier << " <gmr:Attribute>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"WorkbookView::show_vertical_scrollbar");
	//fichier << "  <gmr:name>WorkbookView::show_vertical_scrollbar</gmr:name>"
	//	<< endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "type", "4");
	//fichier << "  <gmr:type>4</gmr:type>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "value",
			"TRUE");
	//fichier << "  <gmr:value>TRUE</gmr:value>" << endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Attribute>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Attribute");
	//fichier << " <gmr:Attribute>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"WorkbookView::show_notebook_tabs");
	//fichier << "   <gmr:name>WorkbookView::show_notebook_tabs</gmr:name>"
	//		<< endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "type", "4");
	//fichier << "   <gmr:type>4</gmr:type>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "value",
			"TRUE");
	//fichier << "   <gmr:value>TRUE</gmr:value>" << endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Attribute>" << endl;

	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Attribute");
	//fichier << " <gmr:Attribute>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"WorkbookView::do_auto_completion");
	//fichier << "   <gmr:name>WorkbookView::do_auto_completion</gmr:name>"
	//		<< endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "type", "4");
	//fichier << "   <gmr:type>4</gmr:type>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "value",
			"TRUE");
	//fichier << "   <gmr:value>TRUE</gmr:value>" << endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Attribute>" << endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Attributes>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Summary");
	//fichier << " <gmr:Summary>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Item");
	//fichier << "  <gmr:Item>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"biology softwares");
	//fichier << "  <gmr:name>biology softwares</gmr:name>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd",
			"val-string", "http://www.pge.cnrs-gif.fr/bioinfo");
	//fichier
	//		<< "  <gmr:val-string>http://www.pge.cnrs-gif.fr/bioinfo</gmr:val-string>"
	//		<< endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Item>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Item");
	//fichier << " <gmr:Item>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"author");
	//fichier << "   <gmr:name>author</gmr:name>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd",
			"val-string", "Olivier Langella <Olivier.Langella@moulon.inra.fr>");
	//fichier
	//		<< "   <gmr:val-string>Olivier Langella, Olivier.Langella@pge.cnrs-gif.fr</gmr:val-string>"
	//		<< endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Item>" << endl;
	xml_stream.writeEndElement();
	//fichier << "</gmr:Summary>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd",
			"SheetNameIndex");
	//fichier << "<gmr:SheetNameIndex>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "SheetName",
			"Matrix 1");
	//fichier << "  <gmr:SheetName>Matrix 1</gmr:SheetName>" << endl;
	xml_stream.writeEndElement();
	//fichier << "</gmr:SheetNameIndex> " << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Sheets");
	//fichier << "<gmr:Sheets>	 " << endl;
	//	fichier.setf(ios::scientific);

	QString sheetname("Matrix 1");
	oGnumericSheet(xml_stream, sheetname);

	//fichier << " </gmr:Sheets> " << endl;
	//fichier << "</gmr:Workbook> " << endl;

	xml_stream.writeEndDocument();

	fichier << p_output_xml->toStdString();
	delete (p_output_xml);

}

void Matrice::oGnumericSheet(QXmlStreamWriter& xml_stream,
		const QString & sheetname) const {

	qDebug()
			<< "Matrice<T>::oGnumericSheet(QXmlStreamWriter& xml_stream, const QString & sheetname) begin";
	unsigned long i, j, irow(0), jcol(0);
	const QString value_format("0.000000");

	/*fichier << "<gmr:Sheet ";
	 fichier
	 << "DisplayFormulas=\"false\" HideZero=\"false\" HideGrid=\"false\" HideColHeader=\"false\" HideRowHeader=\"false\" DisplayOutlines=\"true\" OutlineSymbolsBelow=\"true\" OutlineSymbolsRight=\"true\">"
	 << endl;*/
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Sheet");
	xml_stream.writeAttribute("DisplayFormulas", "false");
	xml_stream.writeAttribute("HideZero", "false");
	xml_stream.writeAttribute("HideGrid", "false");
	xml_stream.writeAttribute("HideColHeader", "false");
	xml_stream.writeAttribute("HideRowHeader", "false");
	xml_stream.writeAttribute("DisplayOutlines", "true");
	xml_stream.writeAttribute("OutlineSymbolsBelow", "true");
	xml_stream.writeAttribute("OutlineSymbolsRight", "true");

	/*_p_xml_stream->writeAttribute("xml", "lang", "en");
	 _p_xml_stream->writeStartElement("body");
	 _p_xml_stream->writeStartElement("table");
	 _p_xml_stream->writeStartElement("tbody");*/

	// 	fichier.imbue();
	//	fichier << "<gmr:Name>" << sheetname << "</gmr:Name>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "Name",
			sheetname);

	//fichier << "<gmr:MaxCol>" << (GetNC() + 2) << "</gmr:MaxCol>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "MaxCol",
			QString::number(GetNC() + 2));
	//fichier << "<gmr:MaxRow>" << (GetNL() + 5 + _titre.size())
	//		<< "</gmr:MaxRow>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "MaxRow",
			QString::number((GetNL() + 5 + _titre.size())));
	//fichier << "<gmr:Zoom>1.000000</gmr:Zoom>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "Zoom",
			"1.000000");

	//fichier << "<gmr:Names/>" << endl;
	xml_stream.writeEmptyElement("http://www.gnumeric.org/v10.dtd", "Names");

	//fichier << "<gmr:Cells>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Cells");
	// �criture du titre
	for (i = 0; i < _titre.size(); i++, irow++) {
		xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Cell");
		//fichier << "<gmr:Cell Col=\"0\" Row=\"" << irow
		//		<< "\" ValueType=\"60\">";
		xml_stream.writeAttribute("Row", QString::number(irow));
		xml_stream.writeAttribute("Col", "0");
		xml_stream.writeAttribute("ValueType", "60");
		//fichier << _titre[i];
		xml_stream.writeCharacters(_titre[i].c_str());
		//fichier << "</gmr:Cell>" << endl;
		xml_stream.writeEndElement();
	}
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Cell");
	xml_stream.writeAttribute("Col", "0");
	xml_stream.writeAttribute("Row", QString::number(irow));
	xml_stream.writeAttribute("ValueType", "60");
	xml_stream.writeCharacters("#");
	xml_stream.writeEndElement();

	//fichier << "<gmr:Cell Col=\"0\" Row=\"" << irow
	//		<< "\" ValueType=\"60\">#</gmr:Cell>";
	if ((_flag == 2) || (_flag == 3)) {
		//�tiquettes des colonnes
		jcol = 1;
		xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Cell");
		xml_stream.writeAttribute("Col", QString::number(jcol));
		xml_stream.writeAttribute("Row", QString::number(irow));
		xml_stream.writeAttribute("ValueType", "60");
		xml_stream.writeCharacters(_tcol[0].c_str());
		xml_stream.writeEndElement();

		//fichier << "<gmr:Cell Col=\"" << jcol << "\" Row=\"" << irow
		//		<< "\" ValueType=\"60\">";
		//fichier << _tcol[0];
		//fichier << "</gmr:Cell>" << endl;
		jcol++;
		for (i = 1; i < _nc; i++, jcol++) {
			xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd",
					"Cell");
			xml_stream.writeAttribute("Col", QString::number(jcol));
			xml_stream.writeAttribute("Row", QString::number(irow));
			xml_stream.writeAttribute("ValueType", "60");
			xml_stream.writeCharacters(_tcol[i].c_str());
			xml_stream.writeEndElement();
			//fichier << "<gmr:Cell Col=\"" << jcol << "\" Row=\"" << irow
			//		<< "\" ValueType=\"60\">";
			//fichier << _tcol[i];
			//fichier << "</gmr:Cell>" << endl;
		}
	}
	irow++;

	//fichier.setf(ios::scientific);
	//�criture de la matrice
	for (i = 0; i < _nl; i++, irow++) {
		if ((_flag == 1) || (_flag == 3)) {
			//�tiquettes des lignes
			xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd",
					"Cell");
			xml_stream.writeAttribute("Col", "0");
			xml_stream.writeAttribute("Row", QString::number(irow));
			xml_stream.writeAttribute("ValueType", "60");
			xml_stream.writeCharacters(_tlig[i].c_str());
			xml_stream.writeEndElement();
			//fichier << "<gmr:Cell Col=\"0\" Row=\"" << irow
			//		<< "\" ValueType=\"60\">";
			//fichier << _tlig[i];
			//fichier << "</gmr:Cell>" << endl;
		}
		jcol = 1;
		for (j = 0; j < _nc; j++, jcol++) {
			//			fichier << '\t' << _tab [i * _nc + j];
			xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd",
					"Cell");
			xml_stream.writeAttribute("Col", QString::number(jcol));
			xml_stream.writeAttribute("Row", QString::number(irow));
			xml_stream.writeAttribute("ValueType", "40");
			xml_stream.writeAttribute("ValueFormat", value_format);
			xml_stream.writeCharacters(QString::number((double) GetCase(i, j)));
			xml_stream.writeEndElement();
			//fichier << "<gmr:Cell Col=\"" << jcol << "\" Row=\"" << irow
			//		<< "\" ValueType=\"40\" ValueFormat=\"" << value_format
			//		<< "\">";
			//fichier << GetCase(i, j);
			//fichier << "</gmr:Cell>" << endl;
		}
		//fichier << endl;
	}
	//fichier << "</gmr:Cells>" << endl;
	//fichier << " </gmr:Sheet> " << endl;
	qDebug()
			<< "Matrice<T>::oGnumericSheet(QXmlStreamWriter& xml_stream, const QString & sheetname) end";

}

void Matrice::oNtsys(ostream& sortie) {
	unsigned long i, j, k, tmaxligne(100);
	long pos;

	//	sortie << setf(ios::fixed);

	// �criture du titre
	for (i = 0; i < _titre.size(); i++) {
		sortie << "\"";
		sortie << _titre[i];
		sortie << endl;
	}

	sortie << _type << " " << _nl;
	if ((_flag == 1) || (_flag == 3))
		sortie << "L";

	sortie << " " << _nc;
	if ((_flag == 2) || (_flag == 3))
		sortie << "L";

	sortie << " " << _miss << endl;

	//�criture des �tiquettes, lignes puis colonnes
	if ((_flag == 1) || (_flag == 3)) {
		//�tiquettes des lignes
		pos = sortie.tellp();
		sortie << _tlig[0];
		for (i = 1; i < _nl; i++) {
			sortie << " " << _tlig[i];
			j = sortie.tellp();
			if ((j - pos) > tmaxligne) {
				sortie << endl;
				pos = j;
			}
		}
		sortie << endl;
	}

	if ((_flag == 2) || (_flag == 3)) {
		//�tiquettes des colonnes
		pos = sortie.tellp();
		sortie << _tcol[0];
		for (i = 1; i < _nc; i++) {
			sortie << " " << _tcol[i];
			j = sortie.tellp();
			if ((j - pos) > tmaxligne) {
				sortie << endl;
				pos = j;
			}
		}
		sortie << endl;
	}

	//�criture de la matrice
	switch (_type) {
	case 2:
		// matrice triangulaire
		// attention, ne sort que la partie triangle du bas
		for (i = 0; i < _nc; i++) {
			pos = sortie.tellp();
			sortie << _tab[i * _nc];
			for (j = 1; j <= i; j++) { //scan d'une moiti� (triangle)
				//[ligne i] [colonne j] triangle du bas
				sortie << " " << _tab[(i * _nc) + j];
				k = sortie.tellp();
				if ((k - pos) > tmaxligne) {
					sortie << endl;
					pos = k;
				}

			}
			sortie << endl;
		}
		break;

	case 1:
		for (i = 0; i < _nl; i++) {

			pos = sortie.tellp();
			sortie << _tab[i * _nc];
			for (j = 1; j < _nc; j++) {
				sortie << " " << _tab[i * _nc + j];
				k = sortie.tellp();
				if ((k - pos) > tmaxligne) {
					sortie << endl;
					pos = k;
				}
			}
			sortie << endl;
		}
		break;

	default:
		break;
	}
}

long double Matrice::get_ppvaleur() const {
	//retourne la plus petite valeur de la matrice
	unsigned long taille(_nc * _nl);
	unsigned long j;
	long double ppvaleur(_tab[0]);

	for (j = 1; j < taille; j++)
		if (_tab[j] < ppvaleur)
			ppvaleur = _tab[j];
	return (ppvaleur);
}

void Matrice::f_neg2zero() {
	//remet � z�ro les chiffres n�gatifs
	unsigned long taille(_nc * _nl);
	unsigned long j(_nc * _nl);

	for (j = 0; j < taille; j++)
		if (_tab[j] < 0)
			_tab[j] = 0;
}

void Matrice::iGnumeric(istream& entree) {
	//lecture de matrices contenues dans les fichiers Gnumeric XML
#ifdef XmlParse_INCLUDED
	//entree.seekg(0);

	//cerr << "void Matrice<long double>::iGnumeric(istream& entree) 1" << endl;

	try {
		olivxml::ImportGnumeric parser;
		parser.iParseFlux(entree);
		*this = parser.get_set_of_matrix().GetConstMatrice(0);
	}
	catch (olivxml::ImportGnumeric::Anomalie pb) {
		throw Anomalie(1);
	}
	//cerr << "void Matrice<long double>::iGnumeric(istream& entree)" << endl;
	//cerr << "void Matrice<long double>::iGnumeric(istream& entree) apres" << endl;
#else
	throw Anomalie(1);
#endif
}

void Matrice::iNtsys(istream& entree) {
	//lecture de matrices contenues dans les fichiers NTSYS
	char car;
	ChaineCar mot;
	ChaineCar sousmot;
	int titres; //1=> titres des lignes 2=> titres des colonnes
	//3=> les 2 //0=> rien
	unsigned long i, j, nc, nl;
	int miss, type;

	//cerr << "Matrice<T>::iNtsys(istream& entree)" << endl;
	entree.seekg(0);

	car = entree.peek();
	//	entree.get(car);
	//	while ((car != '"') && (entree.eof()==0))	entree.get(car);
	while ((car == '"') && (entree.eof() == 0)) {
		entree.get(car);
		GetLigneFlot(entree, mot);
		//		entree.getline(mot,200,'\n');
		_titre.push_back(mot);
		//		entree.get(car);
		car = entree.peek();
	}
	//cerr << "Matrice<T>::iNtsys(istream& entree) 2" << endl;
	if ((entree.eof() != 0) || (entree.fail()))
		throw Anomalie(1);//erreur de lecture
	//cerr << "Matrice<T>::iNtsys(istream& entree) 3" << endl;

	//	mot[0] = car;
	//	mot[1] = '\0';
	//	type = atoi(mot);

	GetLigneFlot(entree, mot); //ligne 0 L23 L34 missing_value
	if ((mot.GetNbMots() != 4) || (entree.fail()) || (entree.eof() != 0))
		throw Anomalie(1);

	mot.GetMot(1, sousmot);
	type = atoi(sousmot.c_str());
	if ((_type > 2) || (_type < 0))
		throw Anomalie(1);

	titres = 0;
	//nombre de lignes
	mot.GetMot(2, sousmot);
	//	entree >> mot;
	if (sousmot[sousmot.size() - 1] == 'L') {
		sousmot.Remplacer("L", "");
		titres = 1;
		//		strcpy(mot + strlen(mot) - 1,"");
	}
	nl = atoi(sousmot.c_str());
	if ((nl > 9999) || (nl < 1))
		throw Anomalie(1);

	//nombre de colonnes
	mot.GetMot(3, sousmot);
	if (sousmot[sousmot.size() - 1] == 'L') {
		sousmot.Remplacer("L", "");
		titres = titres + 2;
		//		strcpy(mot + strlen(mot) - 1,"");
	}
	nc = atoi(sousmot.c_str());
	if ((nc > 9999) || (nc < 1))
		throw Anomalie(1);

	//	entree >> mot; //missing value
	mot.GetMot(4, sousmot);
	miss = atoi(mot.c_str());

	resize(nl, nc);
	//cerr << "Matrice<T>::iNtsys(istream& entree) nc nl " << _nc << _nl << endl;

	_miss = miss;
	_type = type;

	_flag = titres;
	//cerr << "Matrice<T>::iNtsys(istream& entree) 2" << endl;
	//lecture des �tiquettes, lignes puis colonnes
	if ((titres == 1) || (titres == 3)) {
		//�tiquettes des lignes
		for (i = 0; i < _nl; i++) {
			entree >> _tlig[i];
			//cerr << "Matrice<T>::iNtsys(istream& entree) _tlig " << _tlig[i] << endl;
			if (entree.fail())
				throw Anomalie(1);//erreur de lecture
			//			_tlig[i].assign(mot);
		}
	}
	//cerr << "Matrice<T>::iNtsys(istream& entree) 3" << endl;

	if ((titres == 2) || (titres == 3)) {
		//�tiquettes des colonnes
		for (i = 0; i < _nc; i++) {
			entree >> _tcol[i];
			//cerr << "Matrice<T>::iNtsys(istream& entree) tcol " << _tcol[i] << endl;
			if (entree.fail())
				throw Anomalie(1);//erreur de lecture
		}
	}

	//lecture de la matrice proprement dite
	switch (_type) {
	case 1:
		// cas des matrices rectangulaires ou carr�es
		_t = _nc * _nl;
		//		long double chiffre;

		for (i = 0; i < _t; i++) {
			entree >> _tab[i];
			if (entree.fail())
				throw Anomalie(1);//erreur de lecture
			//	_tab[i] = (T) chiffre;
			//	_tab[i] =  atof (mot);
		}
		break;

	case 2:
		// cas des matrices triangulaires
		if (_flag == 2)
			_tlig = _tcol;
		if (_flag == 1)
			_tcol = _tlig;

		entree.clear();

		for (i = 0; i < _nc; i++) {
			for (j = 0; j <= i; j++) {
				//				entree >> (long double) _tab[(i*_nc) + j];
				entree >> _tab[(i * _nc) + j];
				//cerr << "Matrice<T>::iNtsys(istream& entree) 4 " << _tab[(i*_nc) + j] << " " << i << " " << j << endl;
				if (entree.fail())
					throw Anomalie(1);//erreur de lecture
				_tab[(j * _nc) + i] = _tab[(i * _nc) + j];
			}
		}
		break;

	default:
		throw Anomalie(1);
		break;
	}

}

void Matrice::iPhylip(istream& entree) {
	//lecture de matrices contenues dans des fichiers Phylip
	ChaineCar mot;
	ChaineCar sousmot;
	unsigned long nbmot;
	unsigned long i, j;
	long nl(0), nc(0), top(0);

	//	entree.seekg(0);
	entree.clear();

	//cerr << "Matrice<T>::iPhylip(istream& entree)" << endl;
	mot.GetLigneFlot(entree);

	//cerr << "Matrice<T>::iPhylip(istream& entree) 2" << endl;
	nbmot = mot.GetNbMots();
	if ((nbmot < 1) || (nbmot > 2))
		throw Anomalie(1);

	mot.GetMot(1, sousmot);
	if (sousmot.EstUnChiffre() == false)
		throw Anomalie(1);
	nl = atol(sousmot.c_str());

	//cerr << "Matrice<T>::iPhylip(istream& entree) 3" << endl;
	_flag = 0;
	if (nbmot == 1) {
		resize(nl, nl);
		//		_type = 3;
	} else {
		mot.GetMot(2, sousmot);
		if (sousmot.EstUnChiffre() == false)
			throw Anomalie(1);
		nc = atol(sousmot.c_str());
		resize(nl, nc);
	}
	//cerr << nl << " " << nc << endl;
	top = entree.tellg();
	//	GetLigneFlot(entree, mot);
	GetLigneFlot(entree, mot);
	mot.GetMot(1, sousmot);
	//cerr << "Matrice<T>::iPhylip(istream& entree) coucou 1 " << sousmot << endl;
	if (sousmot.EstUnChiffre())
		_flag = 0;
	else { // titre de ligne
		_flag = 1;
		_tlig.resize(nl);
	}
	/*	nbmot = mot.GetNbMots();
	 if (nbmot == (_nc + 1)) {
	 _flag = 1;
	 }
	 else if (nbmot == _nc) {
	 _flag = 0;
	 }
	 else throw Anomalie(1);
	 */
	entree.seekg(top);

	for (i = 0; i < _nl; i++) {
		if ((_flag == 1) || (_flag == 3))
			entree >> _tlig[i];
		//cerr << "Matrice<T>::iPhylip(istream& entree) coucou 2 " << _tlig[i] << endl;
		if (entree.fail())
			throw Anomalie(1);//erreur de lecture
		for (j = 0; j < _nc; j++) {
			entree >> GetCase(i, j);
			if (entree.fail())
				throw Anomalie(1);//erreur de lecture
		}
	}
	SetType(1);
	SetType(2);

	//cerr << "Matrice<T>::iPhylip(istream& entree) fin" << endl;

}

void Matrice::iExcel(istream& entree) {
	//lecture de matrices contenues dans des fichiers Excel
	// la matrice doit �tre indiqu�e par "/" ou "#" et commencer
	// 1 case en dessous et � gauche.
	char car;
	qDebug() << "Matrice<T>::iExcel(istream& entree) begin";
	ChaineCar mot;
	//	char mot[200];
	//	string ligne;
	//1=> titres des lignes 2=> titres des colonnes
	//3=> les 2 //0=> rien
	unsigned long i, j;
	long nc(0), nl(0);
	long debut, top;

	entree.seekg(0);
	qDebug() << "Matrice<T>::iExcel(istream& entree) 1";

	entree.get(car);
	//	while ((car != '"') && (entree.eof()==0))	entree.get(car);
	while (((car != '/') && (car != '#')) && (entree.good())) {
		//		mot = car;
		GetLigneFlot(entree, mot);
		mot = car + mot;
		_titre.push_back(mot);
		entree.get(car);
	}

	qDebug() << "Matrice<T>::iExcel(istream& entree) 2";
	//cerr << "coucou excel 2";
	if (entree.fail())
		throw Anomalie(1);//erreur de lecture
	nc = 0;
	nl = 0;
	_flag = 0;
	debut = entree.tellg();
	GetLigneFlot(entree, mot);
	if ((mot[0] > 4) && (mot[1] != '\t')) {
		_flag = 2; //il ya des titres de colonnes
	}
	if (entree.eof() != 0)
		throw Anomalie(1);//erreur de lecture
	//cerr << "coucou " << mot << endl ;
	qDebug() << "Matrice<T>::iExcel(istream& entree) 3 " << mot.c_str();

	top = entree.tellg();
	//cerr << top << endl;

	GetLigneFlot(entree, mot);
	for (i = 0; i < mot.size(); i++) {
		if (mot[i] > 64) {
			_flag++; //il ya les titres des lignes
			//cerr << mot << endl;
			break;
		}
	}
	qDebug() << "Matrice<T>::iExcel(istream& entree) 4 ";

	//determination du nombre de colonnes:
	nc = 0;
	entree.seekg(top);
	entree.clear();
	if ((_flag == 1) || (_flag == 3)) {
		entree >> mot;
	}
	car = '3';
	GetLigneFlot(entree, mot);
	nc = mot.GetNbMots();
	//cerr << " nc " << nc << endl;
	qDebug() << "Matrice<T>::iExcel(istream& entree) 5 nc " << nc;

	//cerr << "coucou " << mot << endl ;
	//	if (entree.eof() != 0) throw Anomalie(1);//erreur de lecture
	//cerr << "coucou2 " << mot << endl ;
	//determination du nombre de lignes:
	nl = 1;
	entree.seekg(top);
	GetLigneFlot(entree, mot);
	entree >> mot;
	while ((mot.GetNbMots() > 0) && (entree.eof() == 0)) {
		GetLigneFlot(entree, mot);
		nl++;
		entree >> mot;
		//cerr << mot << endl;
		//cin >> i;
	}
	entree.clear();

	qDebug() << "Matrice<T>::iExcel(istream& entree) 6 nl " << nl << " nc "
			<< nc;
	//cerr << nl << endl;
	//cerr << nc << endl;

	//  on a le nb de colonnes, le nb de lignes, les �tiquettes,
	// remplissons !!!
	resize(nl, nc);
	entree.clear();

	if ((_flag == 2) || (_flag == 3)) { //saisie des titres des colonnes
		entree.seekg(debut);
		//		entree >> _tcol[i];
		for (i = 0; i < _nc; i++) {
			entree >> _tcol[i];
			//cerr << _tcol[i] << endl;
			if (entree.fail())
				throw Anomalie(1);//erreur de lecture
		}
	}
	entree.clear();

	qDebug() << "Matrice<T>::iExcel(istream& entree) 7 ";

	//	entree.seekg(top);
	entree.seekg(debut);
	GetLigneFlot(entree, mot);
	//cerr << "coucou" << top << endl;
	for (i = 0; i < _nl; i++) {
		if ((_flag == 1) || (_flag == 3))
			entree >> _tlig[i];
		//cerr << _tlig[i] << endl;
		for (j = 0; j < _nc; j++) {
			entree >> _tab[(i * _nc) + j];
			//cerr << _tab[(i * _nc) + j] << endl;
			if (entree.fail())
				throw Anomalie(1);//erreur de lecture
		}
	}
	qDebug() << "Matrice<T>::iExcel(istream& entree) 8 ";

	//try {
	SetType(1);
	SetType(2);
	//} catch (biolib::vecteurs::Matrice<T>::Anomalie erreur) {
	//	cerr << erreur.fmessage(erreur.le_pb);
	//SetType(1);
	//}
}

void Matrice::resize(unsigned long nblig,
		unsigned long nbcol) {
	unsigned long i;

	if (_tab != 0)
		delete[] _tab;

	if (_nl > nblig)
		_tlig.erase(_tlig.begin() + _nl, _tlig.end());
	if (_nc > nbcol)
		_tcol.erase(_tcol.begin() + _nc, _tcol.end());

	_tcol.reserve(nbcol);
	_tlig.reserve(nblig);

	for (i = _nc; i < nbcol; i++)
		_tcol.push_back("");
	for (i = _nl; i < nblig; i++)
		_tlig.push_back("");

	_nc = nbcol;
	_nl = nblig;
	_t = _nc * _nl;
	_tab = new long double[_t];
	//	_miss = 0;
	//	_flag = 0;

	for (i = 0; i < _t; i++)
		_tab[i] = 0;

}

bool Matrice::redim(unsigned long nblig,
		unsigned long nbcol) {
	unsigned long i, j, t;
	long double* Ptab;

	if (_tab == 0)
		return (false);
	if ((_type == 3) && (nblig != nbcol))
		return (false);

	if (_nl > nblig)
		_tlig.erase(_tlig.begin() + _nl, _tlig.end());
	if (_nc > nbcol)
		_tcol.erase(_tcol.begin() + _nc, _tcol.end());

	_tcol.reserve(nbcol);
	_tlig.reserve(nblig);
	for (i = _nc; i < nbcol; i++)
		_tcol.push_back("");
	for (i = _nl; i < nblig; i++)
		_tlig.push_back("");

	Ptab = _tab;
	t = nblig * nbcol;
	_tab = new long double[t];

	for (i = 0; i < nblig; i++) {
		for (j = 0; j < nbcol; j++) {
			if ((j < _nc) && (i < _nl))
				*(_tab + (i * nbcol) + j) = *(Ptab + (i * _nc) + j);
			else
				*(_tab + (i * nbcol) + j) = 0;
		}
	}

	delete[] Ptab;
	_nc = nbcol;
	_nl = nblig;
	_t = t;
	return (true);
}

void Matrice::fslig(vector<long double>& somme) const {

	int i, j;

	if (_type == 3)
		throw Anomalie(3); //op�ration impossible sur ce type de matrice

	if (somme.size() < _nl)
		somme.resize(_nl);

	for (i = 0; i < _nl; i++) {
		somme[i] = _tab[i * _nc];
	}
	for (j = 1; j < _nc; j++) {
		for (i = 0; i < _nl; i++) {
			somme[i] += _tab[j + (i * _nc)];
		}
	}
}

void Matrice::fscol(vector<long double>& somme) const {

	int pos, i, j;

	if (_type == 3)
		throw Anomalie(3); //op�ration impossible sur ce type de matrice

	if (somme.size() < _nc)
		somme.resize(_nc);

	for (i = 0; i < _nc; i++) {
		somme[i] = _tab[i];
	}
	pos = _nc;
	for (j = 1; j < _nl; j++) {
		for (i = 0; i < _nc; i++) {
			somme[i] += _tab[pos];
			pos++;
		}
	}
}

void Matrice::ftranspose() {
	//transposition de matrices:

	Titre swap;
	unsigned long i, j;

	swap = _tcol;
	_tcol = _tlig;
	_tlig = swap;

	if (_type == 3)
		return;

	//_flag = 2;
	if (_flag == 1)
		_flag = 2;
	else if (_flag == 2)
		_flag = 1;

	long double* Ptab;
	Ptab = new long double[_t];

	for (i = 0; i < _nl; i++) {
		for (j = 0; j < _nc; j++) {
			*(Ptab + (j * _nl) + i) = *(_tab + rindice(i, j));
		}
	}

	i = _nc;
	_nc = _nl;
	_nl = i;

	delete[] _tab;
	_tab = Ptab;
}

Matrice Matrice::operator*(Matrice &rval) const {

	//produit matriciel
	Matrice Resultat(_nl, rval._nc);
	//	long double limite(1e-030);

	if (_nc != rval._nl)
		throw Anomalie(4); // 4-> calcul impossible
	//	if (_nl != rval._nc) throw Anomalie(4); // 4-> calcul impossible

	int i, j, k; //ligne, colonne


	Resultat.SetFlag(0);
	if ((rval.GetFlag() == 2) || (rval.GetFlag() == 3)) {
		Resultat._tcol = rval._tcol;
		Resultat.SetFlag(2);
	}
	if ((_flag == 1) || (_flag == 3)) {
		Resultat._tlig = _tlig;
		Resultat._flag++;
	}

	for (i = 0; i < _nl; i++) {
		for (j = 0; j < rval._nc; j++) {
			Resultat.GetCase(i, j) = 0;
			for (k = 0; k < _nc; k++) {
				Resultat.GetCase(i, j) = Resultat.GetCase(i, j)
						+ ((long double) GetCase(i, k) * rval.GetCase(k, j));
			}
		}
	}

	//v�rification limite
	/*	for (i=0; i < _t; i++) {
	 if (Resultat._tab[i] < limite) Resultat._tab[i] = 0;
	 }*/

	return Resultat;
}

vector<long double> Matrice::operator*(const vector<long double> &rval) {
	//produit d'une matrice par un vecteur

	vector<long double> Resultat;
	Matrice& lamatrice = *this;
	long i, k; //ligne, colonne

	Resultat.resize(lamatrice._nl);

	if (lamatrice._nl != rval.size())
		throw Anomalie(4); // 4-> calcul impossible


	for (i = 0; i < Resultat.size(); i++) {
		Resultat[i] = 0;
		for (k = 0; k < lamatrice._nc; k++) {
			Resultat[i] = Resultat[i] + (lamatrice.GetCase(i, k) * rval[i]);
		}
	}

	return Resultat;
}

Matrice Matrice::operator*(long double scalaire) {

	Matrice Resultat(_nl, _nc);
	long i;

	//	Resultat.resize(_nl,_nc);
	//	cout << "coucou";
	Resultat.SetType(1);
	Resultat._titre = _titre;
	//	Resultat._titre.push_back("Produit par un scalaire");
	Resultat._flag = 0;

	if ((_flag == 2) || (_flag == 3)) {
		//copie des �tiquettes des colonnes
		Resultat._flag = 2;
		Resultat._tcol = _tcol;
		Resultat._tlig = _tcol;
	}

	for (i = 0; i < _t; i++) {
		Resultat._tab[i] = _tab[i] * scalaire;
	}

	return Resultat;
}

Matrice Matrice::operator-(Matrice& rval) {

	Matrice Resultat(_nl, _nc);
	long i;

	if (_nl != rval._nl)
		throw Anomalie(4);
	if (_nc != rval._nc)
		throw Anomalie(4);

	//	cout << "coucou";
	Resultat.SetType(_type);
	Resultat._titre = _titre;
	//	Resultat._titre.push_back("Produit par un scalaire");
	Resultat._flag = _flag;

	if ((_flag == 2) || (_flag == 3)) {
		//copie des �tiquettes des colonnes
		Resultat._tcol = _tcol;
	}
	if ((_flag == 1) || (_flag == 3)) {
		//copie des �tiquettes des lignes
		Resultat._tlig = _tlig;
	}

	for (i = 0; i < _t; i++) {
		Resultat._tab[i] = _tab[i] - rval._tab[i];
	}

	return Resultat;

}

Matrice Matrice::operator+(Matrice &rval) {
	long i;

	Matrice Resultat;

	if (_nl != rval._nl)
		throw Anomalie(4);
	if (_nc != rval._nc)
		throw Anomalie(4);

	Resultat.resize(_nl, _nc);
	//	cout << "coucou";
	Resultat.SetType(_type);
	Resultat._titre = _titre;
	//	Resultat._titre.push_back("Produit par un scalaire");
	Resultat._flag = _flag;

	if ((_flag == 2) || (_flag == 3)) {
		//copie des �tiquettes des colonnes
		Resultat._tcol = _tcol;
	}
	if ((_flag == 1) || (_flag == 3)) {
		//copie des �tiquettes des lignes
		Resultat._tlig = _tlig;
	}

	for (i = 0; i < _t; i++) {
		Resultat._tab[i] = _tab[i] + rval._tab[i];
	}

	return Resultat;

}

long double Matrice::fdet() const {
	//calcul du d�terminant d'une matrice par r�cursivit
	// Olivier Langella 29 oct 98
	// D'apr�s J. Lefebvre "introduction aux analyses statistiques
	// multidimensionnelle" p 36
	long double det;
	if (_nc != _nl)
		throw Anomalie(4); //calcul impossible

	MatriceLD calculs;

	calculs = *this;

	det = calculs.fdetrec();

	return (det);
}

long double Matrice::fdetrec() const {
	//calcul du d�terminant d'une matrice par r�cursivit
	// utilis� par fdet;
	long double det(0);
	unsigned long i;
	long cofacteur(1);
	Matrice calculs;

	if (_nc == 2) {
		//solution
		det = ((long double) GetCase(0, 0) * GetCase(1, 1))
				- ((long double) GetCase(1, 0) * GetCase(0, 1));
		return (det);
	} else {

		for (i = 0; i < _nl; i++) {
			calculs = *this;
			calculs.SupprCol(0);
			calculs.SupprLig(i);

			det = det + ((long double) calculs.fdetrec()
					* ((long double) GetCase(i, 0) * cofacteur));
			cofacteur = cofacteur * -1;
		}
		return (det);
	}
}

void Matrice::SupprCol(unsigned long nbcol) {
	unsigned long i, j, k, n;
	long double * Ptab;

	//	if (_nl > nblig) _tlig.erase(_tlig.begin() + _nl,_tlig.end());
	if (nbcol < _tcol.size())
		_tcol.erase(_tcol.begin() + nbcol);

	n = _nc - 1;

	Ptab = new long double[n * _nl];
	k = 0;

	for (i = 0; i < _nl; i++) {
		for (j = 0; j < _nc; j++) {
			if (j != nbcol) {
				Ptab[k] = GetCase(i, j);
				k++;
			}
		}
	}

	_nc = _nc - 1;
	_t = _nc * _nl;

	if (_tab != 0)
		delete[] _tab;
	_tab = Ptab;
	_type = 1;

}

void Matrice::SupprLig(unsigned long nblig) {
	unsigned long i, j, k, n;
	long double* Ptab;

	//	if (_nl > nblig) _tlig.erase(_tlig.begin() + _nl,_tlig.end());
	if (nblig < _tlig.size())
		_tlig.erase(_tlig.begin() + nblig);

	n = _nl - 1;

	Ptab = new long double[n * _nc];
	k = 0;

	for (i = 0; i < _nl; i++) {
		for (j = 0; j < _nc; j++) {
			if (i != nblig) {
				Ptab[k] = GetCase(i, j);
				k++;
			}
		}
	}

	_nl = _nl - 1;
	_t = _nc * _nl;

	if (_tab != 0)
		delete[] _tab;
	_tab = Ptab;
	_type = 1;

}

void MatriceLD::finv(MatriceLD& inverse) const {
	//calcul de l'inverse d'une matrice
	// Olivier Langella 29 oct 98
	// D'apr�s J. Lefebvre "introduction aux analyses statistiques
	// multidimensionnelle" p 42
	if (_nc != _nl)
		throw Anomalie(4); //calcul impossible

	long double detA;
	MatriceLD calculs;
	int cofacteur, cofl(-1);
	unsigned long i, j;

	inverse = *this;

	detA = fdet();

	for (i = 0; i < _nl; i++) {
		cofacteur = cofl;
		for (j = 0; j < _nc; j++) {
			cofacteur *= -1;
			calculs = *this;
			calculs.SupprCol(i);
			calculs.SupprLig(j);

			inverse.GetCase(i, j) = (calculs.fdet() * cofacteur) / detA;
		}

		cofl *= -1;
	}

}

void MatriceLD::fvalpropres(MatriceLD& vectpropres,
		vector<float>& valpropres, float precision) {

	//Calcul des valeurs propres pour une matrice sym�trique
	// M�thode de Jacobi
	// Olivier Langella 29 oct 98
	// D'apr�s J. Lefebvre "introduction aux analyses statistiques
	// multidimensionnelle" p 67
	// (m�thode it�rative)

	if (GetType() != 3)
		throw Anomalie(3); //calcul impossible
	//ATTENTION, ne v�rifie pas si la matrice est bien symetrique !!

	valpropres.resize(_nc);
	vectpropres.resize(_nc, _nc);
	vectpropres.SetType(1);
	MatriceLD matC;
	MatriceLD matA;
	matA = *this;

	matA._titre.push_back("Matrice A");
	matC._titre.push_back("Matrice C");
	vectpropres = vectpropres + 1;

	//it�rations de C'AC
	unsigned long poss, posr;
	long double temp, teta;
	unsigned long i, j, nc(_nc);
	long ind1, ind2;

	long double scarre(0), tracecar;

	for (i = 0; i < _t; i++) {
		scarre = scarre + (_tab[i] * _tab[i]);
	}

	matC.resize(nc, nc);
	MatriceLD matInter(nc, nc); //matrice pour les calculs
	//intermediaires
	do {
		// choix du point � annuler
		// : le plus grand non situ� sur la diagonale
		posr = 0;
		poss = 0;
		temp = -1;
		for (i = 1; i < nc; i++) {
			for (j = 0; j < i; j++) {
				teta = fabs(matA._tab[(i * nc) + j]);
				if (temp < teta) {
					temp = teta;
					poss = i;
					posr = j;
				}
			}
		}

		// calcul de teta
		teta = (matA._tab[(posr * nc) + poss] * 2) / (matA._tab[(posr * nc)
				+ posr] - matA._tab[(poss * nc) + poss]);
		teta = atan(teta) / 2;

		// fabriquer la matrice C'
		for (i = 0; i < nc; i++) {
			matC._tab[(i * nc) + i] = 1;
			if ((i == poss) || (i == posr)) {
				matC._tab[(i * nc) + i] = cos(teta);
			}
			for (j = 0; j < i; j++) {
				ind1 = (j * nc) + i;
				ind2 = (i * nc) + j;
				if ((i == poss) && (j == posr)) {
					matC._tab[ind1] = sin(teta);
					matC._tab[ind2] = matC._tab[ind1] * -1;
				} else {
					matC._tab[ind1] = 0;
					matC._tab[ind2] = 0;
				}
			}
		}

		//	matA = matC * matA;
		matInter.fmultiplier(matC, matA); // ajoute pour optimiser
		matC.ftranspose();
		//	matA = matA * matC;
		matA.fmultiplier(matInter, matC); // ajoute pour optimiser

		//	vectpropres = vectpropres * matC;
		for (i = 0; i < _t; i++) {
			matInter._tab[i] = vectpropres._tab[i];
		}
		vectpropres.fmultiplier(matInter, matC);

		tracecar = 0;
		for (i = 0; i < nc; i++) {
			teta = matA._tab[(i * nc) + i];
			tracecar = tracecar + (teta * teta);
		}
	} while (((scarre - tracecar) / tracecar) > precision);

	for (i = 0; i < _nc; i++) {
		valpropres[i] = matA.GetCase(i, i);
	}

}

long double Matrice::ftrace() const {
	//calcul de la trace d'une matrice (somme des E diagonaux)
	// Olivier Langella 29 oct 98
	if (_nc != _nl)
		throw Anomalie(4); //calcul impossible

	int i, j(0);

	long double res(0);

	for (i = 0; i < _nc; i++) {
		res += _tab[i + j];
		j += _nc;
	}

	return res;
}

Matrice Matrice::operator+(long double rval) {

	Matrice Resultat;

	Resultat = *this;
	unsigned long i;

	for (i = 0; i < _nc; i++) {
		Resultat.GetCase(i, i) = Resultat.GetCase(i, i) + rval;
	}

	return Resultat;

}

void Matrice::fswapcol(long i, long j) {
	long double swap;
	long k;

	for (k = 0; k < _nc; k++) {
		swap = GetCase(k, i);
		GetCase(k, i) = GetCase(k, j);
		GetCase(k, j) = swap;
	}
}

void Matrice::fmultiplier(const Matrice& matA,
		const Matrice& matB) {
	//pour multiplier 2 matrices plus rapidement
	// A et B sont carrees !!!!
	long i, j, k, nc(_nc);
	long double res;

	for (i = 0; i < nc; i++) {
		for (j = 0; j < nc; j++) {
			res = 0;
			for (k = 0; k < nc; k++) {
				res += matA._tab[(i * nc) + k] * matB._tab[(k * nc) + j];
			}
			_tab[(i * nc) + j] = res;
		}
	}
}

void Matrice::oXgobi(const string &fnom) {
	unsigned long i, j;
	ofstream fichier;
	//	string fnom(nomfichier);
	string fnomplus(fnom);

	if (_type != 1)
		throw Anomalie(3);

	fnomplus = fnom + ".dat";
	fichier.open(fnomplus.c_str(), ios::out);
	if (fichier.is_open() == false)
		throw Anomalie(6);

	for (i = 0; i < _nl; i++) {
		fichier << _tab[i * _nc];
		for (j = 1; j < _nc; j++) {
			fichier << " " << _tab[(i * _nc) + j];
		}
		fichier << endl;
	}

	fichier.close();

	if (_titre.size() > 0) {
		fnomplus = fnom + ".doc";
		fichier.open(fnomplus.c_str(), ios::out);
		if (fichier.is_open() == false)
			throw Anomalie(6);

		for (i = 0; i < _titre.size(); i++) {
			fichier << _titre[i];
			fichier << endl;
		}
		fichier.close();
	}

	if ((_flag == 1) || (_flag == 3)) {
		fnomplus = fnom + ".row";
		fichier.open(fnomplus.c_str(), ios::out);
		if (fichier.is_open() == false)
			throw Anomalie(6);

		for (i = 0; i < _tlig.size(); i++) {
			fichier << _tlig[i];
			fichier << endl;
		}

		fichier.close();
	}

	if ((_flag == 2) || (_flag == 3)) {
		fnomplus = fnom + ".col";
		fichier.open(fnomplus.c_str(), ios::out);
		if (fichier.is_open() == false)
			throw Anomalie(6);

		for (i = 0; i < _tcol.size(); i++) {
			fichier << _tcol[i];
			fichier << endl;
		}

		fichier.close();
	}

}

////////////////////////////////////////////////
// GLOBAL
///////////////////////////////////////////////
ostream& operator<<(ostream& sortie, Matrice& lamatrice) {
	//1= Excel
	//2= Ntsys
	//3= xgobi ==!!!! seulement en ofstream !!!!!

	lamatrice.oFormat(sortie, lamatrice._oformat);
	return (sortie);

}

ofstream& operator<<(ofstream& sortie, Matrice& lamatrice) {
	//1= Excel
	//2= Ntsys
	//3= xgobi  ==!!!! seulement en ofstream !!!!!

	if (lamatrice._oformat == 3) {
		lamatrice.oXgobi("xgobi");
	} else {
		lamatrice.oFormat(sortie, lamatrice._oformat);
	}
	return (sortie);

}

/*ofstream& operator<<(ofstream& sortie,MatriceLD& lamatrice) {
 //1= Excel
 //2= Ntsys
 //3= xgobi  ==!!!! seulement en ofstream !!!!!

 if (lamatrice._oformat == 3) {
 lamatrice.oXgobi("xgobi");
 }
 else {
 lamatrice.oFormat(sortie, lamatrice._oformat);
 }
 return(sortie);

 }*/

istream& operator>>(istream& ientree, Matrice& lamatrice) {

	//cerr << "coucou";
	lamatrice.iFichier(ientree);
	//cerr << "coucou";
	return (ientree);
}

void Matrice::oPhylip(ostream& fichier) {
	unsigned long i, j;

	fichier.setf(ios::scientific);

	/*	// �criture du titre
	 for (i=0; i < _titre.size();i++) {
	 fichier << _titre[i];
	 fichier << endl;
	 }*/
	if (_type == 3) { //matrice triangulaire
		fichier << '\t' << GetNL() << endl;
		_tlig = _tcol;
	} else {
		fichier << '\t' << GetNL() << '\t' << GetNC() << endl;
	}

	//	fichier << "#";
	/*	if ((_flag == 2)||(_flag == 3)){
	 //�tiquettes des colonnes
	 fichier << '\t' << _tcol[0];
	 for (i=1; i<_nc; i++) fichier << '\t' << _tcol[i];
	 }
	 fichier << endl;
	 */
	//�criture de la matrice
	for (i = 0; i < _nl; i++) {
		if ((_flag == 1) || (_flag == 3)) {
			//�tiquettes des lignes
			fichier << _tlig[i];
		}

		for (j = 0; j < _nc; j++) {
			fichier << '\t' << GetCase(i, j);
		}
		fichier << endl;
	}

}

void Matrice::iFichier(istream& ientree) {
	int nbformat(6), i(1);
	char car;
	bool autre(true);

	//	entree = ientree;
	qDebug() << "Matrice<T>::iFichier(istream& ientree) begin nbformat "
			<< nbformat;
	ientree.get(car);
	if (ientree.fail()) {
		//		cerr << "Le fichier n'a pas pu �tre ouvert... "<< endl;
		throw Anomalie(1);
	}
	while ((autre) & (i < nbformat)) {
		qDebug() << "Matrice<T>::iFichier(istream& ientree) ifichier " << i
				<< " autre " << autre;
		//cerr << "coucou ifichier"  << i << endl;
		if (i == 3) {
			i = 4;
			continue;
		} //xgobi
		try {
			ientree.clear();
			ientree.seekg(0);
			//ientree.seekg (0, ios::beg);
			//		ientree.rewind();
			_titre.resize(0);
			//cerr << "coucou ifichier" << i << endl;
			iFichier(ientree, i);
			//cerr << "coucou ifichier" << endl;

			autre = false;
			qDebug() << "Matrice<T>::iFichier(istream& ientree) 1 autre "
					<< autre;
		} catch (Anomalie erreur) {
			if (erreur.le_pb > 0) {
				autre = true;
				if (i == (nbformat - 1)) {
					//					cerr << erreur.fmessage(erreur.le_pb)<< endl;
					throw Anomalie(erreur.le_pb);
					autre = false;
				}
				erreur.le_pb = 0;
			}
		}
		qDebug() << "Matrice<T>::iFichier(istream& ientree) 2 autre " << autre;
		i++;
	}
	qDebug() << "Matrice<T>::iFichier(istream& ientree) end";
}

MatriceLD::MatriceLD() :
	Matrice () {
}
;

void MatriceLD::fdiagonalisation(MatriceLD & matdiag, vector<long double>& pvlp) {
	/******************************************************************************/
	/*                  DIAGONALISATION DE LA MATRICE  (Householder)        */
	/*                        1) tridiagonalisation (tridiag)                              */
	/*                	  2) diagonalisation par la methode Q-L (diaggl)          */
	/******************************************************************************/
	int m;
	unsigned long i;
	long double *ps;

	if (_type != 2)
		throw Anomalie(3);
	// 3-> op�ration impossible sur ce type de matrice
	pvlp.resize(_nc);

	matdiag.resize(_nc, _nc);
	matdiag.SetType(2);

	ps = new long double[_nc];

	matdiag._titre = _titre;
	matdiag._titre.push_back("diagonalisation par la methode Q-L");
	matdiag._flag = _flag;

	if ((_flag == 2) || (_flag == 3)) {
		matdiag._tcol = _tcol;
		matdiag._tlig = _tcol;
	}

	//copie du tableau
	for (i = 0; i < _t; i++) {
		matdiag._tab[i] = _tab[i];
	}

	m = matdiag.ftridiag(ps, pvlp);

	matdiag.fmdiagql(m, ps, pvlp);

	delete[] ps;

}

/*======================   methode  Q-L  =====================================*/

void MatriceLD::fmdiagql(int m, long double *ps, vector<long double> & pvlp) {
	long double *pcov;
	unsigned long i, ij, j, k, l;
	long ijk, is;
	long double q, h, t, xp, u, b, a, v;
	long double p1;

	if (_type != 2)
		throw Anomalie(3);
	// 3-> op�ration impossible sur ce type de matrice
	pcov = _tab;
	a = (long double) 1e-10;

	for (i = 1; i < _nc; i++) {
		*(ps + i - 1) = *(ps + i);
	}
	*(ps + _nc - 1) = 0;

	for (k = 0; k < _nc; k++) {
		j = k;
		while ((long double) (((long double) j < (long double) _nc - 1)
				&& fabs((long double) *(ps + j))) >= (long double) (a * (fabs(
				(long double) pvlp[j]) + fabs((long double) pvlp[j + 1]))))
			j++;
		while (j != k) {
			h = pvlp[k];
			m = m + 1;
			q = (pvlp[k + 1] - h) * 0.5 / (*(ps + k));
			t = sqrt((long double) q * q + 1);
			if (q < 0)
				is = -1;
			else
				is = 1;
			q = pvlp[j] - h + (*(ps + k)) / (q + t * is);
			u = 1;
			v = 1;
			h = 0;
			for (ijk = 1; ijk <= (long) (j - k); ijk++) {
				i = j - ijk;
				xp = u * (*(ps + i));
				b = v * (*(ps + i));
				if (q == 0 || xp == 0) {
					//	printf("cette matrice ne peut etre diagonalisee\n");
					// erreur
					//	return();
					delete[] ps;
					throw Anomalie(2);
				}
				if (fabs((long double) xp) >= fabs((long double) q)) {
					u = xp / q;
					t = sqrt((long double) u * u + 1);
					*(ps + i + 1) = q * t;
					v = 1 / t;
					u = u * v;
				} else {
					v = q / xp;
					t = sqrt((long double) 1 + v * v);
					*(ps + i + 1) = t * xp;
					u = 1 / t;
					v = v * u;
				}
				q = pvlp[i + 1] - h;
				t = ((pvlp[i]) - q) * u + 2 * v * b;
				h = u * t;
				pvlp[i + 1] = q + h;
				q = v * t - b;
				l = 0;
				while (l < _nc) {
					xp = *(pcov + rindice(l, i + 1));
					*(pcov + rindice(l, i + 1)) = u * (*(pcov + rindice(l, i)))
							+ v * xp;
					*(pcov + rindice(l, i)) = v * (*(pcov + rindice(l, i))) - u
							* xp;
					l = l + 1;
				}
			}
			pvlp[k] = pvlp[k] - h;
			*(ps + k) = q;
			*(ps + j) = 0;
			j = k;
			while (j < _nc - 1 && fabs((long double) *(ps + j)) >= a * (fabs(
					(long double) pvlp[j]) + fabs((long double) pvlp[j + 1])))
				j++;

		}
	}
	for (ij = 1; ij < _nc; ij++) {
		i = ij - 1;
		l = i;
		h = pvlp[i];
		for (m = ij; m < (int) _nc; m++) {
			if (pvlp[m] >= h) {
				l = m;
				h = pvlp[m];
			}
		}
		if (l != i) {
			pvlp[l] = pvlp[i];
			pvlp[i] = h;
			for (m = 0; m < (int) _nc; m++) {
				p1 = *(pcov + rindice(m, i));
				*(pcov + rindice(m, i)) = *(pcov + rindice(m, l));
				*(pcov + rindice(m, l)) = p1;
			}
		}
	}
}

int MatriceLD::ftridiag(long double *ps, vector<long double> & pvlp) {
	long double *pcov;
	unsigned long i, j;
	int k, l, m(0);
	long double b, c, q, x, xp, bp;

	pcov = _tab;

	for (j = 1; j < _nc; j++) {
		b = 0;
		c = 0;
		i = (_nc - 1) - j + 1;
		k = i - 1;

		if (k < 1) {
			*(ps + i) = *(pcov + rindice(i, k));
			pvlp[i] = b;
			continue;
		}
		for (l = 0; l <= k; l++) {
			c = c + fabs((long double) *(pcov + rindice(i, l)));
		}
		if (c == 0) {
			*(ps + i) = *(pcov + rindice(i, k));
			pvlp[i] = b;
			continue;
		}
		for (l = 0; l <= k; l++) {
			x = (*(pcov + rindice(i, l))) / c;
			*(pcov + rindice(i, l)) = x;
			b = b + (x * x);
		}
		xp = *(pcov + rindice(i, k));
		if (xp < 0) {
			q = sqrt((long double) b);
		} else {
			q = (sqrt((long double) b)) * (-1);
		}
		*(ps + i) = c * q;
		b = b - xp * q;
		*(pcov + rindice(i, k)) = xp - q;
		xp = 0;
		for (m = 0; m <= k; m++) {
			*(pcov + rindice(m, i)) = (*(pcov + rindice(i, m))) / (b * c);
			q = 0;
			for (l = 0; l <= m; l++) {
				q = q + (*(pcov + rindice(m, l))) * (*(pcov + rindice(i, l)));
			}
			for (l = m + 1; l <= k; l++) {
				q = q + ((*(pcov + rindice(l, m))) * (*(pcov + rindice(i, l))));

			}
			*(ps + m) = q / b;
			xp = xp + (*(ps + m)) * (*(pcov + rindice(i, m)));
		}
		bp = xp * 0.5 / b;
		for (m = 0; m <= k; m++) {
			xp = *(pcov + rindice(i, m));
			q = (*(ps + m)) - bp * xp;
			*(ps + m) = q;
			for (l = 0; l <= m; l++) {
				*(pcov + rindice(m, l)) = (*(pcov + rindice(m, l))) - xp
						* (*(ps + l)) - q * (*(pcov + rindice(i, l)));
			}
		}
		for (l = 0; l <= k; l++) {
			*(pcov + rindice(i, l)) = c * (*(pcov + rindice(i, l)));
		}
		pvlp[i] = b;
	}
	*ps = 0;
	pvlp[0] = 0;
	for (i = 0; i < _nc; i++) {
		k = i - 1;
		if (pvlp[i] != 0) {
			for (m = 0; m <= k; m++) {
				q = 0;
				for (l = 0; l <= k; l++) {
					q = q + (*(pcov + rindice(i, l)))
							* (*(pcov + rindice(l, m)));
				}
				for (l = 0; l <= k; l++) {
					*(pcov + rindice(l, m)) = (*(pcov + rindice(l, m))) - q
							* (*(pcov + rindice(l, i)));
				}
			}
		}
		pvlp[i] = *(pcov + rindice(i, i));
		*(pcov + rindice(i, i)) = 1;
		for (m = 0; m <= k; m++) {
			*(pcov + rindice(i, m)) = 0;
			*(pcov + rindice(m, i)) = 0;
		}
	}
	return (m);
}

void MatriceLD::fcoordcol(MatriceLD& stat, MatriceLD& res, MatriceLD& norm,
		vector<long double> & pvlp) {
	/******************************************************************************/
	/*                         calcul des coordonnees                             */
	/******************************************************************************/
	/*===================  coordonnees des colonnes  =============================*/
	unsigned long p0; //nb d'axes
	unsigned long i, j;
	int PC, k;
	long double tr; //somme des valeurs propres
	long double limite; //limite des possibilit�s de calculs
	float t; //cumul des pourcentages
	float v; //inertie (pourcentage sur un axe)
	long double *pcov, a1;
	char * temp;
	//	string temps;

	limite = 0.000001; //1e-010;//1e-030;

	if (norm._type != 2)
		throw Anomalie(3);
	// 3-> op�ration impossible sur ce type de matrice

	temp = new (char[50]);
	p0 = _nc - 1;

	// redimensionnement
	res.resize(_nc, p0);
	//
	res.SetType(1);
	res._titre = _titre;
	res._titre.push_back("coordonn�es spatiales sur les colonnes");
	res._titre.push_back("espace � ");
	//	itoa (p0,temp,10);
	res._titre[res._titre.size() - 1].AjEntier(p0); //temp ;
	res._titre[res._titre.size() - 1] += " dimensions";
	res._flag = 0;

	// redimensionnement
	stat.resize(p0, 3);
	//
	stat.SetType(1);
	stat._titre = _titre;
	stat._titre.push_back(
			"statistiques des coordonn�es spatiales sur les colonnes");
	stat._titre.push_back("espace � ");
	//	temps = p0;
	//	itoa (p0,temp,10);
	stat._titre[stat._titre.size() - 1].AjEntier(p0); //temps.c_str() ;
	stat._titre[stat._titre.size() - 1] += " dimensions";
	stat._flag = 3;

	if ((_flag == 2) || (_flag == 3)) {
		res._flag = 1;
		//copie des �tiquettes des lignes
		//		res._tlig = _tcol;
		res._tlig = _tlig;
	}

	res._flag = res._flag + 2; //num�rotation des axes
	for (i = 0; i < res._nc; i++) {
		//		strcpy(temp,"axe_");
		//		itoa(i + 1,temp + 4,10);
		//		strcat(temp,"");
		res._tcol[i].assign("axe_");
		res._tcol[i].AjEntier(i + 1);

		//		res._tcol[i].assign(temp);
		stat._tlig[i].assign(res._tcol[i]);
	}
	stat._tcol[0].assign("Valeur_Propre");
	stat._tcol[1].assign("Inertie");
	stat._tcol[2].assign("Cumul");

	pcov = norm._tab;
	PC = 100;

	//test sur les valeurs propres pour �liminer l'effet Ariane V
	j = 0;
	while ((fabs(pvlp[j]) > limite) && (j < _nc)) {
		j++;
	}
	if (j < _nc)
		for (i = j; i < _nc; i++)
			pvlp[i] = 0;

	//somme des valeurs propres
	tr = 0;
	for (j = 0; j < _nc; j++)
		tr = tr + pvlp[j];

	v = 0;
	t = 0;
	for (i = 0; i < p0; i++) {
		a1 = pvlp[i] / tr;
		v = PC * (float) a1;
		t = t + v;
		stat._tab[i * 3] = pvlp[i];
		stat._tab[(i * 3) + 1] = v;
		stat._tab[(i * 3) + 2] = t;
	}

	k = 0;
	for (i = 0; i < norm._nc; i++) { //scan sur les colonnes
		for (j = 0; j < p0; j++) { //coord col i, axe j
			a1 = (*(pcov + rindice(i, j))) * (sqrt((long double) pvlp[j]));
			res._tab[k] = a1 * PC;
			k++;
		}
	}
}

void MatriceLD::fscalaire(MatriceLD& pscalaire) {
	/******************************************************************************/
	/*                     calcul du produit scalaire                             */
	/******************************************************************************/
	unsigned long i, a, j;

	long double dt, x, x2, z;
	long double *pcov, *pvp, *ps;
	unsigned long nbcolonnes(GetNC());
	//cerr << "MatriceLD::fscalaire(MatriceLD& pscalaire) debut " << nbcolonnes << endl;
	pvp = new long double[nbcolonnes];
	ps = new long double[nbcolonnes];
	//cerr << "MatriceLD::fscalaire(MatriceLD& pscalaire) coucou 1" << endl;
	for (i = 0; i < nbcolonnes; i++) {
		pvp[i] = 0;
		ps[i] = 0;
	}

	pscalaire.resize(nbcolonnes, nbcolonnes);
	pscalaire.SetType(2);
	//cerr << "MatriceLD::fscalaire(MatriceLD& pscalaire) coucou 2" << endl;
	pscalaire._titre = _titre;
	pscalaire._titre.push_back("produit scalaire");
	pscalaire._flag = _flag;

	if ((_flag == 2) || (_flag == 3)) {
		//copie des �tiquettes des colonnes
		pscalaire._tcol = _tcol;
		pscalaire._tlig = _tcol;
	}

	//cerr << "MatriceLD::fscalaire(MatriceLD& pscalaire) coucou 3" << endl;
	//copie du tableau
	a = nbcolonnes * nbcolonnes;
	for (i = 0; i < a; i++) {
		if (i < _t)
			pscalaire._tab[i] = _tab[i];
		else
			pscalaire._tab[i] = 0;
	}

	pcov = pscalaire._tab;

	dt = 0.;
	z = (long double) 1 / nbcolonnes;

	//cerr << "MatriceLD::fscalaire(MatriceLD& pscalaire) coucou 4" << endl;
	for (i = 0; i < nbcolonnes; i++) {
		for (j = 0; j < nbcolonnes; j++) {
			x = *(pcov + rindice(i, j));
			x2 = x * x;
			*(ps + i) = (*(ps + i)) + x2;
			dt = dt + x2;
		}
		*(ps + i) = (*(ps + i)) * z;
	}
	//cerr << "MatriceLD::fscalaire(MatriceLD& pscalaire) coucou 5 " << nbcolonnes << " " << z << endl;
	dt = dt * z * z;
	for (i = 0; i < nbcolonnes; i++) {
		//cerr << "MatriceLD::fscalaire(MatriceLD& pscalaire) coucou i " << i << endl;
		for (j = 0; ((i > 0) && (j <= (i - 1))); j++) {
			//cerr << "MatriceLD::fscalaire(MatriceLD& pscalaire) coucou j " << j << endl;
			a = rindice(i, j);
			*(pcov + a) = 0.5 * ((*(ps + i)) + (*(ps + j)) - dt - (*(pcov + a))
					* (*(pcov + a)));
			*(pcov + rindice(j, i)) = *(pcov + a);
		}
		//cerr << "MatriceLD::fscalaire(MatriceLD& pscalaire) coucou 1i " << i << endl;
		*(pcov + rindice(i, j)) = 0.5 * (2 * (*(ps + i)) - dt);
		*(pvp + i) = (*(pcov + rindice(i, i))) / z;
	}

	//cerr << "MatriceLD::fscalaire(MatriceLD& pscalaire) delete" << endl;
	delete[] pvp;
	delete[] ps;
	//cerr << "MatriceLD::fscalaire(MatriceLD& pscalaire) fin" << endl;

}

void MatriceLD::fatd(MatriceLD& pcoord, MatriceLD& pstat) {
	//pmat1, matrice de d�part: tableau de distances (matrice
	//triangulaire inf�rieure, de type 2 pour NTSYS
	//pstat: matrice contenant les statistiques sur l'importance de
	//chaque axe dans un espace � n dimensions
	//pcoord: matrice contenant les coordonn�es des OTUs (r�sultat) dans cet
	// espace � n dimensions

	MatriceLD& pmat1 = *this;
	pmat1.SetType(1);

	//cerr << "MatriceLD::fatd (MatriceLD& pcoord, MatriceLD& pstat) debut" << endl;
	if (pmat1.GetFlag() == 2)
		pmat1.ftranspose();

	// au fomat NTSys: mettre les labels sur les colonnes (2� chiffre)

	MatriceLD mscalaire; //produit scalaire
	MatriceLD mdiag;//matrice diagonalis�e

	MatriceLD mnormalisee; //matrice normalisee
	vector<long double> pvlp; //vecteurs propres

	try {
		//travail sur une matrice de distances
		if (_type != 2)
			pmat1.SetType(2);

		//cerr << "MatriceLD::fatd (MatriceLD& pcoord, MatriceLD& pstat) coucou 1" << endl;
		pmat1.fscalaire(mscalaire);

		//cerr << "MatriceLD::fatd (MatriceLD& pcoord, MatriceLD& pstat) coucou 2" << endl;

		mscalaire.fdiagonalisation(mdiag, pvlp);

		//cerr << "MatriceLD::fatd (MatriceLD& pcoord, MatriceLD& pstat) coucou 3" << endl;
	} catch (MatriceLD::Anomalie erreur) {
		cout << erreur.fmessage(erreur.le_pb);
	}

	//	mdiag.normalise(&mnormalisee, pmat1, pvlp) ;

	//coordcol redimensionne pstat et pcoord
	pmat1.fcoordcol(pstat, pcoord, mdiag, pvlp);
	//cerr << "MatriceLD::fatd (MatriceLD& pcoord, MatriceLD& pstat) fin" << endl;

}

JeuMatriceLD::JeuMatriceLD(istream& entree) {
	// Lecture de fichiers contenant plusieurs matrices
	iFlux(entree);
}

// Lecture de fichiers contenant plusieurs matrices
void JeuMatriceLD::iFluxXML(istream& entree) {

}

void JeuMatriceLD::iFlux(istream& entree) {
	// Lecture de fichiers contenant plusieurs matrices

	stringstream* tampon;
	bool is_xml(false);
	//	iostream ensortie(tampon.rdbuf());
	char car;
	ChaineCar ligne;
	vector<unsigned long> positions;
	MatriceLD* pmat;
	unsigned long i, j;

	//balayage de l'entree pour trouver les positions
	// (delimitee par //)
	entree.clear();
	entree.seekg(0);
	positions.push_back(0);
	positions.push_back(0);

	entree.get(car);
	while (entree.good()) {
		if ((car == '/') && (entree.peek() == '/')) {
			positions.back() = entree.tellg();
			positions.back() -= 2;

			//cerr <<"coucou";
			GetLigneFlot(entree, ligne);
			positions.push_back(entree.tellg());

			positions.push_back(entree.tellg());
		} else {
			GetLigneFlot(entree, ligne);
			if (ligne.find("xml version=\"1.0\"", 0) > 0) {
				// c'est du ricqlèèèès !!!!!
				is_xml = true;
				break;
			}
		}
		positions.back() = entree.tellg();
		entree.get(car);
	}

	if (is_xml) {
		iFluxXML(entree);
		return;
	}
	// remplissage du buffer de matrices

	for (i = 0; i < (positions.size() - 1); i += 2) {
		if ((positions[i + 1] - positions[i]) < 6)
			continue;

		entree.clear();
		entree.seekg(positions[i]);

		_titres.push_back("");
		if (entree.peek() == '@') {
			entree.get(car);
			GetLigneFlot(entree, ligne);//_titres.back());

			//cerr << ligne;
			ligne.GetMot(1, _titres.back());
			//cerr << _titres.back();
		}

		tampon = new stringstream();
		for (j = positions[i]; j < positions[i + 1]; j++) {
			entree.get(car);
			*tampon << car;
			j = entree.tellg();

		}
		*tampon << ends;

		//cin >> car;
		//		cout << tampon->str() <<endl << endl;
		pmat = new MatriceLD();
		try {
			*tampon >> *pmat;
			_tableau.push_back(pmat);
		} catch (MatriceLD::Anomalie pb) {
			delete pmat;
			_titres.pop_back();
		}

		delete tampon;
		//		delete pmat;
		//		delete pensortie;
	}
}

void JeuMatriceLD::oFlux(ostream& sortie, int format) const {
	// Ecriture de fichiers contenant plusieurs matrices
	if (format == 5) {
		oGnumeric(sortie);
		return;
	}
	long i, taille(_tableau.size());

	for (i = 0; i < taille; i++) {
		sortie << "@" << _titres[i] << endl;
		_tableau[i]->oFormat(sortie, format);
		sortie << endl << "//" << endl;
	}

}

void JeuMatriceLD::oGnumeric(ostream& fichier) const {
	QString * p_output_xml = new QString("");
	QXmlStreamWriter xml_stream(p_output_xml);
	xml_stream.setAutoFormatting(true);
	xml_stream.writeStartDocument();
	// Ecriture de fichiers contenant plusieurs matrices
	long i, taille(_tableau.size());

	xml_stream.writeNamespace("http://www.gnumeric.org/v10.dtd", "gmr");
	xml_stream.writeNamespace("http://www.w3.org/2001/XMLSchema-instance",
			"xsi");
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Workbook");
	xml_stream.writeAttribute("http://www.w3.org/2001/XMLSchema-instance",
			"schemaLocation", "http://www.gnumeric.org/v8.xsd");

	//fichier
	//		<< "<gmr:Workbook xmlns:gmr=\"http://www.gnumeric.org/v10.dtd\" xmlns:xsi=\"http://www.w3.org/2001/XMLSchema-instance\" xsi:schemaLocation=\"http://www.gnumeric.org/v8.xsd\">"
	//		<< endl;

	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd",
			"Attributes");
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Attribute");
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"WorkbookView::show_horizontal_scrollbar");
	//fichier << "<gmr:Attributes>" << endl;
	//fichier << "   <gmr:Attribute>" << endl;
	//fichier << "<gmr:name>WorkbookView::show_horizontal_scrollbar</gmr:name>"
	//		<< endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "type", "4");
	//fichier << " <gmr:type>4</gmr:type>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "value",
			"TRUE");
	//fichier << "  <gmr:value>TRUE</gmr:value>" << endl;
	xml_stream.writeEndElement();
	//	fichier << " </gmr:Attribute>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Attribute");
	//fichier << " <gmr:Attribute>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"WorkbookView::show_vertical_scrollbar");
	//fichier << "  <gmr:name>WorkbookView::show_vertical_scrollbar</gmr:name>"
	//	<< endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "type", "4");
	//fichier << "  <gmr:type>4</gmr:type>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "value",
			"TRUE");
	//fichier << "  <gmr:value>TRUE</gmr:value>" << endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Attribute>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Attribute");
	//fichier << " <gmr:Attribute>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"WorkbookView::show_notebook_tabs");
	//fichier << "   <gmr:name>WorkbookView::show_notebook_tabs</gmr:name>"
	//		<< endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "type", "4");
	//fichier << "   <gmr:type>4</gmr:type>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "value",
			"TRUE");
	//fichier << "   <gmr:value>TRUE</gmr:value>" << endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Attribute>" << endl;

	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Attribute");
	//fichier << " <gmr:Attribute>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"WorkbookView::do_auto_completion");
	//fichier << "   <gmr:name>WorkbookView::do_auto_completion</gmr:name>"
	//		<< endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "type", "4");
	//fichier << "   <gmr:type>4</gmr:type>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "value",
			"TRUE");
	//fichier << "   <gmr:value>TRUE</gmr:value>" << endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Attribute>" << endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Attributes>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Summary");
	//fichier << " <gmr:Summary>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Item");
	//fichier << "  <gmr:Item>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"biology softwares");
	//fichier << "  <gmr:name>biology softwares</gmr:name>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd",
			"val-string", "http://www.pge.cnrs-gif.fr/bioinfo");
	//fichier
	//		<< "  <gmr:val-string>http://www.pge.cnrs-gif.fr/bioinfo</gmr:val-string>"
	//		<< endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Item>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Item");
	//fichier << " <gmr:Item>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "name",
			"author");
	//fichier << "   <gmr:name>author</gmr:name>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd",
			"val-string", "Olivier Langella <Olivier.Langella@moulon.inra.fr>");
	//fichier
	//		<< "   <gmr:val-string>Olivier Langella, Olivier.Langella@pge.cnrs-gif.fr</gmr:val-string>"
	//		<< endl;
	xml_stream.writeEndElement();
	//fichier << " </gmr:Item>" << endl;
	xml_stream.writeEndElement();
	//fichier << "</gmr:Summary>" << endl;
	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd",
			"SheetNameIndex");

	//fichier << "  <gmr:SheetName>Matrix 1</gmr:SheetName>" << endl;


	//fichier << "<gmr:SheetNameIndex>" << endl;
	xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd", "SheetName",
			"Matrix 1");
	for (i = 0; i < taille; i++) {
		xml_stream.writeTextElement("http://www.gnumeric.org/v10.dtd",
				"SheetName", _titres[i].c_str());
		//fichier << "<gmr:SheetName>" << _titres[i] << "</gmr:SheetName>"
		//		<< endl;
	}
	xml_stream.writeEndElement();
	//fichier << "</gmr:SheetNameIndex> " << endl;

	xml_stream.writeStartElement("http://www.gnumeric.org/v10.dtd", "Sheets");
	//	fichier.setf(ios::scientific);

	for (i = 0; i < taille; i++) {
		QString sheetname(_titres[i].c_str());
		_tableau[i]->oGnumericSheet(xml_stream, sheetname);
	}

	fichier << " </gmr:Sheets> " << endl;
	fichier << "</gmr:Workbook> " << endl;

	xml_stream.writeEndDocument();

	fichier << p_output_xml->toStdString();
	delete (p_output_xml);

}

void JeuMatriceLD::SetTitre(long i, const char * chaine) {

	//	if ((i < 0) || (i >= _titres.size())) throw Anomalie(1);
	//	cerr << chaine << endl;
	_titres[i].assign(chaine);
	//	cerr << "fini" << endl;
}

void JeuMatriceLD::resize(long nouvtaille) {
	//on efface:
	long i, taille(_tableau.size());

	_titres.resize(nouvtaille);

	for (i = 0; i < taille; i++)
		delete _tableau[i];

	//on r�alloue
	_tableau.resize(nouvtaille);
	for (i = 0; i < nouvtaille; i++)
		_tableau[i] = new MatriceLD;

}

} //namespace biolib {
} //namespace vecteurs {
