tenseur_arithm.C

00001 /*
00002  *  Arithmetics functions for the Tenseur class.
00003  *
00004  *  These functions are not member functions of the Tenseur 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 char tenseur_arithm_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tenseur/tenseur_arithm.C,v 1.7 2003/10/13 10:33:43 f_limousin Exp $" ;
00033 
00034 /*
00035  * $Id: tenseur_arithm.C,v 1.7 2003/10/13 10:33:43 f_limousin Exp $
00036  * $Log: tenseur_arithm.C,v $
00037  * Revision 1.7  2003/10/13 10:33:43  f_limousin
00038  * *** empty log message ***
00039  *
00040  * Revision 1.6  2003/06/20 14:52:21  f_limousin
00041  * Put an assert on "poids" into comments
00042  *
00043  * Revision 1.5  2003/03/03 19:40:52  f_limousin
00044  * Suppression of an  assert on a metric associated with a tensor.
00045  *
00046  * Revision 1.4  2002/10/16 14:37:14  j_novak
00047  * Reorganization of #include instructions of standard C++, in order to
00048  * use experimental version 3 of gcc.
00049  *
00050  * Revision 1.3  2002/09/06 14:49:25  j_novak
00051  * Added method lie_derive for Tenseur and Tenseur_sym.
00052  * Corrected various errors for derive_cov and arithmetic.
00053  *
00054  * Revision 1.2  2002/08/07 16:14:11  j_novak
00055  * class Tenseur can now also handle tensor densities, this should be transparent to older codes
00056  *
00057  * Revision 1.1.1.1  2001/11/20 15:19:30  e_gourgoulhon
00058  * LORENE
00059  *
00060  * Revision 2.5  2000/02/09  19:30:22  eric
00061  * MODIF IMPORTANTE: la triade de decomposition est desormais passee en
00062  * argument des constructeurs.
00063  *
00064  * Revision 2.4  2000/02/08  19:04:58  eric
00065  * Les fonctions arithmetiques ne sont plus amies.
00066  * Les fonctions exp, log et sqrt se trouvent desormais dans le fichier
00067  *   tenseur_math.C
00068  * Modif de diverses operations (notament division avec double)
00069  * Ajout de nouvelles operations (par ex. Tenseur + double, etc...)
00070  *
00071  * Revision 2.3  2000/02/01  15:40:29  eric
00072  * Ajout de la fonction sqrt
00073  *
00074  * Revision 2.2  2000/01/11  11:14:15  eric
00075  * Changement de nom pour la base vectorielle : base --> triad
00076  *
00077  * Revision 2.1  2000/01/10  17:25:34  eric
00078  * Gestion des bases vectorielles (triades de decomposition).
00079  *
00080  * Revision 2.0  1999/12/02  17:18:47  phil
00081  * *** empty log message ***
00082  *
00083  *
00084  * $Header: /cvsroot/Lorene/C++/Source/Tenseur/tenseur_arithm.C,v 1.7 2003/10/13 10:33:43 f_limousin Exp $
00085  *
00086  */
00087 
00088 // Headers C
00089 #include <stdlib.h>
00090 #include <assert.h>
00091 #include <math.h>
00092 
00093 // Headers Lorene
00094 #include "tenseur.h"
00095 
00096             //********************//
00097             // OPERATEURS UNAIRES //
00098             //********************//
00099 
00100 Tenseur operator+(const Tenseur & t) {
00101 
00102     return t ; 
00103 
00104 }
00105 
00106 Tenseur operator-(const Tenseur & t) {
00107     
00108     assert (t.get_etat() != ETATNONDEF) ;
00109     if (t.get_etat() == ETATZERO)
00110     return t ;
00111     else { 
00112     Tenseur res(*(t.get_mp()), t.get_valence(), t.get_type_indice(), 
00113             t.get_triad(), t.get_metric(), t.get_poids()) ;
00114 
00115 
00116     res.set_etat_qcq();
00117 
00118     for (int i=0 ; i<res.get_n_comp() ; i++) {
00119         Itbl indices (res.donne_indices(i)) ;    
00120         res.set(indices) = -t(indices) ;
00121         }
00122     return res ;
00123     }
00124 }
00125 
00126             //**********//
00127             // ADDITION //
00128             //**********//
00129 
00130 Tenseur operator+(const Tenseur & t1, const Tenseur & t2) {
00131     
00132     assert ((t1.get_etat() != ETATNONDEF) && (t2.get_etat() != ETATNONDEF)) ;
00133     assert (t1.get_valence() == t2.get_valence()) ;
00134     assert (t1.get_mp() == t2.get_mp()) ;
00135     if (t1.get_valence() != 0) {
00136     assert ( *(t1.get_triad()) == *(t2.get_triad()) ) ;
00137     }
00138     
00139     for (int i=0 ; i<t1.get_valence() ; i++)
00140     assert(t1.get_type_indice(i) == t2.get_type_indice(i)) ;
00141     //    assert (t1.get_metric() == t2.get_metric()) ;
00142     //assert (fabs(t1.get_poids() - t2.get_poids())<1.e-10) ;
00143 
00144     if (t1.get_etat() == ETATZERO)
00145     return t2 ;
00146     else if (t2.get_etat() == ETATZERO)
00147         return t1 ;
00148      else {
00149         Tenseur res(*(t1.get_mp()), t1.get_valence(), t1.get_type_indice(), 
00150             t1.get_triad(), t1.get_metric(), t1.get_poids() ) ;
00151 
00152         res.set_etat_qcq() ;
00153         for (int i=0 ; i<res.get_n_comp() ; i++) {
00154         Itbl indices (res.donne_indices(i)) ;
00155         res.set(indices) = t1(indices) + t2(indices) ;
00156         }
00157     return res ;
00158     }
00159 }
00160 
00161 
00162 Tenseur operator+(const Tenseur & t1, double x) {
00163     
00164     assert (t1.get_etat() != ETATNONDEF) ;
00165     assert (t1.get_valence() == 0) ;
00166     
00167     if (x == double(0)) {
00168     return t1 ;
00169     }
00170     
00171     Tenseur res( *(t1.get_mp()), t1.get_metric(), t1.get_poids() ) ;
00172 
00173     res.set_etat_qcq() ;
00174 
00175     res.set() = t1() + x ;  // Cmp + double
00176 
00177     return res ;
00178 
00179 }
00180 
00181 
00182 Tenseur operator+(double x, const Tenseur & t2) {
00183     
00184     return t2 + x ; 
00185     
00186 }
00187 
00188 Tenseur operator+(const Tenseur & t1, int m) {
00189     
00190     return t1 + double(m) ;
00191 
00192 }
00193 
00194 
00195 Tenseur operator+(int m, const Tenseur & t2) {
00196     
00197     return t2 + double(m) ; 
00198     
00199 }
00200 
00201 
00202 
00203             //**************//
00204             // SOUSTRACTION //
00205             //**************//
00206 
00207 Tenseur operator-(const Tenseur & t1, const Tenseur & t2) {
00208 
00209     return (t1 + (-t2)) ;
00210 
00211 }
00212 
00213 
00214 Tenseur operator-(const Tenseur & t1, double x) {
00215 
00216     assert (t1.get_etat() != ETATNONDEF) ;
00217     assert (t1.get_valence() == 0) ;
00218     
00219     if (x == double(0)) {
00220     return t1 ;
00221     }
00222     
00223     Tenseur res( *(t1.get_mp()), t1.get_metric(), t1.get_poids() ) ;
00224 
00225     res.set_etat_qcq() ;
00226 
00227     res.set() = t1() - x ;  // Cmp - double
00228 
00229     return res ;
00230 
00231 }
00232 
00233 
00234 Tenseur operator-(double x, const Tenseur & t2) {
00235     
00236     return - (t2 - x) ; 
00237     
00238 }
00239 
00240 
00241 Tenseur operator-(const Tenseur & t1, int m) {
00242 
00243     return t1 - double(m) ; 
00244     
00245 }
00246 
00247 
00248 Tenseur operator-(int m, const Tenseur & t2) {
00249 
00250     return - (t2 - double(m)) ;     
00251 
00252 }
00253 
00254 
00255 
00256             //****************//
00257             // MULTIPLICATION //
00258             //****************//
00259 
00260 
00261 
00262 Tenseur operator*(double x, const Tenseur& t) {
00263     
00264     assert (t.get_etat() != ETATNONDEF) ;
00265     if ( (t.get_etat() == ETATZERO) || (x == double(1)) )
00266     return t ;
00267     else {
00268     Tenseur res(*(t.get_mp()), t.get_valence(), t.get_type_indice(), 
00269             t.get_triad(), t.get_metric(), t.get_poids() ) ;
00270 
00271     if ( x == double(0) )
00272         res.set_etat_zero() ;
00273     else {
00274         res.set_etat_qcq() ;
00275         for (int i=0 ; i<res.get_n_comp() ; i++) {
00276         Itbl indices (res.donne_indices(i)) ;
00277         res.set(indices) = x*t(indices) ;
00278         }
00279         }
00280         return res ; 
00281     }
00282 }
00283 
00284 
00285 Tenseur operator* (const Tenseur& t, double x) {
00286     return x * t ;
00287 }
00288 
00289 Tenseur operator*(int m, const Tenseur& t) {
00290     return double(m) * t ; 
00291 }
00292 
00293 
00294 Tenseur operator* (const Tenseur& t, int m) {
00295     return double(m) * t ;
00296 }
00297 
00298 
00299             //**********//
00300             // DIVISION //
00301             //**********//
00302 
00303 Tenseur operator/ (const Tenseur& t1, const Tenseur& t2) {
00304     
00305     // Protections
00306     assert(t1.get_etat() != ETATNONDEF) ;
00307     assert(t2.get_etat() != ETATNONDEF) ;
00308     assert(t2.get_valence() == 0) ; // t2 doit etre un scalaire !
00309     assert(t1.get_mp() == t2.get_mp()) ;
00310 
00311     double poids_res = t1.get_poids() - t2.get_poids() ;
00312     poids_res = (fabs(poids_res) < 1.e-10 ? 0. : poids_res) ;
00313     const Metrique* met_res = 0x0 ;
00314     if (poids_res != 0.) {
00315       //    assert((t1.get_metric() != 0x0) || (t2.get_metric() != 0x0)) ;
00316       if (t1.get_metric() != 0x0) met_res = t1.get_metric() ;
00317       else met_res = t2.get_metric() ;
00318     }
00319     // Cas particuliers
00320     if (t2.get_etat() == ETATZERO) {
00321     cout << "Division by 0 in Tenseur / Tenseur !" << endl ;
00322     abort() ; 
00323     }
00324     if (t1.get_etat() == ETATZERO) {
00325         Tenseur resu(t1) ;
00326     resu.set_poids(poids_res) ;
00327     resu.set_metric(*met_res) ;
00328         return resu ;
00329     }
00330 
00331     // Cas general
00332     
00333     assert(t1.get_etat() == ETATQCQ) ;  // sinon...
00334     assert(t2.get_etat() == ETATQCQ) ;  // sinon...
00335 
00336     Tenseur res(*(t1.get_mp()), t1.get_valence(), t1.get_type_indice(), 
00337         t1.get_triad(), met_res, poids_res) ;
00338 
00339     res.set_etat_qcq() ;
00340     for (int i=0 ; i<res.get_n_comp() ; i++) {
00341     Itbl indices (res.donne_indices(i)) ;
00342     res.set(indices) = t1(indices) / t2() ;     // Cmp / Cmp
00343     }
00344     return res ;
00345 
00346 }
00347 
00348 
00349 Tenseur operator/ (const Tenseur& t, double x) {
00350 
00351     assert (t.get_etat() != ETATNONDEF) ;
00352  
00353     if ( x == double(0) ) {
00354     cout << "Division by 0 in Tenseur / double !" << endl ;
00355     abort() ;
00356     }
00357 
00358     if ( (t.get_etat() == ETATZERO) || (x == double(1)) )
00359     return t ;
00360     else {
00361     Tenseur res(*(t.get_mp()), t.get_valence(), t.get_type_indice(), 
00362             t.get_triad(), t.get_metric(), t.get_poids()) ;
00363 
00364     res.set_etat_qcq() ;
00365     for (int i=0 ; i<res.get_n_comp() ; i++) {
00366         Itbl indices (res.donne_indices(i)) ;
00367         res.set(indices) = t(indices) / x ;     // Cmp / double
00368     }
00369     return res ; 
00370     }
00371 
00372 }
00373 
00374 
00375 
00376 
00377 Tenseur operator/ (double x, const Tenseur& t) {
00378     
00379     if (t.get_etat() == ETATZERO) {
00380     cout << "Division by 0 in double / Tenseur !" << endl ;
00381     abort() ; 
00382     }
00383     
00384     assert (t.get_etat() == ETATQCQ) ;
00385     assert(t.get_valence() == 0) ;  // Utilisable que sur scalaire !
00386     
00387     Tenseur res( *(t.get_mp()), t.get_metric(), -t.get_poids() ) ;
00388     res.set_etat_qcq() ;
00389     res.set() = x / t() ;   // double / Cmp
00390     return res ;
00391 }
00392 
00393 
00394 Tenseur operator/ (const Tenseur& t, int m) {
00395 
00396     return t / double(m) ; 
00397 }
00398 
00399 
00400 Tenseur operator/ (int m, const Tenseur& t) {
00401     
00402     return double(m) / t ; 
00403 }
00404 
00405 
00406 
00407 
00408 

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