// FICHIER : Coordonnee.h
// CLASSE : Coordonnee
  
 // 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                                               *
*                                                                $     *
*     PROJET:      Herezh++                                            *
*                                                                $     *
************************************************************************
* BUT: Les classes Coordonnee servent a la localisation dans l'espace  *
*     des objets tels que les noeuds ou les points.   Une instance de  *
*     cette classe est caracterisee par le nombre de coordonnees et    *
*     par la valeur de celles-ci.                                      *
*     Les valeurs des coordonnees sont de type double et sont stockees *
*     dans un tableau  dont la taille depend de la dimension du        *
*     probleme.                                                        *
*                                                                $     *
*     ''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''     *
************************************************************************/

                                                    

#ifndef COORDONNEE_H
#define COORDONNEE_H


//#include "Debug.h"
#include <iostream>
#include <fstream>
#include "UtilLecture.h"
#include <stdlib.h>
#include "Sortie.h"
#include "Enum_IO_XML.h"
#include "PtTabRel.h"

class Vecteur;  // declare a la fin du fichier, car Vecteur utilise aussi Coordonnee
class CoordonneeH; class CoordonneeB;


/** @defgroup Les_classes_coordonnee
 *
 *     BUT:   Les classes de type Coordonnee servent à la localisation dans l'espace
 *     des objets tels que les points ou les noeuds etc.\n Une instance de
 *     cette classe est caracterisée par le nombre de coordonnées et
 *     par la valeur de celles-ci.
 *     \n Les valeurs des coordonnées sont de type double et sont stockées
 *     dans un tableau  dont la taille depend de la dimension du
 *     problème.
* \author    Gérard Rio
* \version   1.0
* \date       23/01/97
* \brief       Définition des classes de type Coordonnee, en coordonnées sans variance (ex:  absolues)
*  ou en coordonnées locales c'est-à-dire en coordonnées covariantes ou contravariantes
 *
 */



/// @addtogroup Les_classes_coordonnee
///  @{
///

//==============================================================================
//    cas des coordonnées simples sans variance
//==============================================================================

//!  Coordonnees simples sans variances


class Coordonnee
{

  /// surcharge de l'operator de lecture  avec le type
  friend istream & operator >> (istream &, Coordonnee &);
  
  /// surcharge de l'operator d'ecriture
  friend ostream & operator << (ostream &, const Coordonnee &);
    
  /// Surcharge de l'operateur * : multiplication entre un scalaire et des coordonnees
  inline friend Coordonnee operator* (double val,const Coordonnee& c)
     { return (c*val); };
     
  friend class BaseH; friend class BaseB;   
      
	public :
		// CONSTRUCTEURS :
		
		/// Constructeur par defaut
		Coordonnee () ;
  /*! \brief
		// Constructeur fonction de la dimension du probleme
		// les coordonnees sont initialise a zero
  */
		Coordonnee (int dimension);		
		/// Constructeur pour une localisation unidimensionnelle
		Coordonnee (double x);		
		/// Constructeur pour une localisation bidimensionnelle
		Coordonnee (double x,double y);		
		// Constructeur pour une localisation tridimensionnelle
		Coordonnee (double x,double y,double z);
  /*! \brief
		// constructeur fonction d'une adresse memoire ou sont stockee les coordonnees
		// et d'une dimension ( l'existance de la place mémoire est a la charge
		//  de l'utilisateur et ne sera pas détruite par le destructeur.)
  */
		Coordonnee (int dimension,double* t);
		// Constructeur fonction d'un vecteur qui doit avoir une dim = 1 ou 2 ou 3
// on supprime car il y a plein de conversion n'ont explicite, le mieux est d'utiliser
// l'opérateur Vect(), qui permet "explicitement" de créer un coordonnée et ensuite d'utiliser
// le constructeur en fonction de coordonnée

////on pourrait faire une fonction à la place
		
//		Coordonnee ( const Vecteur& vec);
////        Construit(const Vecteur& vec);

		/// Constructeur de copie
		Coordonnee (const Coordonnee& c);
				
		/// DESTRUCTEUR :
  virtual ~Coordonnee ();
				
		// METHODES :
		
