2021-09-28 17:28:23 +02:00
|
|
|
|
|
|
|
// 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.
|
|
|
|
//
|
2023-05-03 17:23:49 +02:00
|
|
|
// Copyright (C) 1997-2022 Université Bretagne Sud (France)
|
2021-09-28 17:28:23 +02:00
|
|
|
// 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: 28/03/2005 *
|
|
|
|
* $ *
|
|
|
|
* AUTEUR: G RIO (mailto:gerardrio56@free.fr) *
|
|
|
|
* $ *
|
|
|
|
* PROJET: Herezh++ *
|
|
|
|
* $ *
|
|
|
|
************************************************************************
|
|
|
|
* BUT: Utilisation de routines lapack dans le cas de matrices *
|
|
|
|
* rectangulairesn, carrées ou bandes, symétriques ou pas. *
|
|
|
|
* Les coefficients sont des doubles. *
|
|
|
|
* $ *
|
|
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' * *
|
|
|
|
* VERIFICATION: *
|
|
|
|
* *
|
|
|
|
* ! date ! auteur ! but ! *
|
|
|
|
* ------------------------------------------------------------ *
|
|
|
|
* ! ! ! ! *
|
|
|
|
* $ *
|
|
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''' *
|
|
|
|
* MODIFICATIONS: *
|
|
|
|
* ! date ! auteur ! but ! *
|
|
|
|
* ------------------------------------------------------------ *
|
|
|
|
* $ *
|
|
|
|
************************************************************************/
|
|
|
|
|
|
|
|
#ifndef MatLapack_H
|
|
|
|
#define MatLapack_H
|
|
|
|
|
|
|
|
// au niveau de la bibliothèque apple
|
|
|
|
// ./System/Library/Frameworks/vecLib.framework/Versions/A/Headers/clapack.h
|
|
|
|
// ./System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Versions/A/Headers/clapack.h
|
|
|
|
|
|
|
|
//#include "Debug.h"
|
|
|
|
#ifdef SYSTEM_MAC_OS_CARBON
|
|
|
|
#include "LAPACK.h"
|
|
|
|
#endif
|
|
|
|
#ifdef ENLINUX_2009
|
|
|
|
// #include <f2c.h> // on supprime l'inclusion, et on la remplace par une introduction dans le debut de clapack.h !!
|
|
|
|
// ceci pour la version linux !!
|
|
|
|
// #include "INCLUDE/clapack.h"
|
|
|
|
#include "Include_lapack/clapack.h"
|
|
|
|
#include "cblas.h"
|
|
|
|
typedef __CLPK_integer ENTIER_POUR_CLAPACK;
|
|
|
|
// typedef long int ENTIER_POUR_CLAPACK;
|
|
|
|
// on n'arrive pas à faire un include en linux ??
|
|
|
|
// mais l'option de mise au point est supprimée à la fin du matlapack.cc
|
|
|
|
//#define MISE_AU_POINT
|
|
|
|
#else
|
|
|
|
#ifdef SYSTEM_MAC_OS_X_unix
|
|
|
|
// #include </System/Library/Frameworks/vecLib.framework/Versions/A/Headers/clapack.h>
|
|
|
|
// #include "Headers/clapack.h"
|
|
|
|
#include <Accelerate.h>
|
|
|
|
|
|
|
|
// #include </System/Library/Frameworks/Accelerate.framework/Versions/A/Frameworks/vecLib.framework/Headers/clapack.h>
|
|
|
|
typedef __CLPK_integer ENTIER_POUR_CLAPACK;
|
|
|
|
#endif
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#ifdef SYSTEM_MAC_OS_X
|
|
|
|
#include <Versions/A/Headers/clapack.h>
|
|
|
|
typedef __CLPK_integer ENTIER_POUR_CLAPACK;
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#include "Mat_abstraite.h"
|
|
|
|
|
|
|
|
/// @addtogroup Les_classes_Matrices
|
|
|
|
/// @{
|
|
|
|
///
|
|
|
|
|
|
|
|
|
|
|
|
class MatLapack : public Mat_abstraite
|
|
|
|
{ // surcharge de l'operator de lecture typée
|
|
|
|
friend istream & operator >> (istream &, MatLapack &);
|
|
|
|
// surcharge de l'operator d'ecriture typée
|
|
|
|
friend ostream & operator << (ostream &, const MatLapack &);
|
|
|
|
|
|
|
|
public :
|
|
|
|
|
|
|
|
// Constructeur par défaut
|
|
|
|
// il est nécessaire ensuite de définir les données pour l'utiliser
|
|
|
|
MatLapack ( );
|
|
|
|
|
|
|
|
// Constructeur pour une matrice carree quelconque, ou symétrique
|
|
|
|
// se servant d'un nombre de lignes, de = colonnes, et eventuellement
|
|
|
|
// d'une valeur d'initialisation
|
|
|
|
MatLapack (int nb_ligne,int nb_colonne, bool symetrique , double val_init
|
|
|
|
,Enum_type_resolution_matri type_resol //=RIEN_TYPE_RESOLUTION_MATRI
|
|
|
|
,Enum_preconditionnement type_precondi //= RIEN_PRECONDITIONNEMENT
|
|
|
|
);
|
|
|
|
|
|
|
|
// Constructeur pour une matrice bande quelconque, ou symétrique
|
|
|
|
// se servant d'un nombre de lignes (dim) , d'une largeur de bande, et eventuellement
|
|
|
|
// d'une valeur d'initialisation et d'un type de résolution
|
|
|
|
MatLapack (Enum_matrice enu_mat, int lb_totale,int dim , bool symetrique, double val_init //=0.0
|
|
|
|
,Enum_type_resolution_matri type_resol//=GAUSS
|
|
|
|
,Enum_preconditionnement type_precondi//= RIEN_PRECONDITIONNEMENT
|
|
|
|
);
|
|
|
|
|
|
|
|
// de copie
|
|
|
|
MatLapack (const MatLapack& a);
|
|
|
|
|
|
|
|
// DESTRUCTEUR VIRTUEL :
|
|
|
|
|
|
|
|
~MatLapack ();
|
|
|
|
|
|
|
|
|
|
|
|
// METHODES DÉCOULANT DE VIRTUELLES PURES :
|
|
|
|
|
|
|
|
// surcharge de l'opérateur d'affectation
|
|
|
|
// IMPORTANT : le fonctionnement de l'implantation dépend de la classe
|
|
|
|
// dérivée : en particulier il peut y avoir redimentionnement automatique
|
|
|
|
// de la matrice en fonction de l'attribut, cas par exemple des matrices
|
|
|
|
// pleines, ou message d'erreur car les tailles ne sont pas identiques
|
|
|
|
// exemple de la classe mat_band
|
|
|
|
// ici s'il s'agit de même matrices de même place, c'est ok, sinon erreur
|
|
|
|
MatLapack & operator = ( const MatLapack &);
|
|
|
|
|
|
|
|
// 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 );
|
|
|
|
|
|
|
|
Mat_abstraite & operator = ( const Mat_abstraite &);
|
|
|
|
|
|
|
|
//-----------------------------------------------------------------------------------
|
|
|
|
// --- 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)
|
|
|
|
// pour les 2 premières méthodes : += et -= :
|
|
|
|
// les matrices arguments sont en général du mêmes type que celui de la matrice this
|
|
|
|
// mais cela fonctionne également avec comme argument une matrice diagonale (pour tous les types)
|
|
|
|
|
|
|
|
// Surcharge de l'operateur += : addition d'une matrice a la matrice courante
|
|
|
|
void operator+= (const MatLapack& mat_pl);
|
|
|
|
void operator+= (const Mat_abstraite& mat_pl);
|
|
|
|
|
|
|
|
// Surcharge de l'operateur -= : soustraction d'une matrice a la matrice courante
|
|
|
|
void operator-= (const MatLapack& 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 ;
|
|
|
|
int operator== (const MatLapack& mat_pl)const ;
|
|
|
|
|
|
|
|
// fonction permettant de creer une nouvelle instance d'element
|
|
|
|
// dérivé. la nouvelle instance = *this, il y a donc utilisation du constructeur de copie
|
|
|
|
Mat_abstraite * NouvelElement() const;
|
|
|
|
|
|
|
|
// 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 du choix de la méthode de résolution si c'est possible
|
|
|
|
// peut être surchargé par les classes dérivées en fonction des spécificités
|
|
|
|
void Change_Choix_resolution(Enum_type_resolution_matri type_resol,
|
|
|
|
Enum_preconditionnement type_precondi);
|
|
|
|
|
|
|
|
// Initialisation des valeurs des composantes
|
|
|
|
void Initialise (double val_init);
|
|
|
|
|
|
|
|
// Liberation de la place memoire
|
|
|
|
void Libere ();
|
|
|
|
|
|
|
|
// Retour du nombre de lignes
|
|
|
|
int Nb_ligne () const {return nb_lign;};
|
|
|
|
|
|
|
|
// Retour du nombre de colonnes
|
|
|
|
int Nb_colonne () const {return nb_col;};
|
|
|
|
|
|
|
|
// Symetrie de la matrice
|
|
|
|
int Symetrie () const;
|
|
|
|
|
|
|
|
// Acces aux valeurs de la matrices en écriture
|
|
|
|
// i : indice de ligne, j : indice de colonne
|
|
|
|
double& operator () (int i, int j);
|
|
|
|
|
|
|
|
// Acces aux valeurs de la matrices en lecture
|
|
|
|
// cas ou l'on ne veut pas modifier les valeurs
|
|
|
|
// i : indice de ligne, j : indice de colonne
|
|
|
|
// !!! important, si l'élément n'existe pas du au type de stockage
|
|
|
|
// utilisé, (mais que les indices sont possible) le retour est 0
|
|
|
|
double operator () ( int i, int j) const;
|
|
|
|
|
|
|
|
// 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
|
|
|
|
bool Existe(int i, int j) const;
|
|
|
|
|
|
|
|
// Retourne la ieme ligne de la matrice
|
|
|
|
// lorsque implemente ( a verifier )
|
|
|
|
Vecteur& Ligne_set(int i);
|
|
|
|
|
|
|
|
// Retourne la ieme ligne de la matrice
|
|
|
|
Vecteur Ligne(int i) const;
|
|
|
|
|
|
|
|
// Retourne la ieme ligne de la matrice
|
|
|
|
// 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
|
|
|
|
void RemplaceLigneSpe(int i,const Vecteur & v);
|
|
|
|
|
|
|
|
//met une valeur identique sur toute la ligne
|
|
|
|
void MetValLigne(int i,double val);
|
|
|
|
|
|
|
|
// Retourne la jeme colonne de la matrice
|
|
|
|
Vecteur Colonne(int j) const;
|
|
|
|
|
|
|
|
// Retourne la jeme colonne de la matrice
|
|
|
|
// 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 colonne fournie
|
|
|
|
void RemplaceColonneSpe(int j,const Vecteur & v);
|
|
|
|
|
|
|
|
//met une valeur identique sur toute la colonne
|
|
|
|
void MetValColonne(int j,double val);
|
|
|
|
|
|
|
|
// Resolution du systeme Ax=b
|
|
|
|
//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
|
|
|
|
// ici on calcul la factorisation LU de la matrice
|
|
|
|
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 colonne 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;
|
|
|
|
|
|
|
|
// ------------ méthode non virtuelle pur -> générales ----------------
|
|
|
|
|
|
|
|
|
|
|
|
//calcul des valeurs propres par la méthode des puissances itérées
|
|
|
|
// inverses.
|
|
|
|
// --> Utilisable que pour des matrices carrées
|
|
|
|
// Intéressant lorsque l'on veut les plus petites
|
|
|
|
// valeurs propres, en nombre restreind car seule les premières valeurs
|
|
|
|
// sont calculées avec une précision convenable. On obtiend également
|
|
|
|
// les vecteurs propres correspondant.
|
|
|
|
// résolution de : ((*this) - lambda KG) X = 0
|
|
|
|
// en entrée : KG, VP dont la dimension est défini et fourni le nombre
|
|
|
|
// de valeurs propres que l'on veut calculer
|
|
|
|
// On considère que les conditions limites sont déjà appliquées à (*this) et KG.
|
|
|
|
// c'est à dire des 1 sur la diagonale pour (*this) et des 0 sur la diagonale pour KG
|
|
|
|
// en sortie : VP contiend les valeurs propres et vecteurs propres
|
|
|
|
|
|
|
|
Tableau <VeurPropre>* V_Propres(MatLapack& KG,Tableau <VeurPropre> & VP );
|
|
|
|
|
|
|
|
// ================ Méthodes spécifiques à la classe MatLapack ====================
|
|
|
|
|
|
|
|
// changement de taille avec initialisation non nulle éventuelle
|
|
|
|
// si les tailles existantes sont identiques, on ne fait que initialiser
|
|
|
|
void Change_taille(int nb_li,int nb_col, const double& val_init = 0.);
|
|
|
|
|
|
|
|
// Surcharge de l'operateur + : addition de deux matrices
|
|
|
|
// il y a création d'une matrice de sortie
|
|
|
|
MatLapack operator+ (const MatLapack& mat_pl) const;
|
|
|
|
|
|
|
|
// Surcharge de l'operateur - : soustraction entre deux matrices
|
|
|
|
// il y a création d'une matrice de sortie
|
|
|
|
MatLapack operator- (const MatLapack& mat_pl) const;
|
|
|
|
|
|
|
|
// Surcharge de l'operateur - : oppose d'une matrice
|
|
|
|
// il y a création d'une matrice de sortie
|
|
|
|
MatLapack operator- () const;
|
|
|
|
|
|
|
|
// Surcharge de l'operateur * : multiplication de deux matrices
|
|
|
|
// il y a création d'une matrice de sortie
|
|
|
|
MatLapack operator* (const MatLapack& mat_pl) const;
|
|
|
|
|
|
|
|
// Surcharge de l'operateur * : multiplication d'une matrice par un scalaire
|
|
|
|
// il y a création d'une matrice de sortie
|
|
|
|
MatLapack operator* (const double& coeff) const ;
|
|
|
|
|
|
|
|
// Retourne la transposee de la matrice mat
|
|
|
|
// il y a création d'une matrice de sortie
|
|
|
|
MatLapack Transpose () const;
|
|
|
|
|
|
|
|
// determine l'inverse d'une matrice carre
|
|
|
|
MatLapack Inverse();
|
|
|
|
// idem mais en retournant l'inverse dans la matrice passée en paramètre
|
|
|
|
// qui doit être de même taille
|
|
|
|
MatLapack& Inverse(MatLapack& mat) ;
|
|
|
|
|
|
|
|
protected :
|
|
|
|
|
|
|
|
// VARIABLES PROTEGEES :
|
|
|
|
//__CLPK_integer: long int en 32bit et int en 64bit, définit dans clapack.h
|
|
|
|
ENTIER_POUR_CLAPACK nb_lign,nb_col; // nombre de ligne, nombre de colonne utilisées par herezh
|
|
|
|
ENTIER_POUR_CLAPACK ldb; // nombre de ligne du stockage effectif
|
|
|
|
// --- dans le cas d'une matrice bande, nb_col est la largeur de bande totale
|
|
|
|
// dans le cas d'une matrice bande symétrique, nb_col=1/2largeur de bande+1
|
|
|
|
// on utilise des variables intermédiaires:
|
|
|
|
ENTIER_POUR_CLAPACK kl,ku,lda; // correspond à la largeur en dessous et au dessus de la diagonale
|
|
|
|
//lda: largeur maxi du premier indice, qu'utilise réellement lapack: = 2*kl+ku+1 en bande non symétrique
|
|
|
|
// dans le cas d'une matrice rectangulaire = nb_lign
|
|
|
|
|
|
|
|
|
|
|
|
Vecteur mat; // la matrice vue comme un vecteur
|
|
|
|
// le stockage dépend du type de matrice considérée
|
|
|
|
//-- cas des matrices tridiagonales:
|
|
|
|
Vecteur B,C; // ligne sup et inf. La diagonale est stockée dans mat
|
|
|
|
|
|
|
|
//------- variables utilisées pour la résolution de systèmes avec lapack -----------
|
|
|
|
// ces variables sont indépendantes de la matrice donc ne rentre pas en ligne de compte dans les opérateurs
|
|
|
|
// par exemple (échange, sauvegarde ....)
|
|
|
|
ENTIER_POUR_CLAPACK * ipiv; // la matrice des pivots d'indices qui défini la matrice de permutation P
|
|
|
|
// utilisé par le prog clapack: dgesv_
|
|
|
|
MatLapack* ptB; // array intermédiaires contenant en entrée les seconds membres et en sortie les résultats
|
|
|
|
Vecteur travail; // espace de travail
|
|
|
|
|
|
|
|
// pointeur d'acces aux coordonnées avec i variant de 1 à nb_lign et j variant de 1 à nb_col
|
|
|
|
double& (MatLapack::*Coor) (int i, int j );
|
|
|
|
double (MatLapack::*Coor_const) (int i, int j ) const;
|
|
|
|
|
|
|
|
// ----- declaration des différents accès aux composantes
|
|
|
|
// 1) pour une matrice générale non sym, rectangulaire: stockage de type GE
|
|
|
|
double& Coor_GE(int i, int j)
|
|
|
|
#ifdef MISE_AU_POINT
|
|
|
|
{ return mat((j-1)*lda + i); };
|
|
|
|
#else
|
|
|
|
{ return mat.v[(j-1)*lda + i - 1]; };
|
|
|
|
#endif
|
|
|
|
double Coor_GE_const(int i, int j) const
|
|
|
|
#ifdef MISE_AU_POINT
|
|
|
|
{ return mat((j-1)*lda + i); };
|
|
|
|
#else
|
|
|
|
{ return mat.v[(j-1)*lda + i - 1]; };
|
|
|
|
#endif
|
|
|
|
// 2) pour une matrice bande générale: nb_col = la largeur de bande: stockage de type GB
|
|
|
|
double& Coor_GB(int i, int j)
|
|
|
|
#ifdef MISE_AU_POINT
|
|
|
|
{ return mat( (j-1)*lda + nb_col + i-j ); };
|
|
|
|
#else
|
|
|
|
{ return mat.v[( (j-1)*lda + nb_col + i-j ) - 1]; };
|
|
|
|
#endif
|
|
|
|
double Coor_GB_const(int i, int j) const
|
|
|
|
#ifdef MISE_AU_POINT
|
|
|
|
{ return mat( (j-1)*lda + nb_col + i-j ); };
|
|
|
|
#else
|
|
|
|
{ return mat.v[( (j-1)*lda + nb_col + i-j ) - 1]; };
|
|
|
|
#endif
|
|
|
|
// 3) pour une matrice bande symétrique: nb_col = la 1/2 largeur de bande: stockage de type PB
|
|
|
|
// c'est à dire symétrique positif, avec un stockage 'U'
|
|
|
|
// AB(ku+1+i-j,j) = A(i,j) pour max(1,j-ku) <= i <= j
|
|
|
|
double& Coor_PB(int i, int j)
|
|
|
|
#ifdef MISE_AU_POINT
|
|
|
|
{ if (j >= i) return mat( (j-1)*lda + nb_col + i-j);
|
|
|
|
else return mat( (i-1)*lda + nb_col + j-i);};
|
|
|
|
#else
|
|
|
|
{ if (j >= i) return mat.v[( (j-1)*lda + nb_col + i-j ) - 1];
|
|
|
|
else return mat.v[( (i-1)*lda + nb_col + j-i ) - 1];};
|
|
|
|
#endif
|
|
|
|
double Coor_PB_const(int i, int j) const
|
|
|
|
#ifdef MISE_AU_POINT
|
|
|
|
{ if (j >= i) return mat( (j-1)*lda + nb_col + i-j);
|
|
|
|
else return mat( (i-1)*lda + nb_col + j-i);};
|
|
|
|
#else
|
|
|
|
{ if (j >= i) return mat.v[( (j-1)*lda + nb_col + i-j ) - 1];
|
|
|
|
else return mat.v[( (i-1)*lda + nb_col + j-i ) - 1];};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
// 4) pour une matrice carré symétrique: nb_col = la 1/2 largeur de bande: stockage de type PP
|
|
|
|
// c'est à dire symétrique positif, avec un stockage 'U' et stockage carré compacté
|
|
|
|
// AB(i+(j-1)*j/2) = A(i,j) pour 1 <= i <= j
|
|
|
|
double& Coor_PP(int i, int j)
|
|
|
|
#ifdef MISE_AU_POINT
|
|
|
|
{ if (j >= i) return mat( (j-1)*j/2 + i);
|
|
|
|
else return mat( (i-1)*i/2 + j);};
|
|
|
|
#else
|
|
|
|
{ if (j >= i) return mat.v[ (j-1)*j/2 + i - 1];
|
|
|
|
else return mat.v[ (i-1)*i/2 + j - 1];};
|
|
|
|
#endif
|
|
|
|
double Coor_PP_const(int i, int j) const
|
|
|
|
#ifdef MISE_AU_POINT
|
|
|
|
{ if (j >= i) return mat( (j-1)*j/2 + i);
|
|
|
|
else return mat( (i-1)*i/2 + j);};
|
|
|
|
#else
|
|
|
|
{ if (j >= i) return mat.v[ (j-1)*j/2 + i - 1];
|
|
|
|
else return mat.v[ (i-1)*i/2 + j - 1];};
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
// 5) pour une matrice tridiagonale quelconque : mat contient la diagonale
|
|
|
|
// B la diag sup, C la diag inf
|
|
|
|
// A(i-1,i) = B(i-1)
|
|
|
|
// A(i,i-1) = C(i-1); A(i,i) = mat(i); A(i,i+1) = B(i)
|
|
|
|
// A(i+1,i) = C(i)
|
|
|
|
// la suite = def de l'accès aux composantes: en chantier
|
|
|
|
|
|
|
|
|
|
|
|
// fonction interne de vérification des composantes
|
|
|
|
// arrêt si pb
|
|
|
|
void Verif_nb_composante(const Vecteur& b,string nom_routine) const ;
|
|
|
|
void Verif_nb_composante(const Tableau <Vecteur>& b,string nom_routine) const ;
|
|
|
|
// gestion erreur dgesv et dgbsv
|
|
|
|
void GestionErreurDg_sv(const int& info) const;
|
|
|
|
// gestion erreur dpbsv
|
|
|
|
void GestionErreurDpbsv(const int& info) const;
|
|
|
|
// gestion erreur Inverse
|
|
|
|
void GestionErreurInverse(const int& info,int cas,const string nom_routine_lapack) const;
|
|
|
|
|
|
|
|
};
|
|
|
|
/// @} // end of group
|
|
|
|
|
|
|
|
// pour l'instant on n'arrive pas à faire des includes en linux ??
|
|
|
|
#ifndef MISE_AU_POINT
|
|
|
|
#undef MatLapack_H_deja_inclus
|
|
|
|
#include "MatLapack.cc"
|
|
|
|
#define MatLapack_H_deja_inclus
|
|
|
|
#endif
|
|
|
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|