File: esl_stats.h

package info (click to toggle)
hmmer 3.2.1%2Bdfsg-1
  • links: PTS, VCS
  • area: main
  • in suites: buster
  • size: 23,380 kB
  • sloc: ansic: 119,305; perl: 8,791; sh: 3,266; makefile: 1,871; python: 598
file content (138 lines) | stat: -rw-r--r-- 4,292 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/* Foundation, miscellanea for the statistics modules.
 */
#ifndef eslSTATS_INCLUDED
#define eslSTATS_INCLUDED
#include "esl_config.h"

#include "easel.h"

/*****************************************************************
 * Splitting IEEE754 double-precision float into two uint32_t
 *****************************************************************
 *
 * Currently we only need these macros for one function,
 * esl_stats_erfc(). The Sun Microsystems erfc() code that we've
 * borrowed splits an IEEE754 double into two unsigned 32-bit
 * integers. It uses arcane trickery to deal with endianness at
 * runtime, using incantations like these:
 *    n0 = ((*(int*)&one)>>29)^1     0|1 = bigendian | littleendian
 *    hx = *(n0+(int*)&x);           get high word
 *    (1-n0+(int*)&z) = 0;           set low word
 * 
 * Not only is this arcane and dubious, static code checking (using
 * the clang/llvm checker) doesn't like it. I found an improvement
 * in a library called zenilib, at:
 *  http://www-personal.umich.edu/~bazald/l/api/math__private_8h_source.html
 *  
 * Here we do the same thing in an ANSI-respecting way using unions,
 * with endianness detected at compile time.
 * 
 * The zenilib code also appears to derive from (C) Sun Microsystems
 * code.
 *
 * SRE TODO: insert license/copyright info here
 */

#ifdef WORDS_BIGENDIAN    
typedef union 
{
 double val;
 struct {
   uint32_t msw;
   uint32_t lsw;
 } parts;
} esl_double_split_t;
#else /* else we're littleendian, such as Intel */
typedef union
{
 double val;
 struct {
   uint32_t lsw;
   uint32_t msw;
 } parts;
} esl_double_split_t;
#endif /*WORDS_BIGENDIAN*/

#define ESL_GET_WORDS(ix0, ix1, d) \
  do { \
    esl_double_split_t esltmp_ds;  \
    esltmp_ds.val = (d);           \
    (ix0) = esltmp_ds.parts.msw;   \
    (ix1) = esltmp_ds.parts.lsw;   \
  } while (0) 

#define ESL_GET_HIGHWORD(ix0, d)  \
  do { \
    esl_double_split_t esltmp_ds; \
    esltmp_ds.val = (d);          \
    (ix0) = esltmp_ds.parts.msw;  \
  } while (0)

#define ESL_GET_LOWWORD(ix0, d)   \
  do { \
    esl_double_split_t esltmp_ds; \
    esltmp_ds.val = (d);          \
    (ix0) = esltmp_ds.parts.lsw;  \
  } while (0)

#define ESL_SET_WORDS(d, ix0, ix1) \
   do { \
    esl_double_split_t esltmp_ds;  \
    esltmp_ds.parts.msw = (ix0);   \
    esltmp_ds.parts.lsw = (ix1);   \
    (d) = esltmp_ds.val;           \
   } while (0)

#define ESL_SET_HIGHWORD(d, ix0)  \
   do { \
    esl_double_split_t esltmp_ds; \
    esltmp_ds.val = (d);          \
    esltmp_ds.parts.msw = (ix0);  \
    (d) = esltmp_ds.val;          \
  } while (0)

#define ESL_SET_LOWWORD(d, ix1)   \
   do { \
    esl_double_split_t esltmp_ds; \
    esltmp_ds.val = (d);          \
    esltmp_ds.parts.lsw = (ix1);  \
    (d) = esltmp_ds.val;          \
  } while (0)


/*****************************************************************
 * Function declarations
 *****************************************************************/

/* 1. Summary statistics calculations */
extern int esl_stats_DMean(const double *x, int n, double *opt_mean, double *opt_var);
extern int esl_stats_FMean(const float  *x, int n, double *opt_mean, double *opt_var);
extern int esl_stats_IMean(const int    *x, int n, double *opt_mean, double *opt_var);

/* 2. Special functions */
extern int    esl_stats_LogGamma(double x, double *ret_answer);
extern int    esl_stats_Psi(double x, double *ret_answer);
extern int    esl_stats_IncompleteGamma(double a, double x, double *ret_pax, double *ret_qax);
extern double esl_stats_erfc(double x);

/* 3. Standard statistical tests */
extern int esl_stats_GTest(int ca, int na, int cb, int nb, double *ret_G, double *ret_P);
extern int esl_stats_ChiSquaredTest(int v, double x, double *ret_answer);

/* 4. Data fitting */
extern int esl_stats_LinearRegression(const double *x, const double *y, const double *sigma, int n,
				      double *opt_a,       double *opt_b,
				      double *opt_sigma_a, double *opt_sigma_b, double *opt_cov_ab,
				      double *opt_cc,      double *opt_Q);


/***************************************************************** 
 * Portability
 *****************************************************************/

#ifndef HAVE_ERFC
#define erfc(x)  esl_stats_erfc(x)
#endif

#endif /*eslSTATS_INCLUDED*/