  /*! \brief
		// fonction équivalente au constructeur: changement pour une place externe via un pointeur
		// ( l'existance de la place mémoire est a la charge
		//  de l'utilisateur et ne sera pas détruite par le destructeur.)
  */
		void Change_place(int dimension,double* t);
		
		// changement des coordonnees
		// rapide si c'est la même dimension !!
  /// changement rapide des coordonnées: dimension 1
		void Change_Coordonnee(int dimension, double x)	;  // dimension 1
  /// changement rapide des coordonnées: dimension 2
		void Change_Coordonnee(int dimension, double x,double y)	;  // dimension 2
  /// changement rapide des coordonnées: dimension 3
		void Change_Coordonnee(int dimension, double x,double y,double z)	;  // dimension 3
		
		/// Renvoie le nombre de coordonnees
		virtual int Dimension () const ;
		/// Desallocation de la place memoire allouee
		virtual void Libere ();
  /// Renvoie la ieme coordonnee
  virtual double& operator() (int i);
  /// Renvoie une copie de la ieme coordonnee
  virtual double operator() (int i) const; 
		/// Surcharge de l'operateur = : realise l'affectation entre deux points
		Coordonnee& operator= (const Coordonnee& c);
		// Surcharge de l'operateur = avec un vecteur
// trop dangereux, car il y a plein de conversion implicite, donc ce qu'il vaut mieux
// faire, c'est une conversion "explicite" à l'aide de Vect() 
//		Coordonnee& operator= ( const  Vecteur& c);
//		Coordonnee& Egale_vecteur ( const  Vecteur& c);
		/// Surcharge de l'operateur - : renvoie l'oppose d'un point
		Coordonnee operator- () const; 
		/// Surcharge de l'operateur - : realise la soustraction des coordonnees de deux points
		Coordonnee operator- (const Coordonnee& c) const; 
		/// Surcharge de l'operateur + : realise l'addition des coordonnees de deux points
		Coordonnee operator+ (const Coordonnee& c) const; 
		/// Surcharge de l'operateur +=
		void operator+= (const Coordonnee& c);
		/// Surcharge de l'operateur -=
		void operator-= (const Coordonnee& c);
		/// Surcharge de l'operateur *=
		void operator*= (double val);
		/// Surcharge de l'operateur * : multiplication de coordonnees par un scalaire
		Coordonnee operator* (double val) const; 
		/// Surcharge de l'operateur * : produit scalaire entre coordonnees
		double operator* (const Coordonnee& c) const ;
		/// Surcharge de l'operateur / : division de coordonnees par un scalaire
		Coordonnee operator/ (double val) const  ;
		/// Surcharge de l'operateur /= : division de coordonnees par un scalaire
		void operator/= (double val) ;
  /*! \brief
		// Surcharge de l'operateur == : test d'egalite
		// Renvoie 1 si les deux positions sont identiques
		// Renvoie 0 sinon
  */
		int operator== (const Coordonnee& c) const; 
  /*! \brief
		// Surcharge de l'operateur !=
		// Renvoie 1 si les deux positions ne sont pas identiques
		// Renvoie 0 sinon
  */
		int operator!= (const Coordonnee& c) const; 
		/// Affiche les coordonnees du point à l'écran entre accolades
		virtual void Affiche () const; 
		/// Affiche les coordonnees du point dans sort entre accolades
		virtual void Affiche (ostream& sort) const ;
  /*! \brief
		// Affiche les coordonnees du point dans sort sur nb digit plus un blanc
		// et rien d'autre (pas d'accolade)
  */
		virtual void Affiche (ostream& sort,int nb) const ;
		/// Affiche les coordonnees du point dans sort et rien d'autre (pas d'accolade)
		virtual void Affiche_1 (ostream& sort) const ;
		/// lecture brut des coordonnées sans la dimension
		virtual void Lecture (UtilLecture& entreePrinc);
		/// lecture brut des coordonnées sans la dimension dans le flux par défaut
		virtual void Lecture ();
  /*! \brief
		// changement de la dimension
		// dans le cas d'une nouvelle dimension inferieur on supprime les dernieres coord
		// dans le cas d'une dimension superieur, on ajoute des coord initialisees a zero
  */
		virtual void Change_dim(int dim);		
  ///  création d'un Vecteur équivalent
  virtual Vecteur Vect() const ;
  /// mise a zero des coordonnées
		virtual void Zero(); 
		/// Calcul de la norme euclidienne des composantes du point
		virtual double Norme ()  const ;
		/// norme le vecteur coordonnée
		Coordonnee& Normer ();
		/// Calcul du maximum en valeur absolu des composantes du vecteur
		double Max_val_abs ()  const ;
  /// ramène l'indice du maxi en valeur absolu
  int Indice_max_val_abs() const;
  /*! \brief
		// Calcul du maximum en valeur absolu des composantes du vecteur
		// ramene egalement l'indice de tableau du maximum
  */
		double Max_val_abs (int& i)  const ;
  /*! \brief
		// Calcul du maximum en valeur absolu des composantes du vecteur
		// mais ramène la grandeur signée (avec son signe)
  */
		double Max_val_abs_signe()  const ;		
  /*! \brief
		// Calcul du maximum en valeur absolu des composantes du vecteur
		// mais ramène la grandeur signée (avec son signe)
		// ramene egalement l'indice de tableau du maximum
  */
		double Max_val_abs_signe(int& i)  const ;		
  /*! \brief
		// modifie éventuellement les coordonnées de this pour quelles soient supérieures ou égales
		// aux coordonnées en paramètre
  */
		void Modif_en_max(const Coordonnee& v);
  /*! \brief
		// modifie éventuellement les coordonnées de this pour quelles soient inférieures ou égales
		// aux coordonnées en paramètre
  */
		void Modif_en_min(const Coordonnee& v);
		/// ajoute une même valeur à tous les coordonnées
		void Ajout_meme_valeur(double val);
		/// calcul la norme euclidienne au carré
		double Carre()const {return (*this) * (*this);};
  /// sortie du schemaXML: en fonction de enu
  static void SchemaXML_Coordonnee(ofstream& sort,const Enum_IO_XML enu) ;
  // changement de base
  // beta(i,j) represente les coordonnees de la nouvelle base gp dans l'ancienne g
  // gp(i) = beta(i,j) * g(j)
//        void ChBase( const Mat_pleine& beta); 
		
