* real.h - some real valued function definitions
*
* Copyright (C) 2008 Stefan Jahn <stefan@lkcc.org>
* Copyright (C) 2014 Guilheme Brondani Torri <guitorri@gmail.com>
*
* This is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2, or (at your option)
* any later version.
*
* This software is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this package; see the file COPYING. If not, write to
* the Free Software Foundation, Inc., 51 Franklin Street - Fifth Floor,
* Boston, MA 02110-1301, USA.
*
* $Id$
*
*/
#ifndef __REAL_H__
#define __REAL_H__
#include <cmath>
#include <cassert>
#include <constants.h>
#include "consts.h"
* Doing so one is forced do think about compatibility instead of using std directly.
* Inline is optional at this moment
* \todo test if inline indeed performance improves (optimization flags should inline them anyway)
*/
namespace qucs {
\param[in] z angle in radians
\return cosine of z
*/
nr_double_t inline cos (const nr_double_t arg) {
return std::cos (arg);
}
\param[in] z angle in radians
\return sine of z
*/
nr_double_t inline sin (const nr_double_t arg) {
return std::sin (arg);
}
\param[in] z angle in radians
\return tangent of z
*/
nr_double_t inline tan (const nr_double_t arg) {
return std::tan (arg);
}
\param[in] z arc
\return arc cosine of z
*/
nr_double_t inline acos (const nr_double_t arg) {
return std::acos (arg);
}
\param[in] z arc
\return arc sine of z
*/
nr_double_t inline asin (const nr_double_t arg) {
return std::asin (arg);
}
\param[in] z arc
\return arc tangent of z
*/
nr_double_t inline atan (const nr_double_t arg) {
return std::atan (arg);
}
\param[in] x proportion of x-coordinate
\param[in] y proportion of y-coordinate
\return principal value of the arc tangent of y/x, expressed in radians.
*/
nr_double_t inline atan2 (const nr_double_t x, const nr_double_t y) {
return std::atan2 (x,y);
}
\param[in] z arc
\return hyperbolic cosine of z
*/
nr_double_t inline cosh (const nr_double_t arg) {
return std::cosh (arg);
}
\param[in] z arc
\return hyperbolic sine of z
*/
nr_double_t inline sinh (const nr_double_t arg) {
return std::sinh (arg);
}
\param[in] z arc
\return hyperbolic tangent of z
*/
nr_double_t inline tanh (const nr_double_t arg) {
return std::tanh (arg);
}
\param[in] z arc
\return arc hyperbolic cosine of z
*/
nr_double_t inline acosh (const nr_double_t arg) {
return std::acosh (arg);
}
\param[in] z arc
\return arc hyperbolic sine of z
*/
nr_double_t inline asinh (const nr_double_t arg)
{
return std::asinh (arg);
}
\param[in] z arc
\return arc hyperbolic tangent of z
*/
nr_double_t inline atanh (const nr_double_t arg)
{
return std::atanh (arg);
}
nr_double_t inline exp (const nr_double_t arg) {
return std::exp (arg);
}
nr_double_t inline log (const nr_double_t arg) {
return std::log (arg);
}
nr_double_t inline log10 (const nr_double_t arg) {
return std::log10 (arg);
}
nr_double_t inline pow (const nr_double_t a, const nr_double_t b)
{
return std::pow (a,b);
}
nr_double_t inline sqrt (const nr_double_t d) {
return std::sqrt (d);
}
The xhypot() function returns \f$\sqrt{a^2+b^2}\f$.
This is the length of the hypotenuse of a right-angle triangle with sides
of length a and b, or the distance
of the point (a,b) from the origin.
\param[in] a first length
\param[in] b second length
\return Euclidean distance from (0,0) to (a,b): \f$\sqrt{a^2+b^2}\f$
*/
nr_double_t inline xhypot (const nr_double_t a, const nr_double_t b) {
return std::hypot(a,b);
}
nr_double_t inline erf( nr_double_t arg) {
return std::erf (arg);
}
nr_double_t inline ceil( nr_double_t arg) {
return std::ceil(arg);
}
nr_double_t inline floor( nr_double_t arg) {
return std::floor(arg);
}
nr_double_t inline trunc( nr_double_t arg) {
return std::trunc(arg);
}
nr_double_t inline round( nr_double_t arg) {
return std::round(arg);
}
nr_double_t inline coth (const nr_double_t d) {
return 1.0 / std::tanh (d);
}
nr_double_t inline sech (const nr_double_t d) {
return (1.0 / std::cosh (d));
}
nr_double_t inline cosech (const nr_double_t d) {
return (1.0 / std::sinh (d));
}
\param[in] r Real number
\return \f$x^2\f$
*/
nr_double_t inline sqr (const nr_double_t r) {
return r * r;
}
unsigned int inline sqr (unsigned int r) {
return r * r;
}
\param[in] r Real number
\return \f$x^4\f$
*/
nr_double_t inline quadr (const nr_double_t r) {
return r * r * r * r;
}
Compute limited exponential:
\f[
\begin{cases}
\exp r & \text{if } r < \text{M\_LIMEXP} \\
\exp (\text{M\_LIMEXP})\left[1.0 + (r - \text{M\_LIMEXP})\right] &
\text{else}
\end{cases}
\f]
#limitexp is a constant
\param[in] r real number
\return limited exponential of r
\todo Change limexp(real) limexp(complex) file order
\todo Document #limitexp
*/
nr_double_t inline limexp (const nr_double_t r) {
return r < limitexp ? exp (r) : exp (limitexp) * (1.0 + (r - limitexp));
}
compute \f[
\mathrm{signum}\;d=
= \begin{cases}
O & \text{if } d=0 \\
1 & \text{if } d>0 \\
-1 & \text{if } d<0
\end{cases}
\f]
\param[in] d real number
\return signum of d
\todo Move near complex signum
*/
nr_double_t inline signum (const nr_double_t d) {
if (d == 0) return 0;
return d < 0 ? -1 : 1;
}
compute \f[
\mathrm{sign}\;d=
= \begin{cases}
1 & \text{if } d\ge 0 \\
-1 & \text{if } d<0
\end{cases}
\f]
\param[in] d real number
\return sign of d
\todo Move near complex sign
*/
nr_double_t inline sign (const nr_double_t d) {
return d < 0 ? -1 : 1;
}
Compute \f$\mathrm{sinc}\;d=\frac{\sin d}{d}\f$
\param[in] d real number
\return cardianal sinus of s
\todo Why not inline
*/
nr_double_t inline sinc (const nr_double_t d) {
if (d == 0) return 1;
return sin (d) / d;
}
Fix is nearest integral value in direction of 0,
\f[
\operatorname{fix} d=\begin{cases}
\operatorname{floor} d & \text{if } d > 0 \\
\operatorname{ceil} d & \text{else}
\end{cases}
\f]
\param[in] d real number
\return fixed complex number
\todo Why not inline?
*/
nr_double_t inline fix (const nr_double_t d) {
return (d > 0) ? floor (d) : ceil (d);
}
The Heaviside step function, H, also called unit step function,
is a discontinuous function whose value is zero for negative argument and
one for positive argument. For zero by convention, H(0)=0.5
\param[in] d Heaviside argument
\return Heaviside step
\todo Create Heaviside alias
*/
nr_double_t inline step (const nr_double_t d) {
nr_double_t x = d;
if (x < 0.0)
x = 0.0;
else if (x > 0.0)
x = 1.0;
else
x = 0.5;
return x;
}
*/
unsigned int inline
factorial (unsigned int n) {
unsigned int result = 1;
assert (n < 13);
if (n == 0)
return 1;
for (; n > 1; n--)
result = result * n;
return result;
}
\param[in] r Real number
\return Real part of r ie r
*/
nr_double_t inline real (const nr_double_t r) {
return r;
}
\param[in] r Real number
\return Imaginary part of r
*/
nr_double_t inline imag (const nr_double_t r) {
(void) r;
return 0.0;
}
Compute \f$r^2\f$
\param[in] r Real number
\return Euclidean norm of r
*/
nr_double_t inline norm (const nr_double_t r) {
return r * r;
}
\param[in] r Real number
\return Modulus of r
*/
nr_double_t inline abs (const nr_double_t r) {
return std::abs (r);
}
\param[in] r Real number
\return Conjugate of real r ie r
*/
nr_double_t inline conj (const nr_double_t r) {
return r;
}
* \brief rad2deg Convert radian to degree
* \param x input
* \return input in degree (x)*180/pi
*/
nr_double_t inline rad2deg (const nr_double_t x) {
return (180.0 * (x) / pi);
}
* \brief deg2rad Convert radian to degree
* \param x input
* \return input in radian (x)*pi/180
*/
nr_double_t inline deg2rad (const nr_double_t x) {
return (pi * (x) / 180.0);
}
static inline nr_double_t cubic (const nr_double_t x) { return (x * x * x); }
static inline nr_double_t celsius2kelvin (const nr_double_t x) { return (x - K); }
static inline nr_double_t kelvin2celsius (const nr_double_t x) { return (x + K); }
}
#endif