valeur_arithm.C

00001 /*
00002  *  Arithmetical operations for class Valeur
00003  *
00004  */
00005 
00006 /*
00007  *   Copyright (c) 1999-2000 Jean-Alain Marck
00008  *   Copyright (c) 1999-2005 Eric Gourgoulhon
00009  *   Copyright (c) 1999-2001 Philippe Grandclement
00010  *   Copyright (c) 2004 Jerome Novak
00011  *
00012  *   This file is part of LORENE.
00013  *
00014  *   LORENE is free software; you can redistribute it and/or modify
00015  *   it under the terms of the GNU General Public License as published by
00016  *   the Free Software Foundation; either version 2 of the License, or
00017  *   (at your option) any later version.
00018  *
00019  *   LORENE is distributed in the hope that it will be useful,
00020  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
00021  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00022  *   GNU General Public License for more details.
00023  *
00024  *   You should have received a copy of the GNU General Public License
00025  *   along with LORENE; if not, write to the Free Software
00026  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00027  *
00028  */
00029 
00030 
00031 char valeur_arithm_C[] = "$Header: /cvsroot/Lorene/C++/Source/Valeur/valeur_arithm.C,v 1.5 2008/08/27 08:52:55 jl_cornou Exp $" ;
00032 
00033 /*
00034  * $Id: valeur_arithm.C,v 1.5 2008/08/27 08:52:55 jl_cornou Exp $
00035  * $Log: valeur_arithm.C,v $
00036  * Revision 1.5  2008/08/27 08:52:55  jl_cornou
00037  * Added Jacobi(0,2) polynomials case
00038  *
00039  * Revision 1.4  2005/11/17 15:19:23  e_gourgoulhon
00040  * Added Valeur + Mtbl and Valeur - Mtbl.
00041  *
00042  * Revision 1.3  2004/07/06 13:36:30  j_novak
00043  * Added methods for desaliased product (operator |) only in r direction.
00044  *
00045  * Revision 1.2  2002/10/16 14:37:15  j_novak
00046  * Reorganization of #include instructions of standard C++, in order to
00047  * use experimental version 3 of gcc.
00048  *
00049  * Revision 1.1.1.1  2001/11/20 15:19:27  e_gourgoulhon
00050  * LORENE
00051  *
00052  * Revision 2.20  2001/08/31  15:23:48  eri * operator% : traitement du cas ou le Tbl est zero dans une zone.
00053  *
00054  * Revision 2.19  2001/05/28  12:42:27  eric
00055  * Passage en ylm pour le desaliasing dans operator%.
00056  *
00057  * Revision 2.18  2001/05/26  14:50:21  eric
00058  * Ajout de l'operator% : produit de deux Valeur avec desaliasage.
00059  *
00060  * Revision 2.17  2000/01/14  14:42:47  eric
00061  * Valeur * double : operation effectue dans l'espace des coefficients si
00062  *                   la Valeur n'est pas a jour ds l'espace des config.
00063  * Valeur / double : idem.
00064  * += Valeur : idem.
00065  * -= Valeur : idem.
00066  *
00067  * Pour += Valeur et -= Valeur les schemas sont desormais calques sur
00068  * Valeur + Valeur et Valeur - Valeur.
00069  *
00070  * Revision 2.16  1999/12/10  16:33:36  eric
00071  * Dans l'arithmetique membre (+=, -=, *=), on n'appelle desormais
00072  *  del_deriv() que tout a la fin.
00073  *
00074  * Revision 2.15  1999/11/30  14:12:54  phil
00075  * gestion de base dans operator/ (double,Vlaeur)
00076  *
00077  * Revision 2.14  1999/11/30  12:42:10  eric
00078  * Le membre base est desormais un objet de type Base_val et non plus
00079  *  un pointeur vers une Base_val.
00080  *
00081  * Revision 2.13  1999/11/29  13:28:06  eric
00082  * *** empty log message ***
00083  *
00084  * Revision 2.12  1999/11/29  10:20:50  eric
00085  * Ajout de Valeur/Mtbl et Mtbl / Valeur.
00086  *
00087  * Revision 2.11  1999/11/29  10:06:05  eric
00088  * Ajout de Valeur*Mtbl et Mtbl*Valeur
00089  *
00090  * Revision 2.10  1999/10/26  14:40:29  phil
00091  * On gere les bases pour *, *=, /= et /
00092  *
00093  * Revision 2.9  1999/10/20  15:31:28  eric
00094  * Ajout de la plupart des fonctions arithmetiques.
00095  *
00096  * Revision 2.8  1999/10/18  15:07:47  eric
00097  * La fonction membre annule() est rebaptisee annule_hard().
00098  *
00099  * Revision 2.7  1999/10/13  15:50:56  eric
00100  * Depoussierage.
00101  *
00102  * Revision 2.6  1999/09/15  10:02:26  phil
00103  * gestion de la base dans Valeur operator (double, const Valeur &)
00104  *
00105  * Revision 2.5  1999/09/14  17:18:36  phil
00106  * aout de Valeur operator* (double, const Valeur&)
00107  *
00108  * Revision 2.4  1999/09/13  14:52:55  phil
00109  * *** empty log message ***
00110  *
00111  * Revision 2.3  1999/04/09  12:38:05  phil
00112  * *** empty log message ***
00113  *
00114  * Revision 2.2  1999/04/09  12:26:59  phil
00115  * Ajout de valeur * coord
00116  *
00117  * Revision 2.1  1999/02/22  15:49:28  hyc
00118  * *** empty log message ***
00119  *
00120  *
00121  * $Header: /cvsroot/Lorene/C++/Source/Valeur/valeur_arithm.C,v 1.5 2008/08/27 08:52:55 jl_cornou Exp $
00122  *
00123  */
00124 
00125 // Fichiers include
00126 // ----------------
00127 #include <math.h>
00128 #include <assert.h>
00129 #include <stdlib.h>
00130 
00131 #include "mtbl.h"
00132 #include "valeur.h"
00133 #include "coord.h"
00134             //********************//
00135             // OPERATEURS UNAIRES //
00136             //********************//
00137 
00138 Valeur operator+(const Valeur & vi) {
00139     
00140     // Protection
00141     assert(vi.get_etat() != ETATNONDEF) ;
00142     
00143     return vi ;
00144 }
00145 
00146 Valeur operator-(const Valeur & vi) {
00147     
00148     // Protection
00149     assert(vi.get_etat() != ETATNONDEF) ;
00150     
00151     // Cas particulier
00152     if (vi.get_etat() == ETATZERO) {
00153     return vi ;
00154     }
00155     
00156     // Cas general
00157     assert(vi.get_etat() == ETATQCQ) ;  // sinon...
00158 
00159     Valeur resu(vi.get_mg()) ;  // Valeur resultat
00160 
00161     if (vi.c != 0x0) {
00162     resu = - *(vi.c) ; 
00163     resu.base = vi.base ;  // N'oublions pas la base...
00164     }
00165     else{
00166     assert(vi.c_cf != 0x0) ;
00167     resu = - *(vi.c_cf) ;  // Dans ce cas la base est prise en 
00168                        // charge par l'operator=(const Mtbl_cf&).
00169     }    
00170     
00171     // Termine
00172     return resu ;
00173 }
00174 
00175             //**********//
00176             // ADDITION //
00177             //**********//
00178 
00179 // Valeur + Valeur
00180 // ---------------
00181 Valeur operator+(const Valeur& t1, const Valeur& t2)       
00182 {
00183     // Protections
00184     assert(t1.get_etat() != ETATNONDEF) ;
00185     assert(t2.get_etat() != ETATNONDEF) ;
00186     assert(t1.get_mg() == t2.get_mg()) ;
00187     
00188     // Cas particuliers
00189     if (t1.get_etat() == ETATZERO) {
00190         return t2 ;
00191     }
00192     if (t2.get_etat() == ETATZERO) {
00193         return t1 ;
00194     }
00195     assert(t1.get_etat() == ETATQCQ) ;  // sinon...
00196     assert(t2.get_etat() == ETATQCQ) ;  // sinon...
00197 
00198     Valeur resu(t1.get_mg()) ; 
00199     
00200     // On privelegie l'addition dans l'espace des configurations: 
00201     // ----------------------------------------------------------
00202     if (t1.c != 0x0) {
00203     if (t2.c != 0x0) {
00204         resu = *(t1.c) + *(t2.c) ;      // Addition des Mtbl
00205         resu.base = t1.base ;  
00206     }
00207     else {
00208         assert(t2.c_cf != 0x0) ;
00209         if (t1.c_cf != 0x0) {
00210         resu = *(t1.c_cf) + *(t2.c_cf) ;    // Addition des Mtbl_cf
00211         }
00212         else {
00213         t2.coef_i() ; 
00214         resu = *(t1.c) + *(t2.c) ;      // Addition des Mtbl
00215         resu.base = t1.base ;  
00216         }
00217     }
00218     }
00219     else{   // Cas ou t1.c n'est pas a jour
00220     assert(t1.c_cf != 0x0) ;
00221     if (t2.c_cf != 0x0) {
00222         resu = *(t1.c_cf) + *(t2.c_cf) ;    // Addition des Mtbl_cf
00223     }
00224     else {
00225         assert(t2.c != 0x0) ; 
00226         t1.coef_i() ; 
00227         resu = *(t1.c) + *(t2.c) ;      // Addition des Mtbl
00228         resu.base = t1.base ;  
00229     }       
00230     }
00231 
00232     return resu ;
00233 }
00234 
00235 // Valeur + Mtbl
00236 // -------------
00237 Valeur operator+(const Valeur& t1, const Mtbl& mi)     
00238 {
00239     // Protections
00240     assert(t1.get_etat() != ETATNONDEF) ;
00241     assert(mi.get_etat() != ETATNONDEF) ;
00242     
00243     // Cas particuliers
00244     if (mi.get_etat() == ETATZERO) {
00245     return t1 ;
00246     }
00247 
00248     Valeur resu(t1) ;
00249     
00250     if (t1.get_etat() == ETATZERO) {
00251     resu.set_etat_c_qcq() ;
00252     *(resu.c) = mi ; 
00253     }
00254     else{ 
00255     assert(resu.get_etat() == ETATQCQ) ; // sinon ...
00256     resu.coef_i() ; // l'addition se fait dans l'espace des configurations
00257     resu.set_etat_c_qcq() ;
00258     *(resu.c) += mi ;
00259     }
00260         
00261     return resu ;
00262 }
00263 
00264 // Mtbl + Valeur 
00265 // -------------
00266 Valeur operator+(const Mtbl& mi, const Valeur& t1) {
00267     return t1 + mi ; 
00268 }
00269 
00270 
00271 // Valeur + double
00272 // ---------------
00273 Valeur operator+(const Valeur& t1, double x)       
00274 {
00275     // Protections
00276     assert(t1.get_etat() != ETATNONDEF) ;
00277     
00278     // Cas particuliers
00279     if (x == double(0)) {
00280     return t1 ;
00281     }
00282 
00283     Valeur resu(t1) ;
00284     
00285     if (t1.get_etat() == ETATZERO) {
00286     resu.set_etat_c_qcq() ;
00287     *(resu.c) = x ; 
00288     }
00289     else{ 
00290     assert(resu.get_etat() == ETATQCQ) ; // sinon ...
00291     resu.coef_i() ; // l'addition se fait dans l'espace des configurations
00292     resu.set_etat_c_qcq() ;
00293     *(resu.c) = *(resu.c) + x ;
00294     }
00295         
00296     return resu ;
00297 }
00298 
00299 // double + Valeur
00300 // ---------------
00301 Valeur operator+(double x, const Valeur& t1)        // double + Valeur
00302 {
00303     return t1 + x ;
00304 }
00305 
00306 // Valeur + int
00307 // ------------
00308 Valeur operator+(const Valeur& t1, int m)       // Valeur + int
00309 {
00310     return t1 + double(m) ;
00311 }
00312 
00313 // int + Valeur
00314 // -------------
00315 Valeur operator+(int m, const Valeur& t1)       // int + Valeur
00316 {
00317     return t1 + double(m) ;
00318 }
00319 
00320 
00321 
00322             //**************//
00323             // SOUSTRACTION //
00324             //**************//
00325 
00326 // Valeur - Valeur
00327 // ---------------
00328 Valeur operator-(const Valeur& t1, const Valeur& t2)       
00329 {
00330     // Protections
00331     assert(t1.get_etat() != ETATNONDEF) ;
00332     assert(t2.get_etat() != ETATNONDEF) ;
00333     assert(t1.get_mg() == t2.get_mg()) ;
00334     
00335     // Cas particuliers
00336     if (t1.get_etat() == ETATZERO) {
00337         return - t2 ;
00338     }
00339     if (t2.get_etat() == ETATZERO) {
00340         return t1 ;
00341     }
00342     assert(t1.get_etat() == ETATQCQ) ;  // sinon...
00343     assert(t2.get_etat() == ETATQCQ) ;  // sinon...
00344 
00345     Valeur resu(t1.get_mg()) ; 
00346     
00347     // On privelegie la soustraction dans l'espace des configurations: 
00348     // ---------------------------------------------------------------
00349     if (t1.c != 0x0) {
00350     if (t2.c != 0x0) {
00351         resu = *(t1.c) - *(t2.c) ;      // Soustraction des Mtbl
00352         resu.base = t1.base ;  
00353     }
00354     else {
00355         assert(t2.c_cf != 0x0) ;
00356         if (t1.c_cf != 0x0) {
00357         resu = *(t1.c_cf) - *(t2.c_cf) ;    // Soustraction des Mtbl_cf
00358         }
00359         else {
00360         t2.coef_i() ; 
00361         resu = *(t1.c) - *(t2.c) ;      // Soustraction des Mtbl
00362         resu.base = t1.base ;  
00363         }
00364     }
00365     }
00366     else{   // Cas ou t1.c n'est pas a jour
00367     assert(t1.c_cf != 0x0) ;
00368     if (t2.c_cf != 0x0) {
00369         resu = *(t1.c_cf) - *(t2.c_cf) ;    // Soustraction des Mtbl_cf
00370     }
00371     else {
00372         assert(t2.c != 0x0) ; 
00373         t1.coef_i() ; 
00374         resu = *(t1.c) - *(t2.c) ;      // Soustraction des Mtbl
00375         resu.base = t1.base ;  
00376     }       
00377     }
00378 
00379     return resu ;
00380 }
00381 
00382 
00383 // Valeur - Mtbl
00384 // -------------
00385 Valeur operator-(const Valeur& t1, const Mtbl& mi)     
00386 {
00387     // Protections
00388     assert(t1.get_etat() != ETATNONDEF) ;
00389     assert(mi.get_etat() != ETATNONDEF) ;
00390     
00391     // Cas particuliers
00392     if (mi.get_etat() == ETATZERO) {
00393     return t1 ;
00394     }
00395 
00396     Valeur resu(t1) ;
00397     
00398     if (t1.get_etat() == ETATZERO) {
00399     resu.set_etat_c_qcq() ;
00400     *(resu.c) = - mi ; 
00401     }
00402     else{ 
00403     assert(resu.get_etat() == ETATQCQ) ; // sinon ...
00404     resu.coef_i() ; // substraction in configuration space
00405     resu.set_etat_c_qcq() ;
00406     *(resu.c) -= mi ;
00407     }
00408         
00409     return resu ;
00410 }
00411 
00412 // Mtbl - Valeur
00413 // -------------
00414 Valeur operator-(const Mtbl& mi, const Valeur& t1) {
00415     return - (t1 - mi) ; 
00416 }
00417 
00418 // Valeur - double
00419 // ---------------
00420 Valeur operator-(const Valeur& t1, double x)       
00421 {
00422     // Protections
00423     assert(t1.get_etat() != ETATNONDEF) ;
00424     
00425     // Cas particuliers
00426     if (x == double(0)) {
00427     return t1 ;
00428     }
00429 
00430     Valeur resu(t1) ;
00431     
00432     if (t1.get_etat() == ETATZERO) {
00433     resu.set_etat_c_qcq() ;
00434     *(resu.c) = - x ; 
00435     }
00436     else{ 
00437     assert(resu.get_etat() == ETATQCQ) ; // sinon ...
00438     resu.coef_i() ; // l'addition se fait dans l'espace des configurations
00439     resu.set_etat_c_qcq() ;
00440     *(resu.c) = *(resu.c) - x ;
00441     }
00442         
00443     return resu ;
00444 }
00445 
00446 // double - Valeur
00447 // ---------------
00448 Valeur operator-(double x, const Valeur& t1)        // double - Valeur
00449 {
00450     return - (t1 - x) ;
00451 }
00452 
00453 // Valeur - int
00454 // ------------
00455 Valeur operator-(const Valeur& t1, int m)       // Valeur - int
00456 {
00457     return t1 - double(m) ;
00458 }
00459 
00460 // int - Valeur
00461 // -------------
00462 Valeur operator-(int m, const Valeur& t1)       // int - Valeur
00463 {
00464     return double(m) - t1 ;
00465 }
00466 
00467 
00468 
00469 
00470 
00471             //****************//
00472             // MULTIPLICATION //
00473             //****************//
00474             
00475 // Valeur * Valeur
00476 // ---------------
00477 Valeur operator*(const Valeur& t1, const Valeur& t2)       
00478 {
00479     // Protections
00480     assert(t1.get_etat() != ETATNONDEF) ;
00481     assert(t2.get_etat() != ETATNONDEF) ;
00482     assert(t1.get_mg() == t2.get_mg()) ;
00483     
00484     // Cas particuliers
00485     if (t1.get_etat() == ETATZERO) {
00486         return t1 ;
00487     }
00488     if (t2.get_etat() == ETATZERO) {
00489         return t2 ;
00490     }
00491     assert(t1.get_etat() == ETATQCQ) ;  // sinon...
00492     assert(t2.get_etat() == ETATQCQ) ;  // sinon...
00493 
00494     Valeur resu(t1.get_mg()) ; 
00495 
00496     // La multiplication est faite dans l'espace des configurations:    
00497     if (t1.c == 0x0) {
00498     t1.coef_i() ; 
00499     }
00500     if (t2.c == 0x0) {
00501     t2.coef_i() ; 
00502     }
00503     
00504     resu = (*(t1.c)) * (*(t2.c)) ;  // Multiplication des Mtbl 
00505     
00506     // affectation de la base :
00507     resu.base = t1.base * t2.base;
00508     
00509     return resu ;
00510 }
00511 
00512 
00513 // Valeur * double
00514 // ---------------
00515 Valeur operator*(const Valeur& c1, double a) {
00516     
00517     // Protection
00518     assert(c1.get_etat() != ETATNONDEF) ;
00519     
00520     // Cas particulier
00521     if ((c1.get_etat() == ETATZERO) || ( a == double(1) )) {
00522     return c1 ;
00523     }
00524 
00525     // Cas general
00526     assert(c1.get_etat() == ETATQCQ) ;  // sinon...
00527 
00528     Valeur result(c1.get_mg()) ;
00529 
00530     if (c1.c != 0x0) {
00531     result = *(c1.c) * a ;     // Mtbl * double
00532     result.base = c1.base ;    // in this case, result.base must be set
00533                    // by hand
00534     }
00535     else {
00536     assert(c1.c_cf != 0x0) ; 
00537     result = *(c1.c_cf) * a ;   // Mtbl_cf * double
00538     }
00539 
00540     return result ;
00541 }
00542 
00543 // double * Valeur
00544 // ---------------
00545 Valeur operator*(double x, const Valeur& t1)        // double * Valeur
00546 {
00547     return t1 * x ;
00548 }
00549 
00550 // Valeur * int
00551 // ------------
00552 Valeur operator*(const Valeur& t1, int m)       // Valeur * int
00553 {
00554     return t1 * double(m) ;
00555 }
00556 
00557 // int * Valeur
00558 // ------------
00559 Valeur operator*(int m, const Valeur& t1)       // int * Valeur
00560 {
00561     return t1 * double(m) ;
00562 }
00563 
00564 
00565 // Valeur * Mtbl
00566 // --------------
00567 Valeur operator*(const Valeur & c1, const Mtbl& c2) {
00568     
00569     // Protection
00570     assert(c1.get_etat() != ETATNONDEF) ;
00571 
00572     // Cas particulier
00573     if (c1.get_etat() == ETATZERO) {
00574     return c1 ;
00575     }
00576 
00577     // Cas general
00578 
00579     assert(c1.get_etat() == ETATQCQ) ;
00580 
00581     Valeur result(c1.get_mg()) ;
00582 
00583     // La multiplication  est faite dans l'espace des configurations:    
00584     if (c1.c == 0x0) {
00585     c1.coef_i() ; 
00586     }
00587     result = *(c1.c) * c2 ; // Mtbl * Mtbl 
00588 
00589     return result ;
00590 }
00591 
00592 // Mtbl * Valeur
00593 // --------------
00594 Valeur operator*(const Mtbl& c1, const Valeur& t1) {
00595     
00596     return t1 * c1 ; 
00597     
00598 }
00599 
00600 
00601 // Valeur * Coord
00602 // --------------
00603 Valeur operator*(const Valeur & c1, const Coord& c2) {
00604     
00605     // Protection
00606     assert(c1.get_etat() != ETATNONDEF) ;
00607 
00608     // Cas particulier
00609     if (c1.get_etat() == ETATZERO) {
00610     return c1 ;
00611     }
00612 
00613     // Cas general
00614 
00615     assert(c1.get_etat() == ETATQCQ) ;
00616 
00617     Valeur result(c1.get_mg()) ;
00618 
00619     // La multiplication  est faite dans l'espace des configurations:    
00620     if (c1.c == 0x0) {
00621     c1.coef_i() ; 
00622     }
00623     result = *(c1.c) * c2 ; // Mtbl * Coord
00624 
00625     return result ;
00626 }
00627 
00628 // Coord * Valeur
00629 // --------------
00630 Valeur operator*(const Coord& c1, const Valeur& t1) {
00631     
00632     return t1 * c1 ; 
00633     
00634 }
00635 
00636             //**********//
00637             // DIVISION //
00638             //**********//
00639 
00640 // Valeur / Valeur
00641 // ---------------
00642 Valeur operator/(const Valeur& t1, const Valeur& t2)       
00643 {
00644     // Protections
00645     assert(t1.get_etat() != ETATNONDEF) ;
00646     assert(t2.get_etat() != ETATNONDEF) ;
00647     assert(t1.get_mg() == t2.get_mg()) ;
00648     
00649     // Cas particuliers
00650     if (t2.get_etat() == ETATZERO) {
00651     cout << "Division by 0 in Valeur / Valeur !" << endl ;
00652     abort() ; 
00653     }
00654     if (t1.get_etat() == ETATZERO) {
00655         return t1 ;
00656     }
00657 
00658     assert(t1.get_etat() == ETATQCQ) ;  // sinon...
00659     assert(t2.get_etat() == ETATQCQ) ;  // sinon...
00660 
00661     Valeur resu(t1.get_mg()) ; 
00662 
00663     // La division est faite dans l'espace des configurations:    
00664     if (t1.c == 0x0) {
00665     t1.coef_i() ; 
00666     }
00667     if (t2.c == 0x0) {
00668     t2.coef_i() ; 
00669     }
00670     
00671     resu = (*(t1.c)) / (*(t2.c)) ;  // Division des Mtbl 
00672     
00673     // affectation de la base :
00674     resu.base = t1.base * t2.base;
00675     
00676     return resu ;
00677 }
00678 
00679 // Valeur / double 
00680 // ---------------
00681 Valeur operator/(const Valeur& t1, double x)       
00682 {
00683     // Protections
00684     assert(t1.get_etat() != ETATNONDEF) ;
00685     
00686     // Cas particuliers
00687     if ( x == double(0) ) {
00688     cout << "Division by 0 in Valeur / double !" << endl ;
00689     abort() ;
00690     }
00691     if ((t1.get_etat() == ETATZERO) || ( x == double(1) )) {
00692     return t1 ;
00693     }
00694 
00695     assert(t1.get_etat() == ETATQCQ) ;  // sinon...
00696 
00697     Valeur resu(t1.get_mg()) ; 
00698 
00699     if (t1.c != 0x0) {
00700     resu = *(t1.c) / x ;     // Mtbl / double
00701     resu.base = t1.base ;    // in this case, resu.base must be set by hand
00702     }
00703     else {
00704     assert(t1.c_cf != 0x0) ; 
00705     resu = *(t1.c_cf) / x ;   // Mtbl_cf * double
00706     }
00707     
00708     return resu ;
00709 }
00710 
00711 // double / Valeur
00712 // ---------------
00713 Valeur operator/(double x, const Valeur & c2) {
00714     
00715     // Protection
00716     assert(c2.get_etat() != ETATNONDEF) ;
00717 
00718     // Cas particuliers
00719     if (c2.get_etat() == ETATZERO) {
00720     cout << "Division by 0 in double / Valeur !" << endl ;
00721     abort() ; 
00722     }
00723     
00724     // Cas general
00725     assert(c2.get_etat() == ETATQCQ) ;  // sinon...
00726 
00727     // Il faut les valeurs physiques de c2
00728     if (c2.c == 0x0) {
00729     c2.coef_i() ;
00730     }
00731     
00732     // Le resultat
00733     Valeur r(c2.get_mg()) ;
00734     r.set_etat_c_qcq() ;
00735     *(r.c) = x / *(c2.c) ;
00736     
00737     // affectation de la base :
00738     r.base = c2.get_mg()->std_base_scal() * c2.base ; 
00739     
00740     // Termine
00741     return r ;
00742 }
00743 
00744 // Valeur / int
00745 // ------------
00746 Valeur operator/(const Valeur& t1,  int m) {
00747     return t1 / double(m) ;
00748 }
00749 
00750 // int / Valeur
00751 // ------------
00752 Valeur operator/(int m, const Valeur& t1) {
00753     return double(m) / t1 ;
00754 }
00755 
00756 // Valeur / Mtbl 
00757 // ---------------
00758 Valeur operator/(const Valeur& t1, const Mtbl& m2)     
00759 {
00760     // Protections
00761     assert(t1.get_etat() != ETATNONDEF) ;
00762     assert(m2.get_etat() != ETATNONDEF) ;
00763     
00764     // Cas particuliers
00765     if ( m2.get_etat() == ETATZERO ) {
00766     cout << "Division by 0 in Valeur / Mtbl !" << endl ;
00767     abort() ;
00768     }
00769     if (t1.get_etat() == ETATZERO) {
00770     return t1 ;
00771     }
00772 
00773     assert(t1.get_etat() == ETATQCQ) ;  // sinon...
00774 
00775     Valeur resu(t1.get_mg()) ; 
00776 
00777     // La division est faite dans l'espace des configurations:    
00778     if (t1.c == 0x0) {
00779     t1.coef_i() ; 
00780     }
00781     
00782     resu = (*(t1.c)) / m2 ; // Division Mtbl / Mtbl 
00783         
00784     return resu ;
00785 }
00786 
00787 // Mtbl / Valeur
00788 // ---------------
00789 Valeur operator/(const Mtbl& m1, const Valeur & c2) {
00790     
00791     // Protection
00792     assert(m1.get_etat() != ETATNONDEF) ;
00793     assert(c2.get_etat() != ETATNONDEF) ;
00794 
00795     // Cas particuliers
00796     if (c2.get_etat() == ETATZERO) {
00797     cout << "Division by 0 in Mtbl / Valeur !" << endl ;
00798     abort() ; 
00799     }
00800     
00801     // Cas general
00802     assert(c2.get_etat() == ETATQCQ) ;  // sinon...
00803 
00804     // Le resultat
00805     Valeur resu(c2.get_mg()) ;
00806 
00807     // Il faut les valeurs physiques de c2
00808     if (c2.c == 0x0) {
00809     c2.coef_i() ;
00810     }
00811     
00812     resu = m1 / (*(c2.c))  ;    // Division Mtbl / Mtbl
00813     
00814     // Termine
00815     return resu ;
00816 }
00817 
00818 
00819 
00820 
00821 
00822 
00823             //*******************//
00824             // operateurs +=,... //
00825             //*******************//
00826 
00827 void Valeur::operator+=(const Valeur & vi) {
00828     
00829     // Protection
00830     assert(mg == vi.get_mg()) ;         // meme grille
00831     assert(etat != ETATNONDEF) ;        // etat defini
00832     assert(vi.get_etat() != ETATNONDEF) ;   // etat defini
00833     
00834     // Cas particulier
00835     if (vi.get_etat() == ETATZERO) {
00836     return ;
00837     }
00838     
00839     // Cas general
00840     
00841     // Cas de l'etat ZERO
00842     if (etat == ETATZERO) {
00843     annule_hard() ;
00844     }
00845     
00846 
00847     if (c != 0x0) {
00848     if (vi.c != 0x0) {
00849         *c += *(vi.c) ;     // += Mtbl
00850         delete c_cf ; 
00851         c_cf = 0x0 ; 
00852     }
00853     else {
00854         assert(vi.c_cf != 0x0) ;
00855         if (c_cf != 0x0) {
00856         *c_cf += *(vi.c_cf) ;    // += Mtbl_cf
00857         delete c ; 
00858         c = 0x0 ; 
00859         }
00860         else {
00861         vi.coef_i() ; 
00862         *c += *(vi.c) ;      // += Mtbl
00863         delete c_cf ; 
00864         c_cf = 0x0 ; 
00865         }
00866     }
00867     }
00868     else{   // Case where c is not up to date
00869     assert(c_cf != 0x0) ;
00870     if (vi.c_cf != 0x0) {
00871         *c_cf += *(vi.c_cf) ;    // += Mtbl_cf
00872         delete c ; 
00873         c = 0x0 ; 
00874     }
00875     else {
00876         assert(vi.c != 0x0) ; 
00877         coef_i() ; 
00878         *c += *(vi.c) ;      // += Mtbl
00879         delete c_cf ; 
00880         c_cf = 0x0 ; 
00881     }       
00882     }
00883     
00884     // Menage (a ne faire qu'a la fin seulement)
00885     del_deriv() ;
00886 
00887     
00888 }
00889 
00890 void Valeur::operator-=(const Valeur & vi) {
00891     
00892     // Protection
00893     assert(mg == vi.get_mg()) ;         // meme grille
00894     assert(etat != ETATNONDEF) ;        // etat defini
00895     assert(vi.get_etat() != ETATNONDEF) ;   // etat defini
00896     
00897     // Cas particulier
00898     if (vi.get_etat() == ETATZERO) {
00899     return ;
00900     }
00901     
00902     // Cas general
00903     
00904     // Cas de l'etat ZERO
00905     if (etat == ETATZERO) {
00906     annule_hard() ;
00907     }
00908     
00909     if (c != 0x0) {
00910     if (vi.c != 0x0) {
00911         *c -= *(vi.c) ;     // -= Mtbl
00912         delete c_cf ; 
00913         c_cf = 0x0 ; 
00914     }
00915     else {
00916         assert(vi.c_cf != 0x0) ;
00917         if (c_cf != 0x0) {
00918         *c_cf -= *(vi.c_cf) ;    // -= Mtbl_cf
00919         delete c ; 
00920         c = 0x0 ; 
00921         }
00922         else {
00923         vi.coef_i() ; 
00924         *c -= *(vi.c) ;      // -= Mtbl
00925         delete c_cf ; 
00926         c_cf = 0x0 ; 
00927         }
00928     }
00929     }
00930     else{               // Case where c is not up to date
00931     assert(c_cf != 0x0) ;
00932     if (vi.c_cf != 0x0) {
00933         *c_cf -= *(vi.c_cf) ;    // -= Mtbl_cf
00934         delete c ; 
00935         c = 0x0 ; 
00936     }
00937     else {
00938         assert(vi.c != 0x0) ; 
00939         coef_i() ; 
00940         *c -= *(vi.c) ;      // -= Mtbl
00941         delete c_cf ; 
00942         c_cf = 0x0 ; 
00943     }       
00944     }
00945 
00946     // Menage (a ne faire qu'a la fin seulement)
00947     del_deriv() ;
00948 
00949 }
00950 
00951 void Valeur::operator*=(const Valeur & vi) {
00952     
00953     // Protection
00954     assert(mg == vi.get_mg()) ;         // meme grille
00955     assert(etat != ETATNONDEF) ;        // etat defini
00956     assert(vi.get_etat() != ETATNONDEF) ;   // etat defini
00957     
00958     // Cas particuliers
00959     if (etat == ETATZERO) {
00960     return ;
00961     }
00962     if (vi.get_etat() == ETATZERO) {
00963     set_etat_zero() ;
00964     return ;
00965     }
00966     
00967     // Cas general
00968     
00969     // Calcul dans l'espace physique
00970     if (c == 0x0) {
00971     coef_i() ;
00972     }
00973     if (vi.c == 0x0) {
00974     vi.coef_i() ;
00975     }
00976     
00977     // Calcul
00978     *c *= *(vi.c) ;
00979     
00980     // Affectation de la base :
00981     base = base * vi.base ;
00982     
00983     // Coefficients
00984     delete c_cf ;
00985     c_cf = 0x0 ;
00986 
00987     // Menage (a ne faire qu'a la fin seulement)
00988     del_deriv() ;
00989 
00990 }
00991 
00992             //-----------------------------------//
00993             //  Multiplication without aliasing  //
00994             //-----------------------------------//
00995 
00996 Valeur operator%(const Valeur& t1, const Valeur& t2)       
00997 {
00998     // Protections
00999     assert(t1.get_etat() != ETATNONDEF) ;
01000     assert(t2.get_etat() != ETATNONDEF) ;
01001     assert(t1.get_mg() == t2.get_mg()) ;
01002     
01003     // Cas particuliers
01004     if (t1.get_etat() == ETATZERO) {
01005         return t1 ;
01006     }
01007     if (t2.get_etat() == ETATZERO) {
01008         return t2 ;
01009     }
01010     assert(t1.get_etat() == ETATQCQ) ;  // sinon...
01011     assert(t2.get_etat() == ETATQCQ) ;  // sinon...
01012 
01013     // Grid
01014     const Mg3d& mg = *(t1.get_mg()) ; 
01015 
01016     // Grid with twice the number of points in each dimension:
01017     const Mg3d& mg2 = *(mg.get_twice()) ;  
01018     
01019     // The coefficients are required
01020     if (t1.c_cf == 0x0) {
01021     t1.coef() ; 
01022     }
01023     if (t2.c_cf == 0x0) {
01024     t2.coef() ; 
01025     }
01026 
01027     const Mtbl_cf& c1 = *(t1.c_cf) ; 
01028     const Mtbl_cf& c2 = *(t2.c_cf) ; 
01029 
01030     assert( c1.get_etat() == ETATQCQ ) ; 
01031     assert( c2.get_etat() == ETATQCQ ) ; 
01032 
01033     // The number of coefficients is multiplied by 2 and the additionnal
01034     //  coefficients are set to zero
01035     // -----------------------------------------------------------------
01036     
01037     Mtbl_cf cc1( mg2, c1.base ) ;
01038     Mtbl_cf cc2( mg2, c2.base ) ; 
01039     
01040     cc1.set_etat_qcq() ; 
01041     cc2.set_etat_qcq() ; 
01042     
01043     for (int l=0; l<mg.get_nzone(); l++) {
01044 
01045     int nr = mg.get_nr(l) ; 
01046     int nt = mg.get_nt(l) ; 
01047     int np = mg.get_np(l) ; 
01048     int nr2 = mg2.get_nr(l) ; 
01049     int nt2 = mg2.get_nt(l) ; 
01050     int np2 = mg2.get_np(l) ; 
01051 
01052     // Copy of the coefficients of t1
01053     // ------------------------------
01054 
01055     if ( c1.t[l]->get_etat() == ETATZERO ) {
01056         cc1.t[l]->set_etat_zero() ; 
01057     }
01058     else {
01059 
01060         assert( c1.t[l]->get_etat() == ETATQCQ ) ; 
01061         cc1.t[l]->set_etat_qcq() ; 
01062 
01063         // Copy of the coefficients of t1 
01064         for (int k=0; k<np+1; k++) {
01065         for (int j=0; j<nt; j++) {
01066             for (int i=0; i<nr; i++) {
01067             cc1.t[l]->set(k, j, i) = (*(c1.t[l]))(k, j, i) ; 
01068             }
01069         }
01070         }
01071 
01072         // The extra phi coefficients are set to zero
01073         for (int k=np+1; k<np2+2; k++) {
01074         for (int j=0; j<nt2; j++) {
01075             for (int i=0; i<nr2; i++) {
01076             cc1.t[l]->set(k, j, i) = 0 ; 
01077             }
01078         }
01079         }
01080 
01081         // The extra theta coefficients are set to zero
01082         for (int k=0; k<np+1; k++) {
01083         for (int j=nt; j<nt2; j++) {
01084             for (int i=0; i<nr2; i++) {
01085             cc1.t[l]->set(k, j, i) = 0 ; 
01086             }
01087         }
01088         }
01089 
01090         // The extra r coefficients are set to zero
01091         for (int k=0; k<np+1; k++) {
01092         for (int j=0; j<nt; j++) {
01093             for (int i=nr; i<nr2; i++) {
01094             cc1.t[l]->set(k, j, i) = 0 ; 
01095             }
01096         }
01097         }
01098         
01099     }
01100 
01101     // Copy of the coefficients of t2
01102     // ------------------------------
01103 
01104     if ( c2.t[l]->get_etat() == ETATZERO ) {
01105         cc2.t[l]->set_etat_zero() ; 
01106     }
01107     else {
01108     
01109         assert( c2.t[l]->get_etat() == ETATQCQ ) ; 
01110         cc2.t[l]->set_etat_qcq() ; 
01111 
01112         // Copy of the coefficients of t2 
01113         for (int k=0; k<np+1; k++) {
01114         for (int j=0; j<nt; j++) {
01115             for (int i=0; i<nr; i++) {
01116             cc2.t[l]->set(k, j, i) = (*(c2.t[l]))(k, j, i) ; 
01117             }
01118         }
01119         }
01120 
01121         // The extra phi coefficients are set to zero
01122         for (int k=np+1; k<np2+2; k++) {
01123         for (int j=0; j<nt2; j++) {
01124             for (int i=0; i<nr2; i++) {
01125             cc2.t[l]->set(k, j, i) = 0 ; 
01126             }
01127         }
01128         }
01129 
01130         // The extra theta coefficients are set to zero
01131         for (int k=0; k<np+1; k++) {
01132         for (int j=nt; j<nt2; j++) {
01133             for (int i=0; i<nr2; i++) {
01134             cc2.t[l]->set(k, j, i) = 0 ; 
01135             }
01136         }
01137         }
01138 
01139         // The extra r coefficients are set to zero
01140         for (int k=0; k<np+1; k++) {
01141         for (int j=0; j<nt; j++) {
01142             for (int i=nr; i<nr2; i++) {
01143             cc2.t[l]->set(k, j, i) = 0 ; 
01144             }
01145         }
01146         }
01147         
01148     }
01149 
01150     }  // End of loop on the domains
01151     
01152     
01153     Valeur tt1( mg2 ) ; 
01154     Valeur tt2( mg2 ) ; 
01155     
01156     tt1 = cc1 ; 
01157     tt2 = cc2 ; 
01158     
01159 
01160     // Multiplication (in the configuration space) on the large grids
01161     // --------------------------------------------------------------
01162     
01163     tt1 = tt1 * tt2 ; 
01164     
01165     // Coefficients of the result
01166     // --------------------------
01167     
01168     tt1.coef() ; 
01169     
01170     tt1.ylm() ; 
01171     
01172     const Mtbl_cf& cr2 = *(tt1.c_cf) ; 
01173     
01174     Mtbl_cf cr(mg, cr2.base ) ; 
01175     
01176     cr.set_etat_qcq() ; 
01177     
01178     for (int l=0; l<mg.get_nzone(); l++) {
01179 
01180     if ( cr2.t[l]->get_etat() == ETATZERO ) {
01181         
01182         cr.t[l]->set_etat_zero() ; 
01183         
01184     }
01185     else {
01186     
01187         assert( cr2.t[l]->get_etat() == ETATQCQ ) ; 
01188         
01189         cr.t[l]->set_etat_qcq() ; 
01190 
01191         int nr = mg.get_nr(l) ; 
01192         int nt = mg.get_nt(l) ; 
01193         int np = mg.get_np(l) ; 
01194 
01195         // Copy of the coefficients of cr2
01196         for (int k=0; k<np+1; k++) {
01197         for (int j=0; j<nt; j++) {
01198             for (int i=0; i<nr; i++) {
01199             cr.t[l]->set(k, j, i) = (*(cr2.t[l]))(k, j, i) ; 
01200             }
01201         }
01202         }
01203     
01204         // The last coefficient in phi is set to zero
01205         for (int j=0; j<nt; j++) {
01206         for (int i=0; i<nr; i++) {
01207             cr.t[l]->set(np+1, j, i) = 0 ; 
01208         }
01209         }
01210     
01211     }
01212     
01213     }  // End of loop on the domains
01214         
01215     Valeur resu( mg ) ; 
01216 
01217     resu = cr ; 
01218     
01219     resu.ylm_i() ; 
01220     
01221     return resu ;
01222 }
01223 
01224             //---------------------------------------//
01225             //  Multiplication with de-aliasing in r //
01226             //---------------------------------------//
01227 
01228 Valeur operator|(const Valeur& t1, const Valeur& t2)       
01229 {
01230     // Protections
01231     assert(t1.get_etat() != ETATNONDEF) ;
01232     assert(t2.get_etat() != ETATNONDEF) ;
01233     assert(t1.get_mg() == t2.get_mg()) ;
01234     
01235     // Cas particuliers
01236     if (t1.get_etat() == ETATZERO) {
01237         return t1 ;
01238     }
01239     if (t2.get_etat() == ETATZERO) {
01240         return t2 ;
01241     }
01242     assert(t1.get_etat() == ETATQCQ) ;  // sinon...
01243     assert(t2.get_etat() == ETATQCQ) ;  // sinon...
01244 
01245     // Grid
01246     const Mg3d& mg = *(t1.get_mg()) ; 
01247 
01248     // Grid with twice the number of points in each dimension:
01249     const Mg3d& mg2 = *(mg.plus_half()) ; 
01250     
01251     // The coefficients are required
01252     if (t1.c_cf == 0x0) {
01253     t1.coef() ; 
01254     }
01255     if (t2.c_cf == 0x0) {
01256     t2.coef() ; 
01257     }
01258 
01259     const Mtbl_cf& c1 = *(t1.c_cf) ; 
01260     const Mtbl_cf& c2 = *(t2.c_cf) ; 
01261 
01262     assert( c1.get_etat() == ETATQCQ ) ; 
01263     assert( c2.get_etat() == ETATQCQ ) ; 
01264 
01265     // The number of coefficients is increased by 50% in r 
01266     //  and the additionnal coefficients are set to zero
01267     // ---------------------------------------------------
01268     
01269     Mtbl_cf cc1( mg2, c1.base ) ;
01270     Mtbl_cf cc2( mg2, c2.base ) ; 
01271     
01272     cc1.set_etat_qcq() ; 
01273     cc2.set_etat_qcq() ; 
01274     
01275     for (int l=0; l<mg.get_nzone(); l++) {
01276 
01277     int nr = mg.get_nr(l) ; 
01278     int nt = mg.get_nt(l) ; 
01279     int np = mg.get_np(l) ; 
01280     int nr2 = mg2.get_nr(l) ; 
01281 
01282     // Copy of the coefficients of t1
01283     // ------------------------------
01284 
01285     if ( c1.t[l]->get_etat() == ETATZERO ) {
01286         cc1.t[l]->set_etat_zero() ; 
01287     }
01288     else {
01289 
01290         assert( c1.t[l]->get_etat() == ETATQCQ ) ; 
01291         cc1.t[l]->set_etat_qcq() ; 
01292 
01293         // Copy of the coefficients of t1 
01294         for (int k=0; k<np+1; k++) {
01295         for (int j=0; j<nt; j++) {
01296             for (int i=0; i<nr; i++) {
01297             cc1.t[l]->set(k, j, i) = (*(c1.t[l]))(k, j, i) ; 
01298             }
01299         }
01300         }
01301 
01302         // The extra phi coefficient is set to zero
01303         for (int j=0; j<nt; j++) {
01304           for (int i=0; i<nr2; i++) {
01305         cc1.t[l]->set(np+1, j, i) = 0 ; 
01306           }
01307         }
01308 
01309 
01310         // The extra r coefficients are set to zero
01311         for (int k=0; k<np+1; k++) {
01312         for (int j=0; j<nt; j++) {
01313             for (int i=nr; i<nr2; i++) {
01314             cc1.t[l]->set(k, j, i) = 0 ; 
01315             }
01316         }
01317         }
01318         
01319     }
01320 
01321     // Copy of the coefficients of t2
01322     // ------------------------------
01323 
01324     if ( c2.t[l]->get_etat() == ETATZERO ) {
01325         cc2.t[l]->set_etat_zero() ; 
01326     }
01327     else {
01328     
01329         assert( c2.t[l]->get_etat() == ETATQCQ ) ; 
01330         cc2.t[l]->set_etat_qcq() ; 
01331 
01332         // Copy of the coefficients of t2 
01333         for (int k=0; k<np+1; k++) {
01334         for (int j=0; j<nt; j++) {
01335             for (int i=0; i<nr; i++) {
01336             cc2.t[l]->set(k, j, i) = (*(c2.t[l]))(k, j, i) ; 
01337             }
01338         }
01339         }
01340 
01341         // The extra phi coefficient is set to zero
01342         for (int j=0; j<nt; j++) {
01343           for (int i=0; i<nr2; i++) {
01344         cc2.t[l]->set(np+1, j, i) = 0 ; 
01345           }
01346         }
01347 
01348         // The extra r coefficients are set to zero
01349         for (int k=0; k<np+1; k++) {
01350         for (int j=0; j<nt; j++) {
01351             for (int i=nr; i<nr2; i++) {
01352             cc2.t[l]->set(k, j, i) = 0 ; 
01353             }
01354         }
01355         }
01356         
01357     }
01358 
01359     }  // End of loop on the domains
01360     
01361     
01362     Valeur tt1( mg2 ) ; 
01363     Valeur tt2( mg2 ) ; 
01364     
01365     tt1 = cc1 ; 
01366     tt2 = cc2 ; 
01367     
01368     // Multiplication (in the configuration space) on the large grids
01369     // --------------------------------------------------------------
01370     
01371     tt1 = tt1 * tt2 ; 
01372     
01373     // Coefficients of the result
01374     // --------------------------
01375     
01376     tt1.coef() ; 
01377     
01378     const Mtbl_cf& cr2 = *(tt1.c_cf) ; 
01379     
01380     Mtbl_cf cr(mg, cr2.base ) ; 
01381     
01382     cr.set_etat_qcq() ; 
01383     
01384     for (int l=0; l<mg.get_nzone(); l++) {
01385 
01386     if ( cr2.t[l]->get_etat() == ETATZERO ) {
01387         
01388         cr.t[l]->set_etat_zero() ; 
01389         
01390     }
01391     else {
01392     
01393         assert( cr2.t[l]->get_etat() == ETATQCQ ) ; 
01394         
01395         cr.t[l]->set_etat_qcq() ; 
01396 
01397         int nr = mg.get_nr(l) ; 
01398         int nt = mg.get_nt(l) ; 
01399         int np = mg.get_np(l) ; 
01400 
01401         // Copy of the coefficients of cr2
01402         for (int k=0; k<np+1; k++) {
01403         for (int j=0; j<nt; j++) {
01404             for (int i=0; i<nr; i++) {
01405             cr.t[l]->set(k, j, i) = (*(cr2.t[l]))(k, j, i) ; 
01406             }
01407         }
01408         }
01409     
01410         // The last coefficient in phi is set to zero
01411         for (int j=0; j<nt; j++) {
01412         for (int i=0; i<nr; i++) {
01413             cr.t[l]->set(np+1, j, i) = 0 ; 
01414         }
01415         }
01416     
01417     }
01418     
01419     }  // End of loop on the domains
01420         
01421     Valeur resu( mg ) ; 
01422 
01423     resu = cr ; 
01424     
01425     return resu ;
01426 }
01427 

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