Rev 80166 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed
/** R : A Computer Language for Statistical Data Analysis* Copyright (C) 1998--2021 The R Core Team* Copyright (C) 1995--1997 Robert Gentleman and Ross Ihaka** This program 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 of the License, or* (at your option) any later version.** This program 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 program; if not, a copy is available at* https://www.R-project.org/Licenses/* distn == [DIST]ributio[N]s, i.e. probability distributions* ----- notably R's [dpq]<kind>() functions*/#ifdef HAVE_CONFIG_H#include <config.h>#endif#include <Defn.h>#include <Rmath.h>#include "statsR.h"#undef _#ifdef ENABLE_NLS#include <libintl.h>#define _(String) dgettext ("stats", String)#else#define _(String) (String)#endif/* interval at which to check interrupts *///#define NINTERRUPT 1000000#define R_MSG_NA _("NaNs produced")#define R_MSG_NONNUM_MATH _("Non-numeric argument to mathematical function")/* Mathematical Functions of Two Numeric Arguments (plus 1 int) */#define mod_iterate(n1,n2,i1,i2) for (i=i1=i2=0; i<n; \i1 = (++i1 == n1) ? 0 : i1,\i2 = (++i2 == n2) ? 0 : i2,\++i)#define SETUP_Math2 \na = XLENGTH(sa); \nb = XLENGTH(sb); \if ((na == 0) || (nb == 0)) { \PROTECT(sy = allocVector(REALSXP, 0)); \if (na == 0) SHALLOW_DUPLICATE_ATTRIB(sy, sa); \UNPROTECT(1); \return(sy); \} \n = (na < nb) ? nb : na; \PROTECT(sa = coerceVector(sa, REALSXP)); \PROTECT(sb = coerceVector(sb, REALSXP)); \PROTECT(sy = allocVector(REALSXP, n)); \a = REAL(sa); \b = REAL(sb); \y = REAL(sy); \naflag = 0#define FINISH_Math2 \if(naflag) warning(R_MSG_NA); \if (n == na) SHALLOW_DUPLICATE_ATTRIB(sy, sa); \else if (n == nb) SHALLOW_DUPLICATE_ATTRIB(sy, sb); \UNPROTECT(3)#define if_NA_Math2_set(y,a,b) \if (ISNA (a) || ISNA (b)) y = NA_REAL; \else if (ISNAN(a) || ISNAN(b)) y = R_NaN;static SEXP math2_1(SEXP sa, SEXP sb, SEXP sI, double (*f)(double, double, int)){SEXP sy;R_xlen_t i, ia, ib, n, na, nb;double ai, bi, *a, *b, *y;int m_opt;int naflag;if (!isNumeric(sa) || !isNumeric(sb))error(R_MSG_NONNUM_MATH);SETUP_Math2;m_opt = asInteger(sI);mod_iterate(na, nb, ia, ib) {// if ((i+1) % NINTERRUPT) R_CheckUserInterrupt();ai = a[ia];bi = b[ib];if_NA_Math2_set(y[i], ai, bi)else {y[i] = f(ai, bi, m_opt);if (ISNAN(y[i])) naflag = 1;}}FINISH_Math2;return sy;} /* math2_1() */static SEXP math2_2(SEXP sa, SEXP sb, SEXP sI1, SEXP sI2,double (*f)(double, double, int, int)){SEXP sy;R_xlen_t i, ia, ib, n, na, nb;double ai, bi, *a, *b, *y;int i_1, i_2;int naflag;if (!isNumeric(sa) || !isNumeric(sb))error(R_MSG_NONNUM_MATH);SETUP_Math2;i_1 = asInteger(sI1);i_2 = asInteger(sI2);mod_iterate(na, nb, ia, ib) {// if ((i+1) % NINTERRUPT) R_CheckUserInterrupt();ai = a[ia];bi = b[ib];if_NA_Math2_set(y[i], ai, bi)else {y[i] = f(ai, bi, i_1, i_2);if (ISNAN(y[i])) naflag = 1;}}FINISH_Math2;return sy;} /* math2_2() */#define DEFMATH2_1(name) \SEXP do_##name(SEXP sa, SEXP sb, SEXP sI) { \return math2_1(sa, sb, sI, name); \}DEFMATH2_1(dchisq)DEFMATH2_1(dexp)DEFMATH2_1(dgeom)DEFMATH2_1(dpois)DEFMATH2_1(dt)DEFMATH2_1(dsignrank)#define DEFMATH2_2(name) \SEXP do_##name(SEXP sa, SEXP sb, SEXP sI, SEXP sJ) { \return math2_2(sa, sb, sI, sJ, name); \}DEFMATH2_2(pchisq)DEFMATH2_2(qchisq)DEFMATH2_2(pexp)DEFMATH2_2(qexp)DEFMATH2_2(pgeom)DEFMATH2_2(qgeom)DEFMATH2_2(ppois)DEFMATH2_2(qpois)DEFMATH2_2(pt)DEFMATH2_2(qt)DEFMATH2_2(psignrank)DEFMATH2_2(qsignrank)/* Mathematical Functions of Three (Real) Arguments */#define if_NA_Math3_set(y,a,b,c) \if (ISNA (a) || ISNA (b)|| ISNA (c)) y = NA_REAL; \else if (ISNAN(a) || ISNAN(b)|| ISNAN(c)) y = R_NaN;#define mod_iterate3(n1,n2,n3,i1,i2,i3) for (i=i1=i2=i3=0; i<n; \i1 = (++i1==n1) ? 0 : i1, \i2 = (++i2==n2) ? 0 : i2, \i3 = (++i3==n3) ? 0 : i3, \++i)#define SETUP_Math3 \if (!isNumeric(sa) || !isNumeric(sb) || !isNumeric(sc)) \error(R_MSG_NONNUM_MATH); \\na = XLENGTH(sa); \nb = XLENGTH(sb); \nc = XLENGTH(sc); \if ((na == 0) || (nb == 0) || (nc == 0)) \return(allocVector(REALSXP, 0)); \n = na; \if (n < nb) n = nb; \if (n < nc) n = nc; \PROTECT(sa = coerceVector(sa, REALSXP)); \PROTECT(sb = coerceVector(sb, REALSXP)); \PROTECT(sc = coerceVector(sc, REALSXP)); \PROTECT(sy = allocVector(REALSXP, n)); \a = REAL(sa); \b = REAL(sb); \c = REAL(sc); \y = REAL(sy); \naflag = 0#define FINISH_Math3 \if(naflag) warning(R_MSG_NA); \\if (n == na) SHALLOW_DUPLICATE_ATTRIB(sy, sa); \else if (n == nb) SHALLOW_DUPLICATE_ATTRIB(sy, sb); \else if (n == nc) SHALLOW_DUPLICATE_ATTRIB(sy, sc); \UNPROTECT(4)static SEXP math3_1(SEXP sa, SEXP sb, SEXP sc, SEXP sI,double (*f)(double, double, double, int)){SEXP sy;R_xlen_t i, ia, ib, ic, n, na, nb, nc;double ai, bi, ci, *a, *b, *c, *y;int i_1;int naflag;SETUP_Math3;i_1 = asInteger(sI);mod_iterate3 (na, nb, nc, ia, ib, ic) {// if ((i+1) % NINTERRUPT) R_CheckUserInterrupt();ai = a[ia];bi = b[ib];ci = c[ic];if_NA_Math3_set(y[i], ai,bi,ci)else {y[i] = f(ai, bi, ci, i_1);if (ISNAN(y[i])) naflag = 1;}}FINISH_Math3;return sy;} /* math3_1 */static SEXP math3_2(SEXP sa, SEXP sb, SEXP sc, SEXP sI, SEXP sJ,double (*f)(double, double, double, int, int)){SEXP sy;R_xlen_t i, ia, ib, ic, n, na, nb, nc;double ai, bi, ci, *a, *b, *c, *y;int i_1,i_2;int naflag;SETUP_Math3;i_1 = asInteger(sI);i_2 = asInteger(sJ);mod_iterate3 (na, nb, nc, ia, ib, ic) {// if ((i+1) % NINTERRUPT) R_CheckUserInterrupt();ai = a[ia];bi = b[ib];ci = c[ic];if_NA_Math3_set(y[i], ai,bi,ci)else {y[i] = f(ai, bi, ci, i_1, i_2);if (ISNAN(y[i])) naflag = 1;}}FINISH_Math3;return sy;} /* math3_2 */#define DEFMATH3_1(name) \SEXP do_##name(SEXP sa, SEXP sb, SEXP sc, SEXP sI) { \return math3_1(sa, sb, sc, sI, name); \}DEFMATH3_1(dbeta)DEFMATH3_1(dbinom)DEFMATH3_1(dcauchy)DEFMATH3_1(df)DEFMATH3_1(dgamma)DEFMATH3_1(dlnorm)DEFMATH3_1(dlogis)DEFMATH3_1(dnbinom)DEFMATH3_1(dnbinom_mu)DEFMATH3_1(dnorm)DEFMATH3_1(dweibull)DEFMATH3_1(dunif)DEFMATH3_1(dnt)DEFMATH3_1(dnchisq)DEFMATH3_1(dwilcox)#define DEFMATH3_2(name) \SEXP do_##name(SEXP sa, SEXP sb, SEXP sc, SEXP sI, SEXP sJ) { \return math3_2(sa, sb, sc, sI, sJ, name); \}DEFMATH3_2(pbeta)DEFMATH3_2(qbeta)DEFMATH3_2(pbinom)DEFMATH3_2(qbinom)DEFMATH3_2(pcauchy)DEFMATH3_2(qcauchy)DEFMATH3_2(pf)DEFMATH3_2(qf)DEFMATH3_2(pgamma)DEFMATH3_2(qgamma)DEFMATH3_2(plnorm)DEFMATH3_2(qlnorm)DEFMATH3_2(plogis)DEFMATH3_2(qlogis)DEFMATH3_2(pnbinom)DEFMATH3_2(qnbinom)DEFMATH3_2(pnbinom_mu)DEFMATH3_2(qnbinom_mu)DEFMATH3_2(pnorm)DEFMATH3_2(qnorm)DEFMATH3_2(pweibull)DEFMATH3_2(qweibull)DEFMATH3_2(punif)DEFMATH3_2(qunif)DEFMATH3_2(pnt)DEFMATH3_2(qnt)DEFMATH3_2(pnchisq)DEFMATH3_2(qnchisq)DEFMATH3_2(pwilcox)DEFMATH3_2(qwilcox)/* Mathematical Functions of Four (Real) Arguments */#define if_NA_Math4_set(y,a,b,c,d) \if (ISNA (a)|| ISNA (b)|| ISNA (c)|| ISNA (d)) y = NA_REAL;\else if (ISNAN(a)|| ISNAN(b)|| ISNAN(c)|| ISNAN(d)) y = R_NaN;#define mod_iterate4(n1,n2,n3,n4,i1,i2,i3,i4) for (i=i1=i2=i3=i4=0; i<n; \i1 = (++i1==n1) ? 0 : i1, \i2 = (++i2==n2) ? 0 : i2, \i3 = (++i3==n3) ? 0 : i3, \i4 = (++i4==n4) ? 0 : i4, \++i)#define SETUP_Math4 \if(!isNumeric(sa)|| !isNumeric(sb)|| !isNumeric(sc)|| !isNumeric(sd))\error(R_MSG_NONNUM_MATH); \\na = XLENGTH(sa); \nb = XLENGTH(sb); \nc = XLENGTH(sc); \nd = XLENGTH(sd); \if ((na == 0) || (nb == 0) || (nc == 0) || (nd == 0)) \return(allocVector(REALSXP, 0)); \n = na; \if (n < nb) n = nb; \if (n < nc) n = nc; \if (n < nd) n = nd; \PROTECT(sa = coerceVector(sa, REALSXP)); \PROTECT(sb = coerceVector(sb, REALSXP)); \PROTECT(sc = coerceVector(sc, REALSXP)); \PROTECT(sd = coerceVector(sd, REALSXP)); \PROTECT(sy = allocVector(REALSXP, n)); \a = REAL(sa); \b = REAL(sb); \c = REAL(sc); \d = REAL(sd); \y = REAL(sy); \naflag = 0#define FINISH_Math4 \if(naflag) warning(R_MSG_NA); \\if (n == na) SHALLOW_DUPLICATE_ATTRIB(sy, sa); \else if (n == nb) SHALLOW_DUPLICATE_ATTRIB(sy, sb); \else if (n == nc) SHALLOW_DUPLICATE_ATTRIB(sy, sc); \else if (n == nd) SHALLOW_DUPLICATE_ATTRIB(sy, sd); \UNPROTECT(5)static SEXP math4_1(SEXP sa, SEXP sb, SEXP sc, SEXP sd, SEXP sI, double (*f)(double, double, double, double, int)){SEXP sy;R_xlen_t i, ia, ib, ic, id, n, na, nb, nc, nd;double ai, bi, ci, di, *a, *b, *c, *d, *y;int i_1;int naflag;SETUP_Math4;i_1 = asInteger(sI);mod_iterate4 (na, nb, nc, nd, ia, ib, ic, id) {// if ((i+1) % NINTERRUPT) R_CheckUserInterrupt();ai = a[ia];bi = b[ib];ci = c[ic];di = d[id];if_NA_Math4_set(y[i], ai,bi,ci,di)else {y[i] = f(ai, bi, ci, di, i_1);if (ISNAN(y[i])) naflag = 1;}}FINISH_Math4;return sy;} /* math4_1() */static SEXP math4_2(SEXP sa, SEXP sb, SEXP sc, SEXP sd, SEXP sI, SEXP sJ,double (*f)(double, double, double, double, int, int)){SEXP sy;R_xlen_t i, ia, ib, ic, id, n, na, nb, nc, nd;double ai, bi, ci, di, *a, *b, *c, *d, *y;int i_1, i_2;int naflag;SETUP_Math4;i_1 = asInteger(sI);i_2 = asInteger(sJ);mod_iterate4 (na, nb, nc, nd, ia, ib, ic, id) {// if ((i+1) % NINTERRUPT) R_CheckUserInterrupt();ai = a[ia];bi = b[ib];ci = c[ic];di = d[id];if_NA_Math4_set(y[i], ai,bi,ci,di)else {y[i] = f(ai, bi, ci, di, i_1, i_2);if (ISNAN(y[i])) naflag = 1;}}FINISH_Math4;return sy;} /* math4_2() */#define DEFMATH4_1(name) \SEXP do_##name(SEXP sa, SEXP sb, SEXP sc, SEXP sd, SEXP sI) { \return math4_1(sa, sb, sc, sd, sI, name); \}DEFMATH4_1(dhyper)DEFMATH4_1(dnbeta)DEFMATH4_1(dnf)#define DEFMATH4_2(name) \SEXP do_##name(SEXP sa, SEXP sb, SEXP sc, SEXP sd, SEXP sI, SEXP sJ) { \return math4_2(sa, sb, sc, sd, sI, sJ, name); \}DEFMATH4_2(phyper)DEFMATH4_2(qhyper)DEFMATH4_2(pnbeta)DEFMATH4_2(qnbeta)DEFMATH4_2(pnf)DEFMATH4_2(qnf)DEFMATH4_2(ptukey)DEFMATH4_2(qtukey)/* These are here to get them in the correct package *//* from src/nmath/wilcox.cSince 4.2.0 declared in Rmath.hextern void signrank_free(void);extern void wilcox_free(void);*/SEXP stats_signrank_free(void){signrank_free();return R_NilValue;}SEXP stats_wilcox_free(void){wilcox_free();return R_NilValue;}