Qucs-core
0.0.19
|
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