more pre-def'd testing within file, slime-style.
[rclg.git] / rcl / math.lisp
blob6c981dcf913f2c613942ed5c18b50afe26538b6b
1 ;; Copyright (c) 2006-2007 Carlos Ungil
3 ;; Permission is hereby granted, free of charge, to any person obtaining
4 ;; a copy of this software and associated documentation files (the
5 ;; "Software"), to deal in the Software without restriction, including
6 ;; without limitation the rights to use, copy, modify, merge, publish,
7 ;; distribute, sublicense, and/or sell copies of the Software, and to
8 ;; permit persons to whom the Software is furnished to do so, subject to
9 ;; the following conditions:
11 ;; The above copyright notice and this permission notice shall be
12 ;; included in all copies or substantial portions of the Software.
14 ;; THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
15 ;; EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16 ;; MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
17 ;; NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
18 ;; LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
19 ;; OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
20 ;; WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
22 (in-package :rcl)
24 ;; Rmath.h should contain ALL headers from R's C code in `src/nmath'
25 ;; ------- such that ``the Math library'' can be used by simply
26 ;; #include <Rmath.h>
27 ;; and nothing else.
29 ;; R_VERSION_STRING "2.2.1"
31 ;; See http://cran.r-project.org/doc/manuals/R-exts.html#Distribution-functions
33 (cffi:defcfun "Rf_d1mach" :double (a :int))
34 (cffi:defcfun "Rf_i1mach" :double (a :int))
35 #-linux
36 (cffi:defcfun "Rf_gamma_cody" :double (a :double))
38 ;; search also for "undefined" aliens
40 ;; 6.3 Random number generation
42 ;; Random Number Generators
43 (cffi:defcfun "norm_rand" :double)
44 (cffi:defcfun "unif_rand" :double)
45 (cffi:defcfun "exp_rand" :double)
47 ;;(cffi:defcfun "set_seed" :void (a :int) (b :int))
48 ;;(cffi:defcfun "get_seed" :void (a :pointer) (b :pointer))
50 ;; 6.7.2 Mathematical functions
52 ;; Gamma and Related Functions
53 (cffi:defcfun "Rf_gammafn" :double (x :double))
54 (cffi:defcfun "Rf_lgammafn" :double (x :double))
55 (cffi:defcfun "Rf_digamma" :double (x :double))
56 (cffi:defcfun "Rf_trigamma" :double (x :double))
57 (cffi:defcfun "Rf_tetragamma" :double (x :double))
58 (cffi:defcfun "Rf_pentagamma" :double (x :double))
59 (cffi:defcfun "Rf_psigamma" :double (x :double) (deriv :double))
60 ;; The Gamma function, its natural logarithm and first four
61 ;; derivatives and the n-th derivative of Psi, the digamma function.
63 ;;; void dpsifn(double, int, int, int, double*, int*, int*);
65 (cffi:defcfun "Rf_beta" :double (a :double) (b :double))
66 (cffi:defcfun "Rf_lbeta" :double (a :double) (b :double))
67 ;; The (complete) Beta function and its natural logarithm.
69 (cffi:defcfun "Rf_choose" :double (a :double) (b :double))
70 (cffi:defcfun "Rf_lchoose" :double (a :double) (b :double))
71 ;; The number of combinations of k items chosen from from n and its
72 ;; natural logarithm. n and k are rounded to the nearest integer.
74 ;; Bessel Functions
75 (cffi:defcfun "Rf_bessel_i" :double (x :double) (nu :double) (expo :double))
76 (cffi:defcfun "Rf_bessel_j" :double (x :double) (nu :double))
77 (cffi:defcfun "Rf_bessel_k" :double (x :double) (nu :double) (expo :double))
78 (cffi:defcfun "Rf_bessel_y" :double (x :double) (nu :double))
79 ;; Bessel functions of types I, J, K and Y with index nu. For
80 ;; bessel_i and bessel_k there is the option to return
81 ;; exp(-x) I(x; nu) or exp(x) K(x; nu) if expo is 2.
82 ;; (Use expo == 1 for unscaled values.)
85 ;; 6.7.3 Numerical Utilities
87 ;;undefined in newer versions (post 2.1.1)
88 ;;(cffi:defcfun "R_log" :double (x :double))
90 (cffi:defcfun "R_pow" :double (x :double) (y :double))
91 (cffi:defcfun "R_pow_di" :double (x :double) (i :int))
92 ;; R_pow(x, y) and R_pow_di(x, i) compute x^y and x^i, respectively
93 ;; using R_FINITE checks and returning the proper result (the same as
94 ;; R) for the cases where x, y or i are 0 or missing or infinite or
95 ;; NaN.
97 (cffi:defcfun "Rf_pythag" :double (a :double) (b :double))
98 ;; pythag(a, b) computes sqrt(a^2 + b^2) without overflow or
99 ;; destructive underflow: for example it still works when both a and b
100 ;; are between 1e200 and 1e300 (in IEEE double precision).
102 ;;undefined
103 ;;(cffi:defcfun "Rlog1p" :double (x :double))
104 ;; = log(1+x) {care for small x}
105 ;; Computes log(1 + x) (log 1 plus x), accurately even for small x,
106 ;; i.e., |x| << 1.
107 ;; This may be provided by your platform, in which case it is not
108 ;; included in Rmath.h, but is (probably) in math.h which Rmath.h
109 ;; includes. For backwards compatibility with R versions prior to
110 ;; 1.5.0, the entry point Rf_log1p is still provided.
112 (cffi:defcfun "Rf_log1pmx" :double (x :double))
113 ;; Accurate log(1+x) - x, {care for small x} */
114 ;; Computes log(1 + x) - x (log 1 plus x minus x), accurately even for
115 ;; small x, i.e., |x| << 1.
117 (cffi:defcfun "expm1" :double (x :double))
118 ;; = exp(x)-1 {care for small x}
119 ;; Computes exp(x) - 1 (exp x minus 1), accurately even for small x,
120 ;; i.e., |x| << 1.
121 ;; This may be provided by your platform, in which case it is not
122 ;; included in Rmath.h, but is (probably) in math.h which Rmath.h
123 ;; includes.
125 (cffi:defcfun "Rf_lgamma1p" :double (x :double))
126 ;; accurate log(gamma(x+1)), small x (0 < x < 0.5)
127 ;; Computes log(gamma(x + 1)) (log(gamma(1 plus x))), accurately even
128 ;; for small x, i.e., 0 < x < 0.5.
130 (cffi:defcfun "Rf_logspace_add" :double (logx :double) (logy :double))
131 (cffi:defcfun "Rf_logspace_sub" :double (logx :double) (logy :double))
132 ;; Compute the log of a sum or difference from logs of terms, i.e.,
133 ;; “x + y” as log (exp(logx) + exp(logy)) and “x - y” as log
134 ;; (exp(logx) - exp(logy)), without causing overflows or throwing away
135 ;; too much accuracy.
137 (cffi:defcfun "Rf_imax2" :int (x :int) (y :int))
138 (cffi:defcfun "Rf_imin2" :int (x :int) (y :int))
139 (cffi:defcfun "Rf_fmax2" :double (x :double) (y :double))
140 (cffi:defcfun "Rf_fmin2" :double (x :double) (y :double))
141 ;; Return the larger (max) or smaller (min) of two integer or double
142 ;; numbers, respectively.
144 (cffi:defcfun "Rf_sign" :double (x :double))
145 ;; Compute the signum function, where sign(x) is 1, 0, or -1, when x
146 ;; is positive, 0, or negative, respectively.
148 (cffi:defcfun "Rf_fsign" :double (x :double) (y :double))
149 ;; Performs "transfer of sign" and is defined as |x| * sign(y).
151 (cffi:defcfun "Rf_fprec" :double (x :double) (digits :double))
152 ;; Returns the value of x rounded to digits decimal digits (after the
153 ;; decimal point).
155 (cffi:defcfun "Rf_fround" :double (x :double) (digits :double))
156 ;; Returns the value of x rounded to digits significant decimal
157 ;; digits.
159 (cffi:defcfun "Rf_ftrunc" :double (x :double))
160 ;; Returns the value of x truncated (to an integer value) towards zero.
163 ;; 6.7.1 Distribution functions
165 #|The routines used to calculate densities, cumulative distribution
166 functions and quantile functions for the standard statistical
167 distributions are available as entry points.
169 The arguments for the entry points follow the pattern of those for the
170 normal distribution:
171 double dnorm(double x, double mu, double sigma, int give_log);
172 double pnorm(double x, double mu, double sigma, int lower_tail, int give_log);
173 double qnorm(double p, double mu, double sigma, int lower_tail, int log_p);
174 double rnorm(double mu, double sigma);
176 That is, the first argument gives the position for the density and CDF
177 and probability for the quantile function, followed by the
178 distribution's parameters. Argument lower_tail should be TRUE (or 1)
179 for normal use, but can be FALSE (or 0) if the probability of the
180 upper tail is desired or specified.
182 Finally, give_log should be non-zero if the result is required on log
183 scale, and log_p should be non-zero if p has been specified on log
184 scale.
186 Note that you directly get the cumulative (or “integrated”) hazard
187 function, H(t) = - log(1 - F(t)), by using
188 - pdist(t, ..., /*lower_tail = */ FALSE, /* give_log = */ TRUE)
189 or shorter (and more cryptic)
190 - pdist(t, ..., 0, 1).
192 The random-variate generation routine rnorm returns one normal
193 variate. See Random numbers, for the protocol in using the
194 random-variate routines. Note that these argument sequences are (apart
195 from the names and that rnorm has no n) exactly the same as the
196 corresponding R functions of the same name, so the documentation of
197 the R functions can be used.
199 For reference, the following table gives the basic name (to be
200 prefixed by `d', `p', `q' or `r' apart from the exceptions noted) and
201 distribution-specific arguments for the complete set of distributions.
205 Entries marked with an asterisk only have `p' and `q' functions
206 available, and none of the non-central distributions have `r'
207 functions. After a call to dwilcox, pwilcox or qwilcox the function
208 wilcox_free() should be called, and similarly for the signed rank
209 functions.
211 The argument names are not all quite the same as the R ones.
214 ;; Normal Distribution
215 ;; normal norm mu, sigma
216 (cffi:defcfun "Rf_dnorm4" :double (x :double) (mu :double) (sigma :double) (give-log :int))
217 (cffi:defcfun "Rf_pnorm5" :double (x :double) (mu :double) (sigma :double) (lower-tail :int) (give-log :int))
218 (cffi:defcfun "Rf_qnorm5" :double (p :double) (mu :double) (sigma :double) (lower-tail :int) (log-p :int))
219 (cffi:defcfun "Rf_rnorm" :double (mu :double) (sigma :double))
220 (cffi:defcfun "Rf_pnorm_both" :void (x :double) (cum :pointer) (ccum :pointer) (lower-tail :int) (log-p :int))
222 ;; Uniform Distribution
223 ;; unif a, b
224 (cffi:defcfun "Rf_dunif" :double (x :double) (a :double) (b :double) (give-log :int))
225 (cffi:defcfun "Rf_punif" :double (x :double) (a :double) (b :double) (lower-tail :int) (give-log :int))
226 (cffi:defcfun "Rf_qunif" :double (p :double) (a :double) (b :double) (lower-tail :int) (log-p :int))
227 (cffi:defcfun "Rf_runif" :double (a :double) (b :double))
229 ;; Gamma Distribution
230 ;; gamma shape, scale
231 (cffi:defcfun "Rf_dgamma" :double (x :double) (shape :double) (scale :double) (give-log :int))
232 (cffi:defcfun "Rf_pgamma" :double (x :double) (shape :double) (scale :double) (lower-tail :int) (give-log :int))
233 (cffi:defcfun "Rf_qgamma" :double (p :double) (shape :double) (scale :double) (lower-tail :int) (log-p :int))
234 (cffi:defcfun "Rf_rgamma" :double (shape :double) (scale :double))
236 ;; Beta Distribution
237 ;; beta a, b
238 (cffi:defcfun "Rf_dbeta" :double (x :double) (a :double) (b :double) (give-log :int))
239 (cffi:defcfun "Rf_pbeta" :double (x :double) (a :double) (b :double) (lower-tail :int) (give-log :int))
240 (cffi:defcfun "Rf_qbeta" :double (p :double) (a :double) (b :double) (lower-tail :int) (log-p :int))
241 (cffi:defcfun "Rf_rbeta" :double (a :double) (b :double))
242 #-linux
243 (cffi:defcfun "Rf_pbeta_raw" :double (x :double) (a :double) (b :double) (lower-tail :int))
245 ;; Lognormal Distribution
246 ;; lnorm logmean, logsd
247 (cffi:defcfun "Rf_dlnorm" :double (x :double) (logmean :double) (logsd :double) (give-log :int))
248 (cffi:defcfun "Rf_plnorm" :double (x :double) (logmean :double) (logsd :double) (lower-tail :int) (give-log :int))
249 (cffi:defcfun "Rf_qlnorm" :double (p :double) (logmean :double) (logsd :double) (lower-tail :int) (log-p :int))
250 (cffi:defcfun "Rf_rlnorm" :double (logmean :double) (logsd :double))
252 ;; Chi-squared Distribution
253 ;; chisq df
254 (cffi:defcfun "Rf_dchisq" :double (x :double) (df :double) (give-log :int))
255 (cffi:defcfun "Rf_pchisq" :double (x :double) (df :double) (lower-tail :int) (give-log :int))
256 (cffi:defcfun "Rf_qchisq" :double (p :double) (df :double) (lower-tail :int) (log-p :int))
257 (cffi:defcfun "Rf_rchisq" :double (df :double))
258 #-linux
259 (cffi:defcfun "Rf_qchisq_appr" :double (p :double) (df :double) (lgamma :double) (lower-tail :int) (log-p :int) (tol :double))
261 ;; Non-central Chi-squared Distribution
262 ;; nchisq df, lambda
263 (cffi:defcfun "Rf_dnchisq" :double (x :double) (df :double) (lambda :double) (give-log :int))
264 (cffi:defcfun "Rf_pnchisq" :double (x :double) (df :double) (lambda :double) (lower-tail :int) (give-log :int))
265 (cffi:defcfun "Rf_qnchisq" :double (p :double) (df :double) (lambda :double) (lower-tail :int) (log-p :int))
266 (cffi:defcfun "Rf_rnchisq" :double (df :double) (lambda :double))
268 ;; F Distibution
269 ;; f n1, n2
270 (cffi:defcfun "Rf_df" :double (x :double) (n1 :double) (n2 :double) (give-log :int))
271 (cffi:defcfun "Rf_pf" :double (x :double) (n1 :double) (n2 :double) (lower-tail :int) (give-log :int))
272 (cffi:defcfun "Rf_qf" :double (p :double) (n1 :double) (n2 :double) (lower-tail :int) (log-p :int))
273 (cffi:defcfun "Rf_rf" :double (n1 :double) (n2 :double))
275 ;; Student t Distibution
276 ;; t n
277 (cffi:defcfun "Rf_dt" :double (x :double) (n :double) (give-log :int))
278 (cffi:defcfun "Rf_pt" :double (x :double) (n :double) (lower-tail :int) (give-log :int))
279 (cffi:defcfun "Rf_qt" :double (p :double) (n :double) (lower-tail :int) (log-p :int))
280 (cffi:defcfun "Rf_rt" :double (n :double))
282 ;; Binomial Distribution
283 ;; binom n, p
284 (cffi:defcfun "Rf_dbinom" :double (x :double) (n :double) (p :double) (give-log :int))
285 (cffi:defcfun "Rf_pbinom" :double (x :double) (n :double) (p :double) (lower-tail :int) (give-log :int))
286 (cffi:defcfun "Rf_qbinom" :double (p :double) (n :double) (pp :double) (lower-tail :int) (log-p :int))
287 (cffi:defcfun "Rf_rbinom" :double (n :double) (p :double))
289 ;; Multinomial Distribution
291 ;; void rmultinom(int, double*, int, int*);
293 ;; Cauchy Distribution
294 ;;cauchy location, scale
295 (cffi:defcfun "Rf_dcauchy" :double (x :double) (location :double) (scale :double) (give-log :int))
296 (cffi:defcfun "Rf_pcauchy" :double (x :double) (location :double) (scale :double) (lower-tail :int) (give-log :int))
297 (cffi:defcfun "Rf_qcauchy" :double (p :double) (location :double) (scale :double) (lower-tail :int) (log-p :int))
298 (cffi:defcfun "Rf_rcauchy" :double (location :double) (scale :double))
300 ;; Exponential Distribution
301 ;; exp scale
302 (cffi:defcfun "Rf_dexp" :double (x :double) (scale :double) (give-log :int))
303 (cffi:defcfun "Rf_pexp" :double (x :double) (scale :double) (lower-tail :int) (give-log :int))
304 (cffi:defcfun "Rf_qexp" :double (p :double) (scale :double) (lower-tail :int) (log-p :int))
305 (cffi:defcfun "Rf_rexp" :double (scale :double))
307 ;; Geometric Distribution
308 ;; geom p
309 (cffi:defcfun "Rf_dgeom" :double (x :double) (p :double) (give-log :int))
310 (cffi:defcfun "Rf_pgeom" :double (x :double) (p :double) (lower-tail :int) (give-log :int))
311 (cffi:defcfun "Rf_qgeom" :double (p :double) (pp :double) (lower-tail :int) (log-p :int))
312 (cffi:defcfun "Rf_rgeom" :double (p :double))
314 ;; Hypergeometric Distibution
315 ;; hyper NR, NB, n
316 (cffi:defcfun "Rf_dhyper" :double (x :double) (nr :double) (nb :double) (n :double) (give-log :int))
317 (cffi:defcfun "Rf_phyper" :double (x :double) (nr :double) (nb :double) (n :double) (lower-tail :int) (give-log :int))
318 (cffi:defcfun "Rf_qhyper" :double (p :double) (nr :double) (nb :double) (n :double) (lower-tail :int) (log-p :int))
319 (cffi:defcfun "Rf_rhyper" :double (nr :double) (nb :double) (n :double))
321 ;; Negative Binomial Distribution
322 ;; nbinom n, p
323 (cffi:defcfun "Rf_dnbinom" :double (x :double) (n :double) (p :double) (give-log :int))
324 (cffi:defcfun "Rf_pnbinom" :double (x :double) (n :double) (p :double) (lower-tail :int) (give-log :int))
325 (cffi:defcfun "Rf_qnbinom" :double (p :double) (n :double) (pp :double) (lower-tail :int) (log-p :int))
326 (cffi:defcfun "Rf_rnbinom" :double (n :double) (p :double))
328 ;; Poisson Distribution
329 ;; pois lambda
330 (cffi:defcfun "Rf_dpois" :double (x :double) (lambda :double) (give-log :int))
331 (cffi:defcfun "Rf_ppois" :double (x :double) (lambda :double) (lower-tail :int) (give-log :int))
332 (cffi:defcfun "Rf_qpois" :double (p :double) (lambda :double) (lower-tail :int) (log-p :int))
333 (cffi:defcfun "Rf_rpois" :double (lambdax :double))
335 ;; Weibull Distribution
336 ;; weibull shape, scale
337 (cffi:defcfun "Rf_dweibull" :double (x :double) (shape :double) (scale :double) (give-log :int))
338 (cffi:defcfun "Rf_pweibull" :double (x :double) (shape :double) (scale :double) (lower-tail :int) (give-log :int))
339 (cffi:defcfun "Rf_qweibull" :double (p :double) (shape :double) (scale :double) (lower-tail :int) (log-p :int))
340 (cffi:defcfun "Rf_rweibull" :double (shape :double) (scale :double))
342 ;; Logistic Distribution
343 ;; logis location, scale
344 (cffi:defcfun "Rf_dlogis" :double (x :double) (location :double) (scale :double) (give-log :int))
345 (cffi:defcfun "Rf_plogis" :double (x :double) (location :double) (scale :double) (lower-tail :int) (give-log :int))
346 (cffi:defcfun "Rf_qlogis" :double (p :double) (location :double) (scale :double) (lower-tail :int) (log-p :int))
347 (cffi:defcfun "Rf_rlogis" :double (location :double) (scale :double))
349 ;; Non-central Beta Distribution
350 ;; nbeta a, b, lambda
351 (cffi:defcfun "Rf_dnbeta" :double (x :double) (a :double) (b :double) (lambda :double) (give-log :int))
352 (cffi:defcfun "Rf_pnbeta" :double (x :double) (a :double) (b :double) (lambda :double) (lower-tail :int) (give-log :int))
353 ;;undefined
354 ;;(cffi:defcfun "Rf_qnbeta" :double (p :double) (a :double) (b :double) (lambda :double) (lower-tail :int) (log-p :int))
355 ;;(cffi:defcfun "Rf_rnbeta" :double (a :double) (b :double) (lambda :double))
357 ;; Non-central F Distribution
358 ;; nf (*) n1, n2, ncp
359 (cffi:defcfun "Rf_dnf" :double (x :double) (n1 :double) (n2 :double) (ncp :double) (give-log :int))
360 (cffi:defcfun "Rf_pnf" :double (x :double) (n1 :double) (n2 :double) (ncp :double) (lower-tail :int) (give-log :int))
361 (cffi:defcfun "Rf_qnf" :double (p :double) (n1 :double) (n2 :double) (ncp :double) (lower-tail :int) (log-p :int))
363 ;; Non-central Student t Distribution
364 ;; nt df, delta
365 (cffi:defcfun "Rf_dnt" :double (x :double) (df :double) (delta :double) (give-log :int))
366 (cffi:defcfun "Rf_pnt" :double (x :double) (df :double) (delta :double) (lower-tail :int) (give-log :int))
367 (cffi:defcfun "Rf_qnt" :double (p :double) (df :double) (delta :double) (lower-tail :int) (log-p :int))
369 ;; Studentized Range Distribution
370 ;; tukey (*) rr, cc, df
371 (cffi:defcfun "Rf_ptukey" :double (x :double) (rr :double) (cc :double) (df :double) (lower-tail :int) (give-log :int))
372 (cffi:defcfun "Rf_qtukey" :double (p :double) (rr :double) (cc :double) (df :double) (lower-tail :int) (log-p :int))
374 ;; Wilcoxon Rank Sum Distribution
375 ;; wilcox m, n
376 (cffi:defcfun "Rf_dwilcox" :double (x :double) (m :double) (n :double) (give-log :int))
377 (cffi:defcfun "Rf_pwilcox" :double (x :double) (m :double) (n :double) (lower-tail :int) (give-log :int))
378 (cffi:defcfun "Rf_qwilcox" :double (p :double) (m :double) (n :double) (lower-tail :int) (log-p :int))
379 (cffi:defcfun "Rf_rwilcox" :double (m :double) (n :double))
381 ;; Wilcoxon Signed Rank Distribution
382 ;; signrank n
383 (cffi:defcfun "Rf_dsignrank" :double (x :double) (n :double) (give-log :int))
384 (cffi:defcfun "Rf_psignrank" :double (x :double) (n :double) (lower-tail :int) (give-log :int))
385 (cffi:defcfun "Rf_qsignrank" :double (p :double) (n :double) (lower-tail :int) (log-p :int))
386 (cffi:defcfun "Rf_rsignrank" :double (n :double))