	protected :
	 /// dimension
		short int dim;
  /// indique s'il y a allocation ou pas
		bool memoire;
  /// stockage
		double* coord;
		
  /*! \brief
		// Constructeur inline qui ne fait rien
		// utilisé par les classes dérivées
  */
		Coordonnee (bool ) : dim(-1), coord (NULL),memoire(true) {};
		/// définit des coordonnées sans variance à la même place que des coordonnées avec variances
		void Meme_place(CoordonneeB& vB);
  /// définit des coordonnées sans variance à la même place que des coordonnées avec variances
		void Meme_place(CoordonneeH& vH);
		
};
/// @}  // end of group




class CoordonneeB;  // défini par la suite ( nécessaire pour le produit scalaire)
//class BaseH; // pour déclarer une classe friend

/// @addtogroup Les_classes_coordonnee
///  @{
///

//==============================================================================
//!    cas des coordonnées contravariantes
//==============================================================================

class CoordonneeH
{ 
   /// surcharge de l'operator de lecture avec le type
   friend istream & operator >> (istream &, CoordonneeH &);
   /// surcharge de l'operator d'ecriture
   friend ostream & operator << (ostream &, const CoordonneeH &);
   /// Surcharge de l'operateur * : multiplication entre un scalaire et des coordonnees
   inline friend CoordonneeH operator* (double val,const CoordonneeH& c) 
      { return (c*val); };
   
   // déclaration de la classe BaseH comme friend, pour pouvoir faire une relation entre
   // un CoordonneeH et un Coordonnee
//   friend class BaseH; 
   friend class Coordonnee;  friend class CoordonneeB;  

	public :
		// CONSTRUCTEURS :
		
