天天看點

GSL 系列 1 — 數學函數

文章目錄

    • 頭檔案
    • 數學常量
    • 無窮和非數
    • 初等函數
    • 小整數幂
    • 正負測試
    • 奇偶數測試
    • 最大最小函數
    • 浮點數的近似比較
    • 參考

頭檔案

gsl_math.h

數學常量

GSL 系列 1 — 數學函數

宏定義示例:

#ifndef M_E
#define M_E        2.71828182845904523536028747135      /* e */
#endif
           

無窮和非數

GSL_POSINF

: 正無窮

GSL_NEGINF

: 負無窮

GSL_NAN

:非數

宏定義:

// gsl_nan.h
#ifdef INFINITY
# define GSL_POSINF INFINITY
# define GSL_NEGINF (-INFINITY)
#elif defined(HUGE_VAL)
# define GSL_POSINF HUGE_VAL
# define GSL_NEGINF (-HUGE_VAL)
#else
# define GSL_POSINF (gsl_posinf())
# define GSL_NEGINF (gsl_neginf())
#endif

#ifdef NAN
# define GSL_NAN NAN
#elif defined(INFINITY)
# define GSL_NAN (INFINITY/INFINITY)
#else
# define GSL_NAN (gsl_nan())
#endif

//corecrt_math.h
#ifndef _HUGE_ENUF
    #define _HUGE_ENUF  1e+300  // _HUGE_ENUF*_HUGE_ENUF must overflow
#endif

#define INFINITY   ((float)(_HUGE_ENUF * _HUGE_ENUF))
#define HUGE_VAL   ((double)INFINITY)

#define NAN        ((float)(INFINITY * 0.0F))

//gsl_sys.h
double gsl_nan (void);
double gsl_posinf (void);
double gsl_neginf (void);
           

判斷函數:

//gsl_sys.h
int gsl_isnan (const double x); //非數傳回 1
int gsl_isinf (const double x); //正無窮傳回 1,負無窮傳回 -1,其他傳回 0
int gsl_finite (const double x); // 實數傳回 1,無窮和非數傳回 0
           

初等函數

// gsl_sys.h
double gsl_log1p(const double x); // log(1+x); x 小的時候較為精确
double gsl_expm1(const double x); // exp(x)-1; x 小的時候較為精确
double gsl_hypot(const double x, const double y); // sqrt(x^2 + y^2); 避免溢出
double gsl_hypot3(const double x, const double y, const double z); // sqrt(x^2+y^2+z^2); 避免溢出
double gsl_acosh(const double x); // arccosh(x) 
double gsl_asinh(const double x); // arcsinh(x)
double gsl_atanh(const double x); // arctanh(x)
double gsl_ldexp(const double x, const int e); // x*2^e;
double gsl_frexp(const double x, int * e); // x/2^e; x為0,f,e 都設為 0
           

小整數幂

// gsl_pow_int.h
INLINE_DECL double gsl_pow_2(const double x);
INLINE_DECL double gsl_pow_3(const double x);
INLINE_DECL double gsl_pow_4(const double x);
INLINE_DECL double gsl_pow_5(const double x);
INLINE_DECL double gsl_pow_6(const double x);
INLINE_DECL double gsl_pow_7(const double x);
INLINE_DECL double gsl_pow_8(const double x);
INLINE_DECL double gsl_pow_9(const double x);
/* HAVE_INLINE被定義時,以上函數使用内聯 */

double gsl_pow_int(double x, int n);
double gsl_pow_uint(double x, unsigned int n);
/* 該函數還有另一個版本,會計算數值誤差,gsl_sf_pow_int_e()

           

正負測試

GSL_SIGN(X)

: 大于等于 0 為 1,小于 0 為 -1

宏定義:

// gsl_math.h
#define GSL_SIGN(x)    ((x) >= 0.0 ? 1 : -1)
           

奇偶數測試

GSL_IS_ODD(n)

: 奇數傳回 1,偶數傳回 0

GSL_IS_EVEN(n)

: 偶數傳回 1,奇數傳回 0

宏定義:

// gsl_math.h
#define GSL_IS_ODD(n)  ((n) & 1)
#define GSL_IS_EVEN(n) (!(GSL_IS_ODD(n)))
           

最大最小函數

GSL_MAX(a,b)

: 傳回 a, b 的最大值

GSL_MIN(a,b)

: 傳回 a, b 的最小值

宏定義:

// gsl_minmax.h
#define GSL_MAX(a,b) ((a) > (b) ? (a) : (b))
#define GSL_MIN(a,b) ((a) < (b) ? (a) : (b))
// 以上兩個宏,還有函數版本 gsl_max, gsl_min
double gsl_max (double a, double b);
double gsl_min (double a, double b);
           

内聯函數版本(

HAVE_INLINE

定義的前提下):

// gsl_minmax.h
INLINE_FUN int GSL_MAX_INT (int a, int b);
INLINE_FUN int GSL_MIN_INT (int a, int b);
INLINE_FUN double GSL_MAX_DBL (double a, double b);
INLINE_FUN double GSL_MIN_DBL (double a, double b);
INLINE_FUN long double GSL_MAX_LDBL (long double a, long double b);
INLINE_FUN long double GSL_MIN_LDBL (long double a, long double b);

// 内聯版本實作示例
INLINE_FUN int
GSL_MAX_INT (int a, int b)
{
  return GSL_MAX (a, b);
}
//無内聯版本
#define GSL_MAX_INT(a,b)   GSL_MAX(a,b)
           

浮點數的近似比較

int gsl_fcmp (const double x1, const double x2, const double epsilon);
/* 
判斷 x, y 是否近似等于一個相對精度 epsilon, 
根據 frexp() 計算出一個間隔, 判斷 x, y 是否在間隔之内,
在,即傳回0,認為近似相等,否則,x < y 傳回 -1,x > y 傳回 + 1。
注意,比較的是相對精度,而不是兩者間隔接近 0 的程度。
基于 fcmp 實作。
*/
           

參考

https://www.gnu.org/software/gsl/doc/html/math.html

繼續閱讀