tenseur_sym_arithm.C

00001 /*
00002  *  Arithmetics functions for the Tenseur_sym class.
00003  *
00004  *  These functions are not member functions of the Tenseur_sym class.
00005  *
00006  *  (see file tenseur.h for documentation).
00007  *
00008  */
00009 
00010 /*
00011  *   Copyright (c) 1999-2001 Philippe Grandclement
00012  *   Copyright (c) 2000-2001 Eric Gourgoulhon
00013  *
00014  *   This file is part of LORENE.
00015  *
00016  *   LORENE is free software; you can redistribute it and/or modify
00017  *   it under the terms of the GNU General Public License as published by
00018  *   the Free Software Foundation; either version 2 of the License, or
00019  *   (at your option) any later version.
00020  *
00021  *   LORENE is distributed in the hope that it will be useful,
00022  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00023  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00024  *   GNU General Public License for more details.
00025  *
00026  *   You should have received a copy of the GNU General Public License
00027  *   along with LORENE; if not, write to the Free Software
00028  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00029  *
00030  */
00031 
00032 
00033 char tenseur_sym_arithm_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tenseur/tenseur_sym_arithm.C,v 1.5 2003/06/20 14:54:17 f_limousin Exp $" ;
00034 
00035 /*
00036  * $Id: tenseur_sym_arithm.C,v 1.5 2003/06/20 14:54:17 f_limousin Exp $
00037  * $Log: tenseur_sym_arithm.C,v $
00038  * Revision 1.5  2003/06/20 14:54:17  f_limousin
00039  * Put an assert on "poids" into comments
00040  *
00041  * Revision 1.4  2002/10/16 14:37:15  j_novak
00042  * Reorganization of #include instructions of standard C++, in order to
00043  * use experimental version 3 of gcc.
00044  *
00045  * Revision 1.3  2002/09/06 14:49:25  j_novak
00046  * Added method lie_derive for Tenseur and Tenseur_sym.
00047  * Corrected various errors for derive_cov and arithmetic.
00048  *
00049  * Revision 1.2  2002/08/07 16:14:11  j_novak
00050  * class Tenseur can now also handle tensor densities, this should be transparent to older codes
00051  *
00052  * Revision 1.1.1.1  2001/11/20 15:19:30  e_gourgoulhon
00053  * LORENE
00054  *
00055  * Revision 2.3  2000/02/09  19:30:36  eric
00056  * MODIF IMPORTANTE: la triade de decomposition est desormais passee en
00057  * argument des constructeurs.
00058  *
00059  * Revision 2.2  2000/02/08  19:06:40  eric
00060  * Les fonctions arithmetiques ne sont plus amies.
00061  * Modif de diverses operations (notament division avec double)
00062  * Ajout de nouvelles operations (par ex. Tenseur + double, etc...)
00063  *
00064  * Revision 2.1  2000/01/11  11:15:00  eric
00065  * Gestion de la base vectorielle (triad).
00066  *
00067  * Revision 2.0  1999/12/02  17:18:52  phil
00068  * *** empty log message ***
00069  *
00070  *
00071  * $Header: /cvsroot/Lorene/C++/Source/Tenseur/tenseur_sym_arithm.C,v 1.5 2003/06/20 14:54:17 f_limousin Exp $
00072  *
00073  */
00074 
00075 // Headers C
00076 #include <stdlib.h>
00077 #include <assert.h>
00078 #include <math.h>
00079 
00080 // Headers Lorene
00081 #include "tenseur.h"
00082 
00083             //********************//
00084             // OPERATEURS UNAIRES //
00085             //********************//
00086 
00087 Tenseur_sym operator+(const Tenseur_sym & t) {
00088 
00089     return t ; 
00090 
00091 }
00092 
00093 
00094 Tenseur_sym operator-(const Tenseur_sym & t) {
00095     
00096    assert (t.get_etat() != ETATNONDEF) ;
00097     if (t.get_etat() == ETATZERO)
00098     return t ;
00099     else { 
00100     Tenseur_sym res(*(t.get_mp()), t.get_valence(), t.get_type_indice(), 
00101             *(t.get_triad()), t.get_metric(), t.get_poids() ) ; 
00102 
00103     res.set_etat_qcq();
00104     for (int i=0 ; i<res.get_n_comp() ; i++) {
00105         Itbl indices (res.donne_indices(i)) ;    
00106         res.set(indices) = -t(indices) ;
00107         }
00108     return res ;
00109     }
00110 }
00111         
00112 
00113             //**********//
00114             // ADDITION //
00115             //**********//
00116 
00117 Tenseur_sym operator+(const Tenseur_sym & t1, const Tenseur_sym & t2) {
00118     
00119     assert ((t1.get_etat() != ETATNONDEF) && (t2.get_etat() != ETATNONDEF)) ;
00120     assert (t1.get_valence() == t2.get_valence()) ;
00121     assert (t1.get_mp() == t2.get_mp()) ;
00122     if (t1.get_valence() != 0) {
00123     assert ( *(t1.get_triad()) == *(t2.get_triad()) ) ;
00124     }
00125     
00126     for (int i=0 ; i<t1.get_valence() ; i++)
00127     assert(t1.get_type_indice(i) == t2.get_type_indice(i)) ;
00128     assert (t1.get_metric() == t2.get_metric()) ;
00129     assert (fabs(t1.get_poids() - t2.get_poids())<1.e-10) ;
00130    
00131     if (t1.get_etat() == ETATZERO)
00132     return t2 ;
00133     else if (t2.get_etat() == ETATZERO)
00134         return t1 ;
00135      else {
00136         Tenseur_sym res(*(t1.get_mp()), t1.get_valence(), 
00137                 t1.get_type_indice(), *(t1.get_triad()), 
00138                 t1.get_metric(), t1.get_poids() ) ; 
00139 
00140         res.set_etat_qcq() ;
00141         for (int i=0 ; i<res.get_n_comp() ; i++) {
00142         Itbl indices (res.donne_indices(i)) ;
00143         res.set(indices) = t1(indices) + t2(indices) ;
00144         }
00145     return res ;
00146     }
00147 }
00148 
00149 
00150 
00151             //**************//
00152             // SOUSTRACTION //
00153             //**************//
00154 
00155 
00156 Tenseur_sym operator-(const Tenseur_sym & t1, const Tenseur_sym & t2) {
00157 
00158     return (t1 + (-t2)) ;
00159 
00160 }
00161 
00162 
00163             //****************//
00164             // MULTIPLICATION //
00165             //****************//
00166 
00167 Tenseur_sym operator*(double x, const Tenseur_sym& t) {
00168     
00169     assert (t.get_etat() != ETATNONDEF) ;
00170     if ( (t.get_etat() == ETATZERO) || (x == double(1)) )
00171     return t ;
00172     else {
00173     Tenseur_sym res(*(t.get_mp()), t.get_valence(), t.get_type_indice(), 
00174             *(t.get_triad()), t.get_metric(), t.get_poids() ) ; 
00175 
00176     if ( x == double(0) )
00177         res.set_etat_zero() ;
00178     else {
00179         res.set_etat_qcq() ;
00180         for (int i=0 ; i<res.get_n_comp() ; i++) {
00181         Itbl indices (res.donne_indices(i)) ;
00182         res.set(indices) = x*t(indices) ;
00183         }
00184         }
00185         return res ; 
00186     }
00187 }
00188 
00189 
00190 Tenseur_sym operator* (const Tenseur_sym& t, double x) {
00191     return x * t ;
00192 }
00193 
00194 Tenseur_sym operator*(int m, const Tenseur_sym& t) {
00195     return double(m) * t ; 
00196 }
00197 
00198 
00199 Tenseur_sym operator* (const Tenseur_sym& t, int m) {
00200     return double(m) * t ;
00201 }
00202 
00203 
00204 
00205             //**********//
00206             // DIVISION //
00207             //**********//
00208 
00209 Tenseur_sym operator/ (const Tenseur_sym& t1, const Tenseur& t2) {
00210     
00211     // Protections
00212     assert(t1.get_etat() != ETATNONDEF) ;
00213     assert(t2.get_etat() != ETATNONDEF) ;
00214     assert(t2.get_valence() == 0) ; // t2 doit etre un scalaire !
00215     assert(t1.get_mp() == t2.get_mp()) ;
00216 
00217     double poids_res = t1.get_poids() - t2.get_poids() ;
00218     poids_res = (fabs(poids_res) < 1.e-10 ? 0. : poids_res) ;
00219     const Metrique* met_res = 0x0 ;
00220     if (poids_res != 0.) {
00221       //     assert((t1.get_metric() != 0x0) || (t2.get_metric() != 0x0)) ;
00222       if (t1.get_metric() != 0x0) met_res = t1.get_metric() ;
00223       else met_res = t2.get_metric() ;
00224     }
00225     
00226     // Cas particuliers
00227     if (t2.get_etat() == ETATZERO) {
00228     cout << "Division by 0 in Tenseur_sym / Tenseur !" << endl ;
00229     abort() ; 
00230     }
00231     if (t1.get_etat() == ETATZERO) {
00232         Tenseur_sym resu(t1) ;
00233     resu.set_poids(poids_res) ;
00234     resu.set_metric(*met_res) ;
00235         return resu ;
00236     }
00237 
00238     // Cas general
00239     
00240     assert(t1.get_etat() == ETATQCQ) ;  // sinon...
00241     assert(t2.get_etat() == ETATQCQ) ;  // sinon...
00242 
00243     Tenseur_sym res(*(t1.get_mp()), t1.get_valence(), t1.get_type_indice(), 
00244             *(t1.get_triad()), met_res, poids_res ) ; 
00245 
00246     res.set_etat_qcq() ;
00247     for (int i=0 ; i<res.get_n_comp() ; i++) {
00248     Itbl indices (res.donne_indices(i)) ;
00249     res.set(indices) = t1(indices) / t2() ;     // Cmp / Cmp
00250     }
00251     return res ;
00252 
00253 }
00254 
00255 
00256 Tenseur_sym operator/ (const Tenseur_sym& t, double x) {
00257 
00258     assert (t.get_etat() != ETATNONDEF) ;
00259  
00260     if ( x == double(0) ) {
00261     cout << "Division by 0 in Tenseur_sym / double !" << endl ;
00262     abort() ;
00263     }
00264 
00265     if ( (t.get_etat() == ETATZERO) || (x == double(1)) )
00266     return t ;
00267     else {
00268     Tenseur_sym res(*(t.get_mp()), t.get_valence(), t.get_type_indice(), 
00269             *(t.get_triad()), t.get_metric(), t.get_poids() ) ; 
00270 
00271     res.set_etat_qcq() ;
00272     for (int i=0 ; i<res.get_n_comp() ; i++) {
00273         Itbl indices (res.donne_indices(i)) ;
00274         res.set(indices) = t(indices) / x ;     // Cmp / double
00275     }
00276     return res ; 
00277     }
00278 }
00279 
00280 
00281 
00282 Tenseur_sym operator/ (const Tenseur_sym& t, int m) {
00283 
00284     return t / double(m) ; 
00285 }
00286 
00287 

Generated on Tue Feb 7 01:35:21 2012 for LORENE by  doxygen 1.4.6