		/// Constructeur par defaut
		CoordonneeH () ;
  /*! \brief
		// Constructeur fonction de la dimension du probleme
		// les coordonnees sont initialise a zero
  */
		CoordonneeH (int dimension);		
		/// Constructeur pour une localisation unidimensionnelle
		CoordonneeH (double x);		
		/// Constructeur pour une localisation bidimensionnelle
		CoordonneeH (double x,double y);		
		/// Constructeur pour une localisation tridimensionnelle
		CoordonneeH (double x,double y,double z);
  /*! \brief
		// constructeur fonction d'une adresse memoire ou sont stockee les coordonnees
		// et d'une dimension ( l'existance de la place mémoire est a la charge
		//  de l'utilisateur et ne sera pas détruite par le destructeur.
  */
		CoordonneeH (int dimension,double* t);						
		// Constructeur fonction d'un vecteur qui doit avoir une dim = 1 ou 2 ou 3
// on supprime car il y a plein de conversion n'ont explicite, le mieux est d'utiliser
// l'opérateur Vect(), qui permet "explicitement" de créer un coordonnée et ensuite d'utiliser
// le constructeur en fonction de coordonnée		
//		CoordonneeH ( const Vecteur& vec);
		/// Constructeur de copie
		CoordonneeH (const CoordonneeH& c);
				
		/// DESTRUCTEUR :
  virtual ~CoordonneeH ();
				
		// METHODES :
		
  /*! \brief
		// construction "explicite" à partir d'une instance de CoordonneeB
		// intéressant si this est initialement construit par defaut (donc vide)
		// cela permet de créer un CoordonneeH à partir d'un B, mais de manière explicite,
		// donc activé quand on le veux (et non pas par le compilo au gré de conversion pas toujours clair!!)
  */
		void ConstructionAPartirDe_B(const CoordonneeB& aB);
		
