Qucs-core  0.0.19
real.cpp
Go to the documentation of this file.
00001 /*
00002  * real.cpp - some real valued function implementations
00003  *
00004  * Copyright (C) 2008 Stefan Jahn <stefan@lkcc.org>
00005  * Copyright (C) 2014 Guilheme Brondani Torri <guitorri@gmail.com>
00006  *
00007  * This is free software; you can redistribute it and/or modify
00008  * it under the terms of the GNU General Public License as published by
00009  * the Free Software Foundation; either version 2, or (at your option)
00010  * any later version.
00011  *
00012  * This software is distributed in the hope that it will be useful,
00013  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00015  * GNU General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU General Public License
00018  * along with this package; see the file COPYING.  If not, write to
00019  * the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
00020  * Boston, MA 02110-1301, USA.
00021  *
00022  * $Id$
00023  *
00024  */
00025 
00026 #if HAVE_CONFIG_H
00027 # include <config.h>
00028 #endif
00029 
00030 //#include <cstdlib>
00031 #include <cmath>
00032 #include <cassert>
00033 
00034 #include "consts.h"
00035 #include "real.h"
00036 
00037 namespace qucs {
00038 
00039 //
00040 // trigonometric
00041 //
00042 
00047 nr_double_t cos (const nr_double_t arg) {
00048   return std::cos (arg);
00049 }
00050 
00055 nr_double_t sin (const nr_double_t arg) {
00056   return std::sin (arg);
00057 }
00058 
00063 nr_double_t  tan (const nr_double_t arg) {
00064   return std::tan (arg);
00065 }
00066 
00071 nr_double_t  acos (const nr_double_t arg) {
00072   return std::acos (arg);
00073 }
00074 
00079 nr_double_t  asin (const nr_double_t arg) {
00080   return std::asin (arg);
00081 }
00082 
00087 nr_double_t  atan (const nr_double_t arg) {
00088   return std::atan (arg);
00089 }
00090 
00096 nr_double_t  atan2 (const nr_double_t x, const nr_double_t y) {
00097   return std::atan2 (x,y);
00098 }
00099 
00100 //
00101 // hyperbolic
00102 //
00103 
00108 nr_double_t  cosh (const nr_double_t arg) {
00109   return std::cosh (arg);
00110 }
00111 
00116 nr_double_t  sinh (const nr_double_t arg) {
00117   return std::sinh (arg);
00118 }
00119 
00124 nr_double_t  tanh (const nr_double_t arg) {
00125   return std::tanh (arg);
00126 }
00127 
00132 nr_double_t  acosh (const nr_double_t arg) {
00133 #ifdef HAVE_STD_ACOSH
00134   // c++11
00135   return std::acosh (arg);
00136 #elif HAVE_ACOSH
00137   return ::acosh (arg);
00138 #else
00139   return log (arg + sqrt (arg * arg - 1.0));
00140 #endif
00141 }
00142 
00147 nr_double_t asinh (const nr_double_t arg)
00148 {
00149 #ifdef HAVE_STD_ASINH
00150   // c++11
00151   return std::asinh (arg);
00152 #elif HAVE_ASINH
00153   return ::asinh (arg);
00154 #else
00155   return log (arg + sqrt (arg * arg + 1.0));
00156 #endif
00157 }
00158 
00163 nr_double_t atanh (const nr_double_t arg)
00164 {
00165 #ifdef HAVE_STD_ATANH
00166   // c++11
00167   return std::atanh (arg);
00168 #elif HAVE_ATANH
00169   return ::atanh (arg);
00170 #else
00171   return 0.5 * log ( 2.0 / (1.0 - arg) - 1.0);
00172 #endif
00173 }
00174 
00175 
00176 //
00177 // exponential and logarithmic functions
00178 //
00179 nr_double_t exp (const nr_double_t arg) {
00180   return std::exp (arg);
00181 }
00182 nr_double_t log (const nr_double_t arg) {
00183   return std::log (arg);
00184 }
00185 nr_double_t log10 (const nr_double_t arg) {
00186   return std::log10 (arg);
00187 }
00188 
00189 //
00190 // power functions
00191 //
00192 
00193 nr_double_t pow (const nr_double_t a, const nr_double_t b)
00194 {
00195   return std::pow (a,b);
00196 }
00197 
00198 nr_double_t sqrt (const nr_double_t d) {
00199   return std::sqrt (d);
00200 }
00201 
00213 nr_double_t xhypot (const nr_double_t a, const nr_double_t b) {
00214 #ifdef HAVE_STD_HYPOT
00215   return std::hypot(a,b) // c++11
00216 #else
00217   nr_double_t c = fabs (a);
00218   nr_double_t d = fabs (b);
00219   if (c > d) {
00220     nr_double_t e = d / c;
00221     return c * sqrt (1 + e * e);
00222   }
00223   else if (d == 0)
00224     return 0;
00225   else {
00226     nr_double_t e = c / d;
00227     return d * sqrt (1 + e * e);
00228   }
00229 #endif
00230 }
00231 
00232 //
00233 // error functions
00234 //
00235 
00236 nr_double_t erf( nr_double_t arg) {
00237 #ifdef HAVE_STD_ERF
00238   return std::erf (arg); // c++11
00239 #elif HAVE_ERF
00240   return ::erf (arg);
00241 #endif
00242 }
00243 
00244 
00245 //
00246 // rounding and remainder functions
00247 //
00248 nr_double_t ceil( nr_double_t arg) {
00249   return std::ceil(arg);
00250 }
00251 
00252 nr_double_t floor( nr_double_t arg) {
00253   return std::floor(arg);
00254 }
00255 
00256 nr_double_t fmod( nr_double_t arg) {
00257 #ifdef HAVE_STD_TRUNC
00258   return std::fmod(arg);
00259 #else
00260   return fmod(arg);
00261 #endif
00262 }
00263 
00264 nr_double_t trunc( nr_double_t arg) {
00265 #ifdef HAVE_STD_TRUNC
00266   return std::trunc(arg);
00267 #elif HAVE_TRUNC
00268   return ::trunc (arg);
00269 #else
00270   return arg > 0 ? floor (arg) : floor (arg + 1);
00271 #endif
00272 }
00273 nr_double_t round( nr_double_t arg) {
00274 #ifdef HAVE_STD_ROUND
00275   return std::round(arg);
00276 #elif HAVE_ROUND
00277   return ::round (arg);
00278 #else
00279   return (arg > 0) ? floor (arg + 0.5) : ceil (arg - 0.5);
00280 #endif
00281 }
00282 
00283 
00284 //
00285 // Qucs extra trigonometric helper
00286 //
00287 nr_double_t coth (const nr_double_t d) {
00288   return 1.0 / std::tanh (d);
00289 }
00290 
00291 nr_double_t sech (const nr_double_t d) {
00292   return  (1.0 / std::cosh (d));
00293 }
00294 
00295 nr_double_t cosech (const nr_double_t d) {
00296   return  (1.0 / std::sinh (d));
00297 }
00298 
00299 
00300 //
00301 // Qucs extra math functions
00302 //
00303 
00309 nr_double_t  sqr (const nr_double_t r) {
00310   return r * r;
00311 }
00312 
00313 unsigned int sqr (unsigned int r) {
00314   return r * r;
00315 }
00316 
00317 
00318 
00324 nr_double_t  quadr (const nr_double_t r) {
00325   return r * r * r * r;
00326 }
00327 
00328 
00329 //
00330 //  extra math functions
00331 //
00332 
00350 nr_double_t limexp (const nr_double_t r) {
00351   return r < limitexp ? exp (r) : exp (limitexp) * (1.0 + (r - limitexp));
00352 }
00353 
00368 nr_double_t signum (const nr_double_t d) {
00369   if (d == 0) return 0;
00370   return d < 0 ? -1 : 1;
00371 }
00372 
00386 nr_double_t sign (const nr_double_t d) {
00387   return d < 0 ? -1 : 1;
00388 }
00389 
00397 nr_double_t sinc (const nr_double_t d) {
00398   if (d == 0) return 1;
00399   return sin (d) / d;
00400 }
00401 
00416 nr_double_t fix (const nr_double_t d) {
00417   return (d > 0) ? floor (d) : ceil (d);
00418 }
00419 
00429 nr_double_t step (const nr_double_t d) {
00430   nr_double_t x = d;
00431   if (x < 0.0)
00432     x = 0.0;
00433   else if (x > 0.0)
00434     x = 1.0;
00435   else
00436     x = 0.5;
00437   return x;
00438 }
00439 
00443 unsigned int
00444 factorial (unsigned int n) {
00445   unsigned int result = 1;
00446 
00447   /* 13! > 2^32 */
00448   assert (n < 13);
00449 
00450   if (n == 0)
00451     return 1;
00452 
00453   for (; n > 1; n--)
00454     result = result * n;
00455 
00456   return result;
00457 }
00458 
00459 
00460 //
00461 // overload complex manipulations on reals
00462 //
00463 
00464 
00470 nr_double_t real (const nr_double_t r) {
00471   return r;
00472 }
00473 
00479 nr_double_t imag (const nr_double_t r) {
00480   return 0.0;
00481 }
00482 
00489 nr_double_t norm (const nr_double_t r) {
00490   return r * r;
00491 }
00492 
00498 nr_double_t abs (const nr_double_t r) {
00499   return std::abs (r);
00500 }
00501 
00507 nr_double_t conj (const nr_double_t r) {
00508   return r;
00509 }
00510 
00516 nr_double_t rad2deg (const nr_double_t x) {
00517   return (180.0 * (x) / pi); 
00518 }
00519 
00525 nr_double_t deg2rad (const nr_double_t x) {
00526   return (pi * (x) / 180.0); 
00527 }
00528 
00529 
00530 
00531 } // namespace qucs