scalar_math.C

00001 /*
00002  *  Mathematical functions for the Scalar class.
00003  *
00004  *  These functions are not member functions of the Scalar class.
00005  *
00006  */
00007 
00008 /*
00009  *   Copyright (c) 2003 Eric Gourgoulhon & Jerome Novak
00010  *
00011  *   Copyright (c) 1999-2003 Eric Gourgoulhon
00012  *   Copyright (c) 1999-2001 Philippe Grandclement
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 scalar_math_C[] = "$Header: /cvsroot/Lorene/C++/Source/Tensor/Scalar/scalar_math.C,v 1.4 2012/01/17 10:27:46 j_penner Exp $" ;
00033 
00034 /*
00035  * $Id: scalar_math.C,v 1.4 2012/01/17 10:27:46 j_penner Exp $
00036  * $Log: scalar_math.C,v $
00037  * Revision 1.4  2012/01/17 10:27:46  j_penner
00038  * added a Heaviside function
00039  *
00040  * Revision 1.3  2003/10/10 15:57:29  j_novak
00041  * Added the state one (ETATUN) to the class Scalar
00042  *
00043  * Revision 1.2  2003/10/01 13:04:44  e_gourgoulhon
00044  * The method Tensor::get_mp() returns now a reference (and not
00045  * a pointer) onto a mapping.
00046  *
00047  * Revision 1.1  2003/09/25 08:06:56  e_gourgoulhon
00048  * First versions (use Cmp as intermediate quantities).
00049  *
00050  *
00051  * $Header: /cvsroot/Lorene/C++/Source/Tensor/Scalar/scalar_math.C,v 1.4 2012/01/17 10:27:46 j_penner Exp $
00052  *
00053  */
00054 
00055 // Headers C
00056 #include <math.h>
00057 
00058 // Headers Lorene
00059 #include "tensor.h"
00060 
00061                 //-------//
00062                 // Sine  //
00063                 //-------//
00064 
00065 Scalar sin(const Scalar& ci)
00066 {
00067     // Protection
00068     assert(ci.get_etat() != ETATNONDEF) ;
00069     
00070     // Cas ETATZERO
00071     if (ci.get_etat() == ETATZERO) {
00072         return ci ;
00073     }
00074     
00075     // Cas ETATUN
00076     if (ci.get_etat() == ETATUN) {
00077       Scalar resu(ci.get_mp()) ;
00078       resu = sin(double(1)) ;
00079       return resu ;
00080     }
00081     
00082     // Cas general
00083     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00084 
00085     Scalar co(ci.get_mp()) ;        // result
00086 
00087     co.set_etat_qcq() ; 
00088     co.va = sin( ci.va ) ; 
00089 
00090     return co ;
00091 }
00092 
00093                 //---------//
00094                 // Cosine  //
00095                 //---------//
00096 
00097 Scalar cos(const Scalar& ci)
00098 {
00099     // Protection
00100     assert(ci.get_etat() != ETATNONDEF) ;
00101     
00102     Scalar co(ci.get_mp()) ;        // result
00103 
00104     // Cas ETATZERO
00105     if (ci.get_etat() == ETATZERO) {
00106         co.set_etat_qcq() ; 
00107         co.va = double(1) ;
00108     }
00109     else {
00110       // Cas ETATUN
00111       if (ci.get_etat() == ETATUN) {
00112     co = cos(double(1)) ;
00113       }
00114       else {
00115         // Cas general
00116     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00117         co.set_etat_qcq() ; 
00118         co.va = cos( ci.va ) ; 
00119       }
00120     }
00121 
00122     return co ;
00123 }
00124 
00125                 //----------//
00126                 // Tangent  //
00127                 //----------//
00128 
00129 Scalar tan(const Scalar& ci)
00130 {
00131     // Protection
00132     assert(ci.get_etat() != ETATNONDEF) ;
00133     
00134     // Cas ETATZERO
00135     if (ci.get_etat() == ETATZERO) {
00136         return ci ;
00137     }
00138     
00139     // Cas ETATUN
00140     if (ci.get_etat() == ETATUN) {
00141       Scalar resu(ci.get_mp()) ;
00142       resu = tan(double(1)) ;
00143       return resu ;
00144     }
00145     
00146     // Cas general
00147     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00148 
00149     Scalar co(ci.get_mp()) ;        // result
00150     co.set_etat_qcq() ; 
00151     co.va = tan( ci.va ) ; 
00152 
00153     return co ;
00154 }
00155 
00156                 //----------//
00157                 // Arcsine  //
00158                 //----------//
00159 
00160 Scalar asin(const Scalar& ci)
00161 {
00162     // Protection
00163     assert(ci.get_etat() != ETATNONDEF) ;
00164     
00165     // Cas ETATZERO
00166     if (ci.get_etat() == ETATZERO) {
00167     return ci ;
00168     }
00169     
00170     // Cas ETATUN
00171     if (ci.get_etat() == ETATUN) {
00172       Scalar resu(ci.get_mp()) ;
00173       resu = M_PI_2 ;
00174       return resu ;
00175     }
00176     
00177     // Cas general
00178     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00179 
00180     Scalar co(ci.get_mp()) ;        // result
00181 
00182     co.set_etat_qcq() ; 
00183     co.va = asin( ci.va ) ; 
00184 
00185     return co ;
00186 }
00187 
00188                 //-------------//
00189                 // Arccosine  //
00190                 //-------------//
00191 
00192 Scalar acos(const Scalar& ci)
00193 {
00194     // Protection
00195     assert(ci.get_etat() != ETATNONDEF) ;
00196     
00197     Scalar co(ci.get_mp()) ;        // result
00198 
00199     // Cas ETATZERO
00200     if (ci.get_etat() == ETATZERO) {
00201     co.set_etat_qcq() ; 
00202     co.va = double(0.5) * M_PI ;
00203     }
00204     else {
00205       // Cas ETATUN
00206       if (ci.get_etat() == ETATUN) {
00207     co.set_etat_zero() ;
00208       }
00209       else {
00210     // Cas general
00211     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00212     co.set_etat_qcq() ; 
00213     co.va = acos( ci.va ) ; 
00214       }
00215     }
00216 
00217     return co ;
00218 }
00219 
00220                 //-------------//
00221                 // Arctangent  //
00222                 //-------------//
00223 
00224 Scalar atan(const Scalar& ci)
00225 {
00226     // Protection
00227     assert(ci.get_etat() != ETATNONDEF) ;
00228     
00229     // Cas ETATZERO
00230     if (ci.get_etat() == ETATZERO) {
00231     return ci ;
00232     }
00233     
00234     // Cas ETATUN
00235     if (ci.get_etat() == ETATUN) {
00236       Scalar resu(ci.get_mp()) ;
00237       resu = 0.25*M_PI ;
00238       return resu ;
00239     }
00240     
00241     // Cas general
00242     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00243 
00244     Scalar co(ci.get_mp()) ;        // result
00245 
00246     co.set_etat_qcq() ; 
00247     co.va = atan( ci.va ) ; 
00248 
00249     return co ;
00250 }
00251 
00252                 //-------------//
00253                 // Square root //
00254                 //-------------//
00255 
00256 Scalar sqrt(const Scalar& ci)
00257 {
00258     // Protection
00259     assert(ci.get_etat() != ETATNONDEF) ;
00260     
00261     // Cas ETATZERO
00262     if (ci.get_etat() == ETATZERO) {
00263     return ci ;
00264     }
00265     
00266     // Cas ETATUN
00267     if (ci.get_etat() == ETATUN) {
00268     return ci ;
00269     }
00270     
00271     // Cas general
00272     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00273 
00274     Scalar co(ci.get_mp()) ;        // result
00275 
00276     co.set_etat_qcq() ; 
00277     co.va = sqrt( ci.va ) ; 
00278 
00279     return co ;
00280 }
00281 
00282                 //-------------//
00283                 // Cube root   //
00284                 //-------------//
00285 
00286 Scalar racine_cubique(const Scalar& ci)
00287 {
00288     // Protection
00289     assert(ci.get_etat() != ETATNONDEF) ;
00290     
00291     // Cas ETATZERO
00292     if (ci.get_etat() == ETATZERO) {
00293     return ci ;
00294     }
00295     
00296     // Cas ETATUN
00297     if (ci.get_etat() == ETATUN) {
00298     return ci ;
00299     }
00300     
00301     // Cas general
00302     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00303 
00304     Scalar co(ci.get_mp()) ;        // result
00305 
00306     co.set_etat_qcq() ; 
00307     co.va = racine_cubique( ci.va ) ; 
00308 
00309     return co ;
00310 }
00311 
00312                 //--------------//
00313                 // Exponential  //
00314                 //--------------//
00315 
00316 Scalar exp(const Scalar& ci)
00317 {
00318     // Protection
00319     assert(ci.get_etat() != ETATNONDEF) ;
00320     
00321     Scalar co(ci.get_mp()) ;        // result
00322 
00323     // Cas ETATZERO
00324     if (ci.get_etat() == ETATZERO) {
00325     co.set_etat_one() ; 
00326     }
00327     else {
00328       // Cas ETATUN
00329       if (ci.get_etat() == ETATUN) {
00330     co.set_etat_qcq() ;
00331     co = M_E ;
00332       }
00333       else {
00334     // Cas general
00335     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00336     co.set_etat_qcq() ; 
00337     co.va = exp( ci.va ) ; 
00338       }
00339     }
00340 
00341     return co ;
00342 }
00343 
00344                 //---------------------//
00345                 // Heaviside Function  //
00346                 //---------------------//
00347 
00348 Scalar Heaviside(const Scalar& ci)
00349 {
00350     // Protection
00351     assert(ci.get_etat() != ETATNONDEF) ;
00352     
00353     Scalar co(ci.get_mp()) ;        // make output a copy, to ensure the same structure
00354 
00355     // if input state is zero, return zero
00356     if (ci.get_etat() == ETATZERO) {
00357     co.set_etat_zero() ; 
00358     }
00359     else {
00360       // if input state is one, return one
00361       if (ci.get_etat() == ETATUN) {
00362     co.set_etat_one() ;
00363       }
00364       else {
00365     // In general return the Heaviside function
00366     assert(ci.get_etat() == ETATQCQ) ;  // otherwise
00367     co.set_etat_qcq() ; 
00368     co.va = Heaviside( ci.va ) ; 
00369       }
00370     }
00371 
00372     return co ;
00373 }
00374                 //---------------------//
00375                 // Neperian logarithm  //
00376                 //---------------------//
00377 
00378 Scalar log(const Scalar& ci)
00379 {
00380     // Protection
00381     assert(ci.get_etat() != ETATNONDEF) ;
00382     
00383     // Cas ETATZERO
00384     if (ci.get_etat() == ETATZERO) {
00385     cout << "Argument of log is ZERO in log(Scalar) !" << endl ; 
00386     abort() ; 
00387     }
00388 
00389     // Cas ETATUN
00390     if (ci.get_etat() == ETATUN) {
00391       Scalar resu(ci.get_mp()) ;
00392       resu.set_etat_zero() ;
00393       return resu ;
00394     }
00395 
00396     // Cas general
00397     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00398 
00399     Scalar co(ci.get_mp()) ;        // result
00400 
00401     co.set_etat_qcq() ; 
00402     co.va = log( ci.va ) ; 
00403 
00404     return co ;
00405 }
00406 
00407                 //---------------------//
00408                 // Decimal  logarithm  //
00409                 //---------------------//
00410 
00411 Scalar log10(const Scalar& ci)
00412 {
00413     // Protection
00414     assert(ci.get_etat() != ETATNONDEF) ;
00415     
00416     // Cas ETATZERO
00417     if (ci.get_etat() == ETATZERO) {
00418     cout << "Argument of log10 is ZERO in log10(Scalar) !" << endl ; 
00419     abort() ; 
00420     }
00421 
00422     // Cas ETATUN
00423     if (ci.get_etat() == ETATUN) {
00424       Scalar resu(ci.get_mp()) ;
00425       resu.set_etat_zero() ;
00426       return resu ;
00427     }
00428 
00429     // Cas general
00430     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00431 
00432     Scalar co(ci.get_mp()) ;        // result
00433 
00434     co.set_etat_qcq() ; 
00435     co.va = log10( ci.va ) ; 
00436 
00437     return co ;
00438 }
00439 
00440                 //------------------//
00441                 // Power (integer)  //
00442                 //------------------//
00443 
00444 Scalar pow(const Scalar& ci, int n)
00445 {
00446     // Protection
00447     assert(ci.get_etat() != ETATNONDEF) ;
00448     
00449     // Cas ETATZERO
00450     if (ci.get_etat() == ETATZERO) {
00451     if (n > 0) {
00452         return ci ; 
00453     }
00454     else {
00455         cout << "pow(Scalar, int) : ETATZERO^n with n <= 0 !" << endl ; 
00456         abort() ;
00457     } 
00458     }
00459 
00460     // Cas ETATUN
00461     if (ci.get_etat() == ETATUN) {
00462       return ci ;
00463     }
00464 
00465     // Cas general
00466     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00467 
00468     Scalar co(ci.get_mp()) ;        // result
00469 
00470     co.set_etat_qcq() ; 
00471     co.va = pow(ci.va,  n) ; 
00472 
00473     return co ;
00474 }
00475 
00476                 //-----------------//
00477                 // Power (double)  //
00478                 //-----------------//
00479 
00480 Scalar pow(const Scalar& ci, double x)
00481 {
00482     // Protection
00483     assert(ci.get_etat() != ETATNONDEF) ;
00484     
00485     // Cas ETATZERO
00486     if (ci.get_etat() == ETATZERO) {
00487     if (x > double(0)) {
00488         return ci ; 
00489     }
00490     else {
00491         cout << "pow(Scalar, double) : ETATZERO^x with x <= 0 !" << endl ; 
00492         abort() ;
00493     } 
00494     }
00495 
00496     // Cas ETATUN
00497     if (ci.get_etat() == ETATUN) {
00498       return ci ;
00499     }
00500 
00501     // Cas general
00502     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00503 
00504     Scalar co(ci.get_mp()) ;        // result
00505 
00506     co.set_etat_qcq() ; 
00507     co.va = pow(ci.va, x) ; 
00508 
00509     return co ;
00510 }
00511 
00512                 //-----------------//
00513                 // Absolute value  //
00514                 //-----------------//
00515 
00516 Scalar abs(const Scalar& ci)
00517 {
00518     // Protection
00519     assert(ci.get_etat() != ETATNONDEF) ;
00520     
00521     // Cas ETATZERO
00522     if (ci.get_etat() == ETATZERO) {
00523     return ci ;
00524     }
00525     
00526     // Cas ETATUN
00527     if (ci.get_etat() == ETATUN) {
00528       return ci ;
00529     }
00530 
00531     // Cas general
00532     assert(ci.get_etat() == ETATQCQ) ;  // sinon...
00533 
00534     Scalar co(ci.get_mp()) ;        // result
00535 
00536     co.set_etat_qcq() ; 
00537     co.va = abs( ci.va ) ; 
00538 
00539     return co ;
00540 }
00541 
00542             //-------------------------------//
00543                     //            totalmax           //
00544             //-------------------------------//
00545 
00546 double totalmax(const Scalar& ci) {
00547 
00548     // Protection
00549     assert(ci.get_etat() != ETATNONDEF) ;
00550     
00551 //    Tbl resu( ci.get_mp().get_mg()->get_nzone() ) ; 
00552     double resu ; 
00553     
00554     if (ci.get_etat() == ETATZERO) {
00555     resu = 0 ; 
00556     }
00557     else {
00558       if (ci.get_etat() == ETATUN) {
00559     resu = 1 ; 
00560       }
00561       else {
00562     assert(ci.get_etat() == ETATQCQ) ;  
00563     
00564     resu = totalmax( ci.va ) ;      // max(Valeur) 
00565       }
00566     }
00567    
00568     return resu ; 
00569 }
00570 
00571             //-------------------------------//
00572                     //            totalmin           //
00573             //-------------------------------//
00574 
00575 double totalmin(const Scalar& ci) {
00576 
00577     // Protection
00578     assert(ci.get_etat() != ETATNONDEF) ;
00579     
00580 //    Tbl resu( ci.get_mp().get_mg()->get_nzone() ) ; 
00581     double resu ; 
00582     
00583     if (ci.get_etat() == ETATZERO) {
00584     resu = 0 ; 
00585     }
00586     else {
00587       if (ci.get_etat() == ETATUN) {
00588     resu = 1 ; 
00589       }
00590       else {
00591     assert(ci.get_etat() == ETATQCQ) ;  
00592     
00593     resu = totalmin( ci.va ) ;      // min(Valeur)  
00594       }
00595     }
00596           
00597     return resu ; 
00598 }
00599 
00600             //-------------------------------//
00601                     //            max                //
00602             //-------------------------------//
00603 
00604 Tbl max(const Scalar& ci) {
00605 
00606     // Protection
00607     assert(ci.get_etat() != ETATNONDEF) ;
00608     
00609     Tbl resu( ci.get_mp().get_mg()->get_nzone() ) ; 
00610     
00611     if (ci.get_etat() == ETATZERO) {
00612     resu.annule_hard() ; 
00613     }
00614     else {
00615       if (ci.get_etat() == ETATUN) {
00616     resu = 1 ; 
00617       }
00618       else {
00619     assert(ci.get_etat() == ETATQCQ) ;  
00620     
00621     resu = max( ci.va ) ;       // max(Valeur) 
00622       }
00623     }
00624    
00625     return resu ; 
00626 }
00627 
00628             //-------------------------------//
00629                     //            min                //
00630             //-------------------------------//
00631 
00632 Tbl min(const Scalar& ci) {
00633 
00634     // Protection
00635     assert(ci.get_etat() != ETATNONDEF) ;
00636     
00637     Tbl resu( ci.get_mp().get_mg()->get_nzone() ) ; 
00638     
00639     if (ci.get_etat() == ETATZERO) {
00640     resu.annule_hard() ; 
00641     }
00642     else {
00643       if (ci.get_etat() == ETATUN) {
00644     resu = 1 ; 
00645       }
00646       else {
00647     assert(ci.get_etat() == ETATQCQ) ;  
00648     
00649     resu = min( ci.va ) ;       // min(Valeur)  
00650       }
00651     }
00652           
00653     return resu ; 
00654 }
00655 
00656             //-------------------------------//
00657                     //            norme              //
00658             //-------------------------------//
00659 
00660 Tbl norme(const Scalar& ci) {
00661 
00662     // Protection
00663     assert(ci.get_etat() != ETATNONDEF) ;
00664     
00665     Tbl resu( ci.get_mp().get_mg()->get_nzone() ) ; 
00666     
00667     if (ci.get_etat() == ETATZERO) {
00668     resu.annule_hard() ; 
00669     }
00670     else {
00671       if (ci.get_etat() == ETATUN) {
00672     resu = 1 ; 
00673       }
00674       else {
00675     assert(ci.get_etat() == ETATQCQ) ;  
00676     
00677     resu = norme( ci.va ) ;     // norme(Valeur)    
00678       }
00679     }
00680           
00681     return resu ; 
00682 }
00683 
00684             //-------------------------------//
00685                     //          diffrel              //
00686             //-------------------------------//
00687 
00688 Tbl diffrel(const Scalar& c1, const Scalar& c2) {
00689     
00690     // Protections
00691     assert(c1.get_etat() != ETATNONDEF) ;
00692     assert(c2.get_etat() != ETATNONDEF) ;
00693 
00694     int nz = c1.get_mp().get_mg()->get_nzone() ;
00695     Tbl resu(nz) ; 
00696     
00697     Scalar diff = c1 - c2 ;     // la compatibilite dzpuis est testee a ce niveau
00698 
00699     Tbl normdiff = norme(diff) ; 
00700     Tbl norme2 = norme(c2) ;
00701     
00702     assert(normdiff.get_etat() == ETATQCQ) ;     
00703     assert(norme2.get_etat() == ETATQCQ) ; 
00704 
00705     resu.set_etat_qcq() ; 
00706     for (int l=0; l<nz; l++) {
00707     if ( norme2(l) == double(0) ) {
00708         resu.set(l) = normdiff(l) ; 
00709     }
00710     else{
00711         resu.set(l) = normdiff(l) / norme2(l) ;             
00712     }
00713     }
00714     
00715     return resu ; 
00716     
00717 }
00718 
00719             //-------------------------------//
00720             //          diffrelmax           //
00721             //-------------------------------//
00722 
00723 Tbl diffrelmax(const Scalar& c1, const Scalar& c2) {
00724     
00725     // Protections
00726     assert(c1.get_etat() != ETATNONDEF) ;
00727     assert(c2.get_etat() != ETATNONDEF) ;
00728     
00729     int nz = c1.get_mp().get_mg()->get_nzone() ;
00730     Tbl resu(nz) ; 
00731     
00732     Tbl max2 = max(abs(c2)) ;
00733     
00734     Scalar diff = c1 - c2 ;    // la compatibilite dzpuis est testee a ce niveau
00735 
00736     Tbl maxdiff = max(abs(diff)) ; 
00737     
00738     assert(maxdiff.get_etat() == ETATQCQ) ;     
00739     assert(max2.get_etat() == ETATQCQ) ; 
00740 
00741     resu.set_etat_qcq() ; 
00742     for (int l=0; l<nz; l++) {
00743     if ( max2(l) == double(0) ) {
00744         resu.set(l) = maxdiff(l) ; 
00745     }
00746     else{
00747         resu.set(l) = maxdiff(l) / max2(l) ;            
00748     }
00749     }
00750     
00751     return resu ; 
00752     
00753 }
00754 

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