		/// Renvoie le nombre de coordonnees
		virtual int Dimension () const ;
		/// Desallocation de la place memoire allouee
		virtual void Libere ();
  /// Renvoie la ieme coordonnee
  virtual double& operator() (int i);
  /// Renvoie une copie de la ieme coordonnee
  virtual double operator() (int i) const; 
		// Surcharge de l'operateur = : realise l'affectation entre deux points 
		CoordonneeH& operator= (const CoordonneeH& c);
  /// change les valeurs en fonction d'un point sans variance
  void Change_val(const Coordonnee& c);
		// Surcharge de l'operateur = avec un vecteur
// trop dangereux, car il y a plein de conversion implicite, donc ce qu'il vaut mieux
// faire, c'est une conversion "explicite" à l'aide de Vect() 
//		CoordonneeH& operator= ( const  Vecteur& c);
//		CoordonneeH& Egale_vecteur ( const  Vecteur& c);
		/// Surcharge de l'operateur - : renvoie l'oppose d'un point
		CoordonneeH operator- () const; 
		/// Surcharge de l'operateur - : realise la soustraction des coordonnees de deux points
		CoordonneeH operator- (const CoordonneeH& c) const; 
		/// Surcharge de l'operateur + : realise l'addition des  coordonnees de deux points
		CoordonneeH operator+ (const CoordonneeH& c) const; 
		/// Surcharge de l'operateur +=
		void operator+= (const CoordonneeH& c);
		/// Surcharge de l'operateur -=
		void operator-= (const CoordonneeH& c);
		/// Surcharge de l'operateur *=
		void operator*= (double val);
		/// Surcharge de l'operateur * : multiplication de coordonnees par un scalaire
		CoordonneeH operator* (double val) const; 
		/// Surcharge de l'operateur * : produit scalaire entre coordonnees
		double operator* (const CoordonneeB& c) const ;
		///  produit scalaire entre coordonnees contravariantes et contravariantes
		double ScalHH(const CoordonneeH& c) const ;
		/// Surcharge de l'operateur / : division de coordonnees par un scalaire
		CoordonneeH operator/ (double val) const  ;
		/// Surcharge de l'operateur /= : division de coordonnees par un scalaire
		void operator/= (double val) ;
  /*! \brief
		// Surcharge de l'operateur == : test d'egalite
		// Renvoie 1 si les deux positions sont identiques
		// Renvoie 0 sinon
  */
		int operator== (const CoordonneeH& c) const; 
  /*! \brief
		// Surcharge de l'operateur !=
		// Renvoie 1 si les deux positions ne sont pas identiques
		// Renvoie 0 sinon
  */
		int operator!= (const CoordonneeH& c) const; 
		/// Affiche les coordonnees du point à l'écran
		virtual void Affiche () const; 
		/// Affiche les coordonnees du point dans sort
		virtual void Affiche (ostream& sort) const ;
		/// Affiche les coordonnees du point dans sort sur nb digit plus un blanc et rien d'autre
		virtual void Affiche (ostream& sort,int nb) const ;		
		/// lecture brut des coordonnées sans la dimension
		virtual void Lecture (UtilLecture& entreePrinc);
  /*! \brief
		// changement de la dimension
		// dans le cas d'une nouvelle dimension inferieur on supprime les dernieres coord
		// dans le cas d'une dimension superieur, on ajoute des coord initialisees a zero
  */
		virtual void Change_dim(int dim);		
  ///  création d'un  Vecteur équivalent
  virtual Vecteur Vect() const ;
  /// création de  coordonnées équivalentes sans variance
  virtual Coordonnee Coor() const; 
  /*! \brief
  // création explicite en coordonnées sans variance
  // mais le vecteur est à la même place pour un coût de construction minimum, 
  // il est accessible en lecture uniquement
  */
  virtual const Coordonnee Coor_const()const ;
  /// création explicite de H en B
  virtual CoordonneeB Haut_bas()const;
  /// mise a zero des coordonnées
		virtual void Zero(); 
		/// Calcul de la norme euclidienne des composantes du point
		virtual double Norme ()  const ;
		/// norme le vecteur coordonnée
		CoordonneeH& Normer ();
		/// Calcul du maximum en valeur absolu des composantes du vecteur
		double Max_val_abs ()  const ;		
  /*! \brief
		// Calcul du maximum en valeur absolu des composantes du vecteur
		// ramene egalement l'indice de tableau du maximum
  */
		double Max_val_abs (int& i)  const ;
  /*! \brief
		// Calcul du maximum en valeur absolu des composantes du vecteur
		// mais ramène la grandeur signée (avec son signe)
  */
		double Max_val_abs_signe()  const ;		
  /*! \brief
		// Calcul du maximum en valeur absolu des composantes du vecteur
		// mais ramène la grandeur signée (avec son signe)
		// ramene egalement l'indice de tableau du maximum
  */
		double Max_val_abs_signe(int& i)  const ;		
  /*! \brief
		// modifie éventuellement les coordonnées de this pour quelles soient supérieures ou égales
		// aux coordonnées en paramètre
  */
		void Modif_en_max(const CoordonneeH& v);
  /*! \brief
		// modifie éventuellement les coordonnées de this pour quelles soient inférieures ou égales
		// aux coordonnées en paramètre
  */
		void Modif_en_min(const CoordonneeH& v);
		/// ajoute une même valeur à tous les coordonnées
		void Ajout_meme_valeur(double val);  
  /// sortie du schemaXML: en fonction de enu
  static void SchemaXML_Coordonnee(ofstream& sort,const Enum_IO_XML enu) ;
  // changement de base
  // beta(i,j) represente les coordonnees de la nouvelle base gpB dans l'ancienne gB
  // gpB(i) = beta(i,j) * gB(j)
//        void ChBase( const Mat_pleine& beta);
  
		
	protected :
	
		short int dim;
		bool memoire; // indique s'il y a allocation ou pas
		double* coord;
		/// Constructeur inline qui ne fait rien
		CoordonneeH (bool ):dim (-1) , coord (NULL),memoire(true) {};
		
};
/// @}  // end of group

/// @addtogroup Les_classes_coordonnee
///  @{
///
//==============================================================================
//!    cas des coordonnées covariantes
//==============================================================================

class CoordonneeB
{ 
   /// surcharge de l'operator de lecture avec le type
   friend istream & operator >> (istream &, CoordonneeB &);
   /// surcharge de l'operator d'ecriture
   friend ostream & operator << (ostream &, const CoordonneeB &);
   /// Surcharge de l'operateur * : multiplication entre un scalaire et des coordonnees
   inline friend CoordonneeB operator* (double val,CoordonneeB& c)
      { return (c*val); };

