STK++ 1.0
STK_Funct_log1p.cpp
Go to the documentation of this file.
00001 /*--------------------------------------------------------------------*/
00002 /*     Copyright (C) 2004-2007  Serge Iovleff
00003 
00004     This program is free software; you can redistribute it and/or modify
00005     it under the terms of the GNU Lesser General Public License as
00006     published by the Free Software Foundation; either version 2 of the
00007     License, or (at your option) any later version.
00008 
00009     This program is distributed in the hope that it will be useful,
00010     but WITHOUT ANY WARRANTY; without even the implied warranty of
00011     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00012     GNU Lesser General Public License for more details.
00013 
00014     You should have received a copy of the GNU Lesser General Public
00015     License along with this program; if not, write to the
00016     Free Software Foundation, Inc.,
00017     59 Temple Place,
00018     Suite 330,
00019     Boston, MA 02111-1307
00020     USA
00021 
00022     Contact : Serge.Iovleff@stkpp.org
00023 */
00024 
00025 /*
00026  * Project:  Analysis
00027  * Purpose:  implementation of log(x+1)
00028  * Author:   Serge Iovleff, serge.iovleff@stkpp.org
00029  **/
00030 
00035 #include <cmath>
00036 
00037 #include "../../STKernel/include/STK_Exceptions.h"
00038 #include "../../STKernel/include/STK_Integer.h"
00039 #include "../../STKernel/include/STK_Real.h"
00040 #include "../../STKernel/include/STK_Misc.h"
00041 
00042 #include "../include/STK_ISerie.h"
00043 #include "../include/STK_Algo.h"
00044 #include "../include/STK_Funct_util.h"
00045 
00046 namespace STK
00047 {
00048 namespace Funct
00049 {
00057 class Serielog1p : public ISerie<Serielog1p>
00058 {
00059   private:
00060     const   Real& x_;
00061     mutable Real n_;
00062     mutable Real xpown_;
00063 
00064   public:
00065     inline Serielog1p( Real const& x)
00066                        : x_(x)
00067                        , n_(2), xpown_(1.)
00068     { ;}
00069 
00070     inline Real first() const
00071     { return 1./n_;}
00072 
00073     inline Real next() const
00074     {
00075       // n
00076       ++n_;
00077       // x^n
00078       xpown_ *= x_;
00079       // x^n/(n+2)
00080       return xpown_/n_;
00081     }
00082 };
00083 
00088 Real log1p(Real const& x)
00089 {
00090   // trivial values
00091   if (x == 0.)  return 0.;
00092   if (x == -1.) return(-Arithmetic<Real>::infinity());
00093   // check domain
00094   if (x  < -1)
00095      throw domain_error("Funct::log1p(x) "
00096                         "Negative Real argument");
00097   // small values
00098   if (abs(x) < .375)
00099   {
00100     // create functor and compute the alternate serie
00101     Serielog1p f(x);
00102     return x * (1. - x * sumAlternateSerie(f));
00103   }
00104   // large values : compute directly the result
00105   return log(1. + x);
00106 }
00107 
00108 } // namespace Funct
00109 
00110 } // namespace STK