/****************************************************************************
 * Fonction:	Matrice::operateur-
 * Description: Soustrait deux matrices. Il faut que les deux matrices soient de memes dimensions
 * Paramètres:	Matrice a soustraire
 * Retour:		Matrice resultante
 ****************************************************************************/
Matrice Matrice::operator-(const Matrice& uneMatrice)
{
	Matrice result;
	if (uneMatrice.lignes_ == lignes_ && uneMatrice.colonnes_ == colonnes_) {
        
		result = Matrice(lignes_,colonnes_);
		for (int i=0; i<lignes_; i++) {
			for (int j=0; j<uneMatrice.colonnes_; j++)
				result.matrice_(i,j) = matrice_(i,j) - uneMatrice.matrice_(i,j);
		}
	}
	else {
		cerr	<< "Erreur lors de la soustraction des matrices. Les dimensions doivent etre correctes." << endl
        << "(" << lignes_ << "," << colonnes_ << ") + (" << uneMatrice.lignes_ << "," << uneMatrice.colonnes_ << ")" << endl;
	}
	return result;
}
/****************************************************************************
 * Fonction:	Matrice::transpose
 * Description: Calcule la matrice transposée
 * Paramètres:	Aucun
 * Retour:		Matrice résultante
 ****************************************************************************/
Matrice Matrice::transpose()
{
	Matrice result = Matrice(colonnes_,lignes_);
	for (int i=0; i<lignes_; i++) {
		for (int j=0; j<colonnes_; j++)
			result.matrice_(j,i) = matrice_(i,j);
	}
	return result;
}
/****************************************************************************
 * Fonction:	Matrice::operateur/
 * Description: Divise tous les éléments de la matrice par une valeur réelle
 * Paramètres:	Valeur à diviser
 * Retour:		Matrice résultante
 ****************************************************************************/
Matrice Matrice::operator/(double valeur)
{
	Matrice result = Matrice(*this);
	for (int i=0; i<lignes_; i++) {
		for (int j=0; j<colonnes_; j++)
			result.matrice_(i,j) /= valeur;
	}
	return result;
}
/****************************************************************************
 * Fonction:	Matrice::Matrice
 * Description: Constructeur par copie
 * Paramètres:	Matrice à copier
 * Retour:		aucun
 ****************************************************************************/
Matrice::Matrice(const Matrice& uneMatrice)
{
	lignes_ = uneMatrice.lignes_;
	colonnes_ = uneMatrice.colonnes_;
	matrice_.setbounds(0,lignes_-1,0,colonnes_-1);
	for (unsigned int i=0; i<lignes_; i++)
	{
		for (unsigned int j=0; j<colonnes_; j++)
			matrice_(i,j) = uneMatrice.matrice_(i,j);
	}
}
/****************************************************************************
 * Fonction:	Matrice::operateur*
 * Description: Multiplie la matrice avec celle passée en paramètre en vérifiant les dimensions
 * Paramètres:	Matrice à multiplier
 * Retour:		Matrice résultante
 ****************************************************************************/
Matrice Matrice::operator*(const Matrice& uneMatrice)
{
	Matrice result;
	if (uneMatrice.lignes_ == colonnes_) {
		result = Matrice(lignes_,uneMatrice.colonnes_);
        real_1d_array work; work.setbounds(0,lignes_);
        for (int k=0; k<lignes_; k++) work(k) = 0.0;
        //matrixmatrixmultiply(matrice_,0,lignes_-1,0,colonnes_-1,0,uneMatrice.matrice_,false,uneMatrice.lignes_-1,0,uneMatrice.colonnes_-1,0,1.0,result.matrice_,0,lignes_-1,false,uneMatrice.colonnes_-1,1.0,work);
		//rmatrixgemm(lignes_,uneMatrice.colonnes_,colonnes_,1,matrice_,0,0,0,uneMatrice.matrice_,0,0,0,0,result.matrice_,0,0);
		for (int i=0; i<lignes_; i++) {
			for (int j=0; j<uneMatrice.colonnes_; j++) {
				for (int k=0; k<colonnes_; k++)
					result.matrice_(i,j) += matrice_(i,k)*uneMatrice.matrice_(k,j);
			}
		}
	}
	else {
		cerr	<< "Erreur lors de la multiplication des matrices. Les dimensions doivent etre correctes." << endl
				<< "(" << lignes_ << "," << colonnes_ << ") * (" << uneMatrice.lignes_ << "," << uneMatrice.colonnes_ << ")" << endl;
	}
	return result;
}