359 lines
18 KiB
C
359 lines
18 KiB
C
|
|
||
|
// This file is part of the Herezh++ application.
|
||
|
//
|
||
|
// The finite element software Herezh++ is dedicated to the field
|
||
|
// of mechanics for large transformations of solid structures.
|
||
|
// It is developed by Gérard Rio (APP: IDDN.FR.010.0106078.000.R.P.2006.035.20600)
|
||
|
// INSTITUT DE RECHERCHE DUPUY DE LÔME (IRDL) <https://www.irdl.fr/>.
|
||
|
//
|
||
|
// Herezh++ is distributed under GPL 3 license ou ultérieure.
|
||
|
//
|
||
|
// Copyright (C) 1997-2021 Université Bretagne Sud (France)
|
||
|
// AUTHOR : Gérard Rio
|
||
|
// E-MAIL : gerardrio56@free.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 3 of the License,
|
||
|
// or (at your option) any later version.
|
||
|
//
|
||
|
// This program is distributed in the hope that it will be useful,
|
||
|
// but WITHOUT ANY WARRANTY; without even the implied warranty
|
||
|
// of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||
|
// See the GNU General Public License for more details.
|
||
|
//
|
||
|
// You should have received a copy of the GNU General Public License
|
||
|
// along with this program. If not, see <https://www.gnu.org/licenses/>.
|
||
|
//
|
||
|
// For more information, please consult: <https://herezh.irdl.fr/>.
|
||
|
|
||
|
/************************************************************************
|
||
|
* DATE: 23/01/97 *
|
||
|
* $ *
|
||
|
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
|
||
|
* $ *
|
||
|
* PROJET: Herezh++ *
|
||
|
* $ *
|
||
|
************************************************************************
|
||
|
* BUT: definition de matrices creuses a valeurs reelles. *
|
||
|
* Le stockage est quelconque (pas symétrique par exemple). *
|
||
|
* Ici le stockage est de type en colonne compressée. *
|
||
|
* $ *
|
||
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
|
||
|
* VERIFICATION: *
|
||
|
* *
|
||
|
* ! date ! auteur ! but ! *
|
||
|
* ------------------------------------------------------------ *
|
||
|
* ! ! ! ! *
|
||
|
* $ *
|
||
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
|
||
|
* MODIFICATIONS: *
|
||
|
* ! date ! auteur ! but ! *
|
||
|
* ------------------------------------------------------------ *
|
||
|
* $ *
|
||
|
************************************************************************/
|
||
|
#ifndef MAT_CREUSE_COMPCOL_H
|
||
|
#define MAT_CREUSE_COMPCOL_H
|
||
|
|
||
|
//#include "Debug.h"
|
||
|
#include <iostream>
|
||
|
#include "Mat_abstraite.h"
|
||
|
#include "MathUtil.h"
|
||
|
|
||
|
#include "compcol_double.h"
|
||
|
#include "comprow_double.h"
|
||
|
#include "coord_double.h"
|
||
|
|
||
|
#include "Vecteur.h"
|
||
|
#include "Tableau2_T.h"
|
||
|
|
||
|
/// @addtogroup Les_classes_Matrices
|
||
|
/// @{
|
||
|
///
|
||
|
|
||
|
|
||
|
class Mat_creuse_CompCol : public Mat_abstraite , public CompCol_Mat_double
|
||
|
{ // surcharge de l'operator de lecture typée
|
||
|
friend istream & operator >> (istream &, Mat_creuse_CompCol &);
|
||
|
// surcharge de l'operator d'ecriture typée
|
||
|
friend ostream & operator << (ostream &, const Mat_creuse_CompCol &);
|
||
|
public :
|
||
|
// CONSTRUCTEURS :
|
||
|
Mat_creuse_CompCol (); // par defaut
|
||
|
|
||
|
// constructeur parmettant la création d'une matrice creuse
|
||
|
// ici aucun élément de la matrice n'est créé, il faut ensuite utiliser l'initialisation
|
||
|
// pour créer les éléments non nulles dans la matrice
|
||
|
// M : nombre de lignes
|
||
|
// N : nombre de colonnes
|
||
|
//
|
||
|
Mat_creuse_CompCol(int M, int N);
|
||
|
|
||
|
// constructeur parmettant la création d'une matrice creuse complete
|
||
|
// à partir de la donnée d'un ensemble de sous matrices carrées
|
||
|
// les petites matrices sont carrées, ils sont définit par un tableau ligne qui contiend
|
||
|
// la position d'un terme de la petite matrice dans la grande matrice
|
||
|
// exemple : pet_mat(k)(i), pet_mat(k)(j) : indique le numéro de ligne et le numéro de colonne
|
||
|
// d'un élément non nul dans la grande matrice
|
||
|
// M : nombre de lignes
|
||
|
// N : nombre de colonnes
|
||
|
//
|
||
|
Mat_creuse_CompCol(int M, int N,const Tableau < Tableau <int> >& petites_matrices);
|
||
|
|
||
|
// de copie à partir d'une même instance
|
||
|
Mat_creuse_CompCol(const Mat_creuse_CompCol &S) ;
|
||
|
|
||
|
// de copie à partir d'une sparse matrice compressée par ligne
|
||
|
// Mat_creuse_CompCol(const Mat_creuse_CompRow &R) ;
|
||
|
// de copie à partir d'une sparse matrice non compressée
|
||
|
// Mat_creuse_CompCol(const Mat_creuse_Coord &CO) ;
|
||
|
|
||
|
// DESTRUCTEUR :
|
||
|
~Mat_creuse_CompCol () {};
|
||
|
|
||
|
|
||
|
// fonction permettant de creer une nouvelle instance d'element du même type
|
||
|
Mat_abstraite * NouvelElement() const;
|
||
|
|
||
|
// METHODES PUBLIQUES :
|
||
|
|
||
|
// surcharge de l'opérateur d'affectation : cas de matrices abstraites
|
||
|
Mat_abstraite & operator = ( const Mat_abstraite &);
|
||
|
|
||
|
// transfert des informations de *this dans la matrice passée en paramètre
|
||
|
// la matrice paramètre est au préalable, mise à 0.
|
||
|
void Transfert_vers_mat( Mat_abstraite & A );
|
||
|
|
||
|
// surcharge de l'opérateur d'affectation : cas de matrices creuses
|
||
|
Mat_creuse_CompCol & operator = ( const Mat_creuse_CompCol &);
|
||
|
|
||
|
//-----------------------------------------------------------------------------------
|
||
|
// --- plusieurs fonctions virtuelles qui agissent en général sur la matrice ---------
|
||
|
//-----------------------------------------------------------------------------------
|
||
|
// ici l'idée est d'éviter de construire une nouvelle matrice pour des questions
|
||
|
// d'encombrement, c'est surtout des méthodes utiles pour le stockage de matrice
|
||
|
// de raideur. On met le nombre mini de fonction, pour pouvoir faire des expressions.
|
||
|
// Cependant aucune de ces fonctions n'est en désaccord avec les fonctions membres
|
||
|
// qui crée une matrice en résultat (cf. Mat_pleine)
|
||
|
|
||
|
// Surcharge de l'operateur += : addition d'une matrice a la matrice courante
|
||
|
// cette méthode n'est possible si et seulement les termes existant de mat_pl
|
||
|
void operator+= (const Mat_abstraite& mat_pl);
|
||
|
|
||
|
// Surcharge de l'operateur -= : soustraction d'une matrice a la matrice courante
|
||
|
// cette méthode n'est possible si et seulement les termes existant de mat_pl
|
||
|
void operator-= (const Mat_abstraite& mat_pl);
|
||
|
|
||
|
// Surcharge de l'operateur *= : multiplication de la matrice courante par un scalaire
|
||
|
void operator*= (const double r);
|
||
|
|
||
|
//------------------------------------------------------------------------------------
|
||
|
// --- fin de plusieurs fonctions virtuelles qui agissent en général sur la matrice --
|
||
|
//------------------------------------------------------------------------------------
|
||
|
|
||
|
// Surcharge de l'operateur == : test d'egalite entre deux matrices
|
||
|
int operator== (const Mat_abstraite& mat_pl) const ;
|
||
|
|
||
|
// acces aux composantes comme pour une matrice carree
|
||
|
// il y a un message en cas de mauvaises valeurs
|
||
|
double& operator () (int i, int j )
|
||
|
{ return CompCol_Mat_double::set(i-1,j-1);};
|
||
|
|
||
|
|
||
|
// ramène true si la place (i,j) existe, false sinon
|
||
|
// ici on ne test pas le fait que i et j puissent être négatif ou pas
|
||
|
inline bool Existe(int i, int j) const
|
||
|
{return Exista(i,j);};
|
||
|
|
||
|
|
||
|
// acces en lecture seul, aux composantes comme pour une matrice carree
|
||
|
// il y a un message en cas de mauvais indice
|
||
|
// si les indices sont possibles mais que l'élément n'existe pas retour 0
|
||
|
double operator () (int i, int j ) const
|
||
|
{return CompCol_Mat_double::operator () (i-1,j-1);};
|
||
|
|
||
|
// Retourne la ieme ligne de la matrice en lecture / écriture
|
||
|
// pas util dans le cas des matrices creuses donc
|
||
|
// non implemente
|
||
|
Vecteur& Ligne_set (int i)
|
||
|
{ cout <<" fonction non implementee : "
|
||
|
<< " Vecteur& Mat_creuse_CompCol::operator() (int i) " << endl;
|
||
|
Sortie(1);
|
||
|
i = i; // pour ne pas avoir de message a la compilation !!
|
||
|
Vecteur* toto = new Vecteur();
|
||
|
return *toto;
|
||
|
};
|
||
|
|
||
|
// Retourne la ieme ligne de la matrice uniquement en lecture
|
||
|
// pas util dans le cas des matrices creuses donc
|
||
|
// non implemente
|
||
|
Vecteur operator() (int i) const
|
||
|
{ cout << " fonction non implementee : "
|
||
|
<< " Vecteur& Mat_creuse_CompCol::operator() (int i) " << endl;
|
||
|
i = i; // pour ne pas avoir de message a la compilation !!
|
||
|
return Vecteur(0);
|
||
|
};
|
||
|
|
||
|
// Retourne la ieme ligne de la matrice (lent !!!)
|
||
|
Vecteur Ligne(int i) const ;
|
||
|
|
||
|
// Retourne la ieme ligne de la matrice (lent !!!)
|
||
|
// sous le format de stokage propre a la matrice
|
||
|
// donc a n'utiliser que comme sauvegarde en parralele
|
||
|
// avec la fonction RemplaceLigne
|
||
|
Vecteur LigneSpe(int i) const ;
|
||
|
// remplace la ligne de la matrice par la ligne fournie (lent !!!)
|
||
|
void RemplaceLigneSpe(int i,const Vecteur & v);
|
||
|
|
||
|
//met une valeur identique sur toute la ligne (lent !!!)
|
||
|
void MetValLigne(int i,double val);
|
||
|
|
||
|
// Retourne la jeme colonne de la matrice (rapide)
|
||
|
Vecteur Colonne(int j) const ;
|
||
|
|
||
|
// Retourne la jeme colonne de la matrice (rapide)
|
||
|
// sous le format de stokage propre a la matrice
|
||
|
// donc a n'utiliser que comme sauvegarde en parralele
|
||
|
// avec la fonction RemplaceColonne
|
||
|
Vecteur ColonneSpe(int j) const ;
|
||
|
// remplace la Colonne de la matrice par la ligne fournie (rapide)
|
||
|
void RemplaceColonneSpe(int j, const Vecteur & v);
|
||
|
//met une valeur identique sur toute la colonne (rapide)
|
||
|
void MetValColonne(int j,double val);
|
||
|
|
||
|
// Affichage des valeurs de la matrice
|
||
|
void Affiche () const ;
|
||
|
// Affiche une partie de la matrice (util pour le debug)
|
||
|
// min_ et max_ sont les bornes de la sous_matrice
|
||
|
// pas_ indique le pas en i et j pour les indices
|
||
|
void Affiche1(int min_i,int max_i,int pas_i,int min_j,int max_j,int pas_j) const ;
|
||
|
// Affiche une partie de la matrice idem si dessus
|
||
|
// mais avec un nombre de digit (>7) = nd
|
||
|
// si < 7 ne fait rien
|
||
|
void Affiche2(int min_i,int max_i,int pas_i,int min_j,int max_j,int pas_j,int nd) const ;
|
||
|
|
||
|
// changement de la taille de la matrice : c-a-d permet de redimentionner
|
||
|
// la matrice creuse
|
||
|
// 1) cas d'un utilisateur qui connait un ensemble de petite matrice qui doivent être contenue
|
||
|
// dans la matrice creuse, la matrice initiale est effacée
|
||
|
// les petites matrices sont carrées, ils sont définit par un tableau ligne qui contiend
|
||
|
// la position d'un terme de la petite matrice dans la grande matrice
|
||
|
// exemple : pet_mat(k)(i), pet_mat(k)(j) : indique le numéro de ligne et le numéro de colonne
|
||
|
// d'un élément non nul dans la grande matrice
|
||
|
// M et N : nb ligne et nb colonne,
|
||
|
void Change_taille(const int M, const int N ,const Tableau < Tableau <int> >& petites_matrices);
|
||
|
|
||
|
// 2) cas d'un utilisateur qui connait le stockage par colonne
|
||
|
// M et N : nb ligne et nb colonne,
|
||
|
// pointeur_colonne : donne dans le vecteur de stockage global le début de chaque colonne
|
||
|
// nz : nb de termes non nulles dans la matrice
|
||
|
void Change_taille(const int M, const int N ,const Tableau<int>& pointeur_colonne,const int nz = 0);
|
||
|
|
||
|
// ramène le nombre de colonne
|
||
|
inline int Nb_colonne () const{ return CompCol_Mat_double::dim(1);} ;
|
||
|
// ramène le nombre de ligne
|
||
|
inline int Nb_ligne() const { return CompCol_Mat_double::dim(0);};
|
||
|
// initialisation toutes les valeurs de la matrice a la valeur "a"
|
||
|
void Initialise (double a);
|
||
|
// Liberation de la place memoire
|
||
|
void Libere () ;
|
||
|
// test si la matrice est symétrique ou pas
|
||
|
// ici pour l'instant on considère qu'elle ne l'est pas
|
||
|
int Symetrie () const { return 0; }
|
||
|
|
||
|
// Resolution du systeme Ax=b
|
||
|
// la verification de taille n'est faite que pour le debug
|
||
|
//1) avec en sortie un new vecteur
|
||
|
Vecteur Resol_syst ( const Vecteur& b,const double &tol = tol_defaut
|
||
|
,const int maxit = maxit_defaut,const int restart = restart_defaut) ;
|
||
|
//2) avec en sortie le vecteur d'entree
|
||
|
Vecteur& Resol_systID ( Vecteur& b,const double &tol = tol_defaut
|
||
|
,const int maxit = maxit_defaut,const int restart = restart_defaut);
|
||
|
//3) avec en entrée un tableau de vecteur second membre et
|
||
|
// en sortie un nouveau tableau de vecteurs
|
||
|
Tableau <Vecteur> Resol_syst
|
||
|
(const Tableau <Vecteur>& b,const double &tol = tol_defaut
|
||
|
,const int maxit = maxit_defaut,const int restart = restart_defaut) ;
|
||
|
//4) avec en entrée un tableau de vecteur second membre et
|
||
|
// en sortie le tableau de vecteurs d'entree
|
||
|
Tableau <Vecteur>& Resol_systID
|
||
|
(Tableau <Vecteur>& b,const double &tol = tol_defaut
|
||
|
,const int maxit = maxit_defaut,const int restart = restart_defaut) ;
|
||
|
//5) avec en sortie le dernier vecteur d'entree, le premier étant le second membre
|
||
|
// et restant inchangé, en sortie c'est donc soit le retour ou soit vortie, les
|
||
|
// deux étant identiques
|
||
|
Vecteur& Resol_systID_2 (const Vecteur& b,Vecteur& vortie
|
||
|
, const double &tol = tol_defaut,const int maxit = maxit_defaut
|
||
|
,const int restart = restart_defaut);
|
||
|
|
||
|
// ===== RÉSOLUTION EN DEUX TEMPS ================ :
|
||
|
// 1) préparation de la matrice donc modification de la matrice éventuellement
|
||
|
// par exemple pour les matrices bandes avec cholesky : triangulation
|
||
|
void Preparation_resol();
|
||
|
// 2) *** résolution sans modification de la matrice DOIT ÊTRE PRÉCÉDÉ DE L'APPEL DE
|
||
|
// Preparation_resol
|
||
|
// a) avec en sortie un new vecteur
|
||
|
Vecteur Simple_Resol_syst (const Vecteur& b,const double &tol = tol_defaut
|
||
|
,const int maxit = maxit_defaut,const int restart = restart_defaut) const ;
|
||
|
// b) avec en sortie le vecteur d'entree
|
||
|
Vecteur& Simple_Resol_systID (Vecteur& b,const double &tol = tol_defaut
|
||
|
,const int maxit = maxit_defaut,const int restart = restart_defaut) const ;
|
||
|
// c) avec en entrée un tableau de vecteur second membre et
|
||
|
// en sortie un nouveau tableau de vecteurs
|
||
|
Tableau <Vecteur> Simple_Resol_syst
|
||
|
(const Tableau <Vecteur>& b,const double &tol = tol_defaut
|
||
|
,const int maxit = maxit_defaut,const int restart = restart_defaut) const ;
|
||
|
// d) avec en entrée un tableau de vecteur second membre et
|
||
|
// en sortie le tableau de vecteurs d'entree
|
||
|
Tableau <Vecteur>& Simple_Resol_systID
|
||
|
(Tableau <Vecteur>& b,const double &tol = tol_defaut
|
||
|
,const int maxit = maxit_defaut,const int restart = restart_defaut) const ;
|
||
|
// e) avec en sortie le dernier vecteur d'entree, le premier étant le second membre
|
||
|
// et restant inchangé, en sortie c'est donc soit le retour ou soit vortie, les
|
||
|
// deux étant identiques
|
||
|
Vecteur& Simple_Resol_systID_2 (const Vecteur& b,Vecteur& vortie
|
||
|
, const double &tol = tol_defaut
|
||
|
,const int maxit = maxit_defaut
|
||
|
,const int restart = restart_defaut) const ;
|
||
|
// ===== FIN RÉSOLUTION EN DEUX TEMPS ================ :
|
||
|
|
||
|
// Multiplication d'un vecteur par une matrice ( (vec)t * A )
|
||
|
Vecteur Prod_vec_mat ( const Vecteur& vec) const ;
|
||
|
// idem mais on utilise la place du second vecteur pour le résultat
|
||
|
Vecteur& Prod_vec_mat ( const Vecteur& vec, Vecteur & resul) const ;
|
||
|
// Multiplication d'une matrice par un vecteur ( A * vec )
|
||
|
Vecteur Prod_mat_vec ( const Vecteur& vec) const ;
|
||
|
// idem mais on utilise la place du second vecteur pour le résultat
|
||
|
Vecteur& Prod_mat_vec ( const Vecteur& vec, Vecteur & resul) const;
|
||
|
// Multiplication d'une ligne iligne de la matrice avec un vecteur de
|
||
|
// dimension = le nombre de colonne de la matrice
|
||
|
double Prod_Ligne_vec ( int iligne, const Vecteur& vec) const ;
|
||
|
// Multiplication d'un vecteur avec une colonne icol de la matrice
|
||
|
// dimension = le nombre de ligne de la matrice
|
||
|
double Prod_vec_col( int icol, const Vecteur& vec) const ;
|
||
|
|
||
|
// calcul du produit : (vec_1)^T * A * (vect_2)
|
||
|
double vectT_mat_vec(const Vecteur& vec1, const Vecteur& vec2) const ;
|
||
|
|
||
|
// retourne la place que prend la matrice en entier
|
||
|
int Place() const { return (NumNonzeros() * 3 + dim(1) + 5);};
|
||
|
|
||
|
// ====== quelques méthodes spécifiques à la classe MV_Vector<double>==============
|
||
|
// définie la surcharge de multiplication d'une matrice par un MV_Vector
|
||
|
// ici de type constant, ramène un nouveau MV_Vector<double>
|
||
|
inline virtual MV_Vector<double> operator * (const MV_Vector<double> & vec) const
|
||
|
{ return this->CompCol_Mat_double::operator *(vec); };
|
||
|
// multiplication matrice transposée fois vecteur ce qui est équivalent à
|
||
|
// la transposée du résultat de : multiplication vecteur transposé fois matrice
|
||
|
inline virtual MV_Vector<double> trans_mult(const MV_Vector<double> &x) const
|
||
|
{ return this->CompCol_Mat_double::trans_mult(x); };
|
||
|
// ====== fin des quelques méthodes spécifiques à la classe MV_Vector<double>=======
|
||
|
|
||
|
protected :
|
||
|
|
||
|
// VARIABLES PROTEGEES :
|
||
|
};
|
||
|
/// @} // end of group
|
||
|
|
||
|
#endif
|