   friend class Coordonnee;friend class CoordonneeH;    
	public :
		// CONSTRUCTEURS :
		
		/// Constructeur par defaut
		CoordonneeB () ;
  /*! \brief
		// Constructeur fonction de la dimension du probleme
		// les coordonnees sont initialise a zero
  */
		CoordonneeB (int dimension);		
		/// Constructeur pour une localisation unidimensionnelle
		CoordonneeB (double x);		
		/// Constructeur pour une localisation bidimensionnelle
		CoordonneeB (double x,double y);		
		/// Constructeur pour une localisation tridimensionnelle
		CoordonneeB (double x,double y,double z);
  /*! \brief
		// constructeur fonction d'une adresse memoire ou sont stockee les coordonnees
		// et d'une dimension ( l'existance de la place mémoire est a la charge
		//  de l'utilisateur et ne sera pas détruite par le destructeur.
  */
		CoordonneeB (int dimension,double* t);						
		// Constructeur fonction d'un vecteur qui doit avoir une dim = 1 ou 2 ou 3
// on supprime car il y a plein de conversion n'ont explicite, le mieux est d'utiliser
// l'opérateur Vect(), qui permet "explicitement" de créer un coordonnée et ensuite d'utiliser
// le constructeur en fonction de coordonnée		
//		CoordonneeB ( const Vecteur& vec);
		/// Constructeur de copie
		CoordonneeB (const CoordonneeB& c);
				
		/// DESTRUCTEUR :
	 virtual ~CoordonneeB ();
				
		// METHODES :
		
		
  /*! \brief
		// construction "explicite" à partir d'une instance de CoordonneeB
		// intéressant si this est initialement construit par defaut (donc vide)
		// cela permet de créer un CoordonneeH à partir d'un B, mais de manière explicite,
		// donc activé quand on le veux (et non pas par le compilo au gré de conversion pas toujours clair!!)
  */
		void ConstructionAPartirDe_H(const CoordonneeH& aH);
		
		/// Renvoie le nombre de coordonnees
		virtual int Dimension () const ;
		/// Desallocation de la place memoire allouee
		virtual void Libere ();
  /// Renvoie la ieme coordonnee
  virtual double& operator() (int i);
  /// Renvoie une copie de la ieme coordonnee
  virtual double operator() (int i) const; 
		/// Surcharge de l'operateur = : realise l'affectation entre deux points
		CoordonneeB& operator= (const CoordonneeB& c);
  /// change les valeurs en fonction d'un point sans variance
  void Change_val(const Coordonnee& c);
 
		// Surcharge de l'operateur = avec un vecteur		
// trop dangereux, car il y a plein de conversion implicite, donc ce qu'il vaut mieux
// faire, c'est une conversion "explicite" à l'aide de Vect() 
//		CoordonneeB& operator= ( const  Vecteur& c);
//		CoordonneeB& Egale_vecteur ( const  Vecteur& c);
		/// Surcharge de l'operateur - : renvoie l'oppose d'un point
		CoordonneeB operator- () const; 
		/// Surcharge de l'operateur - : realise la soustraction des coordonnees de deux points
		CoordonneeB operator- (const CoordonneeB& c) const; 
		/// Surcharge de l'operateur + : realise l'addition des coordonnees de deux points
		CoordonneeB operator+ (const CoordonneeB& c) const; 
		/// Surcharge de l'operateur +=
		void operator+= (const CoordonneeB& c);
		/// Surcharge de l'operateur -=
		void operator-= (const CoordonneeB& c);
		/// Surcharge de l'operateur *=
		void operator*= (double val);
		/// Surcharge de l'operateur * : multiplication de coordonnees par un scalaire
		CoordonneeB operator* (double val) const; 
		/// Surcharge de l'operateur * : produit scalaire entre coordonnees
		double operator* (const CoordonneeH& c) const ;
		///  produit scalaire entre coordonnees covariantes et covariantes
		double ScalBB(const CoordonneeB& c) const ;
		/// Surcharge de l'operateur / : division de coordonnees par un scalaire
		CoordonneeB operator/ (double val) const  ;
		/// Surcharge de l'operateur /= : division de coordonnees par un scalaire
		void operator/= (double val) ;
  /*! \brief
		// Surcharge de l'operateur == : test d'egalite
		// Renvoie 1 si les deux positions sont identiques
		// Renvoie 0 sinon
  */
		int operator== (const CoordonneeB& c) const; 
  /*! \brief
		// Surcharge de l'operateur !=
		// Renvoie 1 si les deux positions ne sont pas identiques
		// Renvoie 0 sinon
  */
		int operator!= (const CoordonneeB& c) const; 
		/// Affiche les coordonnees du point à l'écran
		virtual void Affiche () const; 
		/// Affiche les coordonnees du point dans sort
		virtual void Affiche (ostream& sort) const ;
		// Affiche les coordonnees du point dans sort sur nb digit plus un blanc
		// et rien d'autre
		virtual void Affiche (ostream& sort,int nb) const ;		
		/// lecture brut des coordonnées sans la dimension
		virtual void Lecture (UtilLecture& entreePrinc);
  /*! \brief
		// changement de la dimension
		// dans le cas d'une nouvelle dimension inferieur on supprime les dernieres coord
		// dans le cas d'une dimension superieur, on ajoute des coord initialisees a zero
  */
		virtual void Change_dim(int dim);		
  ///  conversion en Vecteur
  virtual Vecteur Vect() const ;
  /// conversion explicite en coordonnées sans variance
  virtual Coordonnee Coor()const ;
  /*! \brief
  // création explicite en coordonnées sans variance
  // mais le vecteur est à la même place pour un coût de construction minimum, 
  // il est accessible en lecture uniquement
  */
  virtual const Coordonnee Coor_const()const ;
  /// conversion explicite de B en H
  virtual CoordonneeH Bas_haut()const;
  /// mise a zero des coordonnées
		virtual void Zero(); 
		/// Calcul de la norme euclidienne des composantes du point
		virtual double Norme ()  const ;
		/// norme le vecteur coordonnée
		CoordonneeB& Normer ();
		/// Calcul du maximum en valeur absolu des composantes du vecteur
		double Max_val_abs ()  const ;		
  /*! \brief
		// Calcul du maximum en valeur absolu des composantes du vecteur
		// ramene egalement l'indice de tableau du maximum
  */
		double Max_val_abs (int& i)  const ;
		// Calcul du maximum en valeur absolu des composantes du vecteur
		// mais ramène la grandeur signée (avec son signe)
		double Max_val_abs_signe()  const ;		
  /*! \brief
		// Calcul du maximum en valeur absolu des composantes du vecteur
		// mais ramène la grandeur signée (avec son signe)
		// ramene egalement l'indice de tableau du maximum
  */
		double Max_val_abs_signe(int& i)  const ;		
  /*! \brief
		// modifie éventuellement les coordonnées de this pour quelles soient supérieures ou égales
		// aux coordonnées en paramètre
  */
		void Modif_en_max(const CoordonneeB& v);
  /*! \brief
		// modifie éventuellement les coordonnées de this pour quelles soient inférieures ou égales
		// aux coordonnées en paramètre
  */
		void Modif_en_min(const CoordonneeB& v);
		/// ajoute une même valeur à tous les coordonnées
		void Ajout_meme_valeur(double val);  
  /// sortie du schemaXML: en fonction de enu
  static void SchemaXML_Coordonnee(ofstream& sort,const Enum_IO_XML enu) ;
  // changement de base
  // beta(i,j) represente les coordonnees de la nouvelle base duale gpH dans l'ancienne gH
  // gpH(i) = beta(i,j) * gH(j), i indice de ligne, j indice de colonne
//        void ChBase( const Mat_pleine& beta);

		
	protected :
	
		short int dim;
	    bool memoire; // indique s'il y a allocation ou pas
		double* coord;
		// Constructeur inline qui ne fait rien 
		CoordonneeB (bool ):dim (-1) , coord (NULL),memoire(true) {};
		
};
/// @}  // end of group

#ifndef MISE_AU_POINT
  #include "Coordonnee.cc"
  #include "CoordonneeH.cc"
  #include "CoordonneeB.cc"
  #define  COORDONNEE_H_deja_inclus
#endif


//#include "Vecteur.h"
#endif

