r2rs-stats 0.1.1

Statistics programming for Rust based on R's stats package
Documentation
use crate::sexprec::{SEXP, SEXPTYPE};
use ::libc;
extern "C" {
    /*
     *  R : A Computer Language for Statistical Data Analysis
     *  Copyright (C) 1995, 1996  Robert Gentleman and Ross Ihaka
     *  Copyright (C) 1998--2016  The R Core Team.
     *
     *  This header file is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU Lesser General Public License as published by
     *  the Free Software Foundation; either version 2.1 of the License, or
     *  (at your option) any later version.
     *
     *  This file is part of R. R is distributed under the terms of the
     *  GNU General Public License, either Version 2, June 1991 or Version 3,
     *  June 2007. See doc/COPYRIGHTS for details of the copyright status of R.
     *
     *  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 Lesser General Public License for more details.
     *
     *  You should have received a copy of the GNU Lesser General Public License
     *  along with this program; if not, a copy is available at
     *  https://www.R-project.org/Licenses/
     */
    /* Included by R.h: API */
    /*
       This used to define _BSD_SOURCE to make declarations of isfinite
       and isnan visible in glibc.  But that was deprecated in glibc 2.20,
       and --std=c99 suffices nowadays.
    */
    /* needed for isnan and isfinite, neither of which are used under C++ */
    /* implementation of these : ../../main/arithmetic.c */
    #[no_mangle]
    static mut R_NaN: libc::c_double;
    /*
     *  R : A Computer Language for Statistical Data Analysis
     *  Copyright (C) 1998-2005   The R Core Team
     *
     *  This header file is free software; you can redistribute it and/or modify
     *  it under the terms of the GNU Lesser General Public License as published by
     *  the Free Software Foundation; either version 2.1 of the License, or
     *  (at your option) any later version.
     *
     *  This file is part of R. R is distributed under the terms of the
     *  GNU General Public License, either Version 2, June 1991 or Version 3,
     *  June 2007. See doc/COPYRIGHTS for details of the copyright status of R.
     *
     *  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 Lesser General Public License for more details.
     *
     *  You should have received a copy of the GNU Lesser General Public License
     *  along with this program; if not, a copy is available at
     *  https://www.R-project.org/Licenses/
     */
    /* Included by R.h: API */
    #[no_mangle]
    fn error(_: *const libc::c_char, _: ...) -> !;
    #[no_mangle]
    fn XLENGTH(x: SEXP) -> R_xlen_t;
    #[no_mangle]
    fn REAL(x: SEXP) -> *mut libc::c_double;
    #[no_mangle]
    static mut R_NilValue: SEXP;
    #[no_mangle]
    fn coerceVector(_: SEXP, _: SEXPTYPE) -> SEXP;
    #[no_mangle]
    fn asInteger(x: SEXP) -> libc::c_int;
    #[no_mangle]
    fn asReal(x: SEXP) -> libc::c_double;
    #[no_mangle]
    fn allocVector(_: SEXPTYPE, _: R_xlen_t) -> SEXP;
    #[no_mangle]
    fn protect(_: SEXP) -> SEXP;
    #[no_mangle]
    fn unprotect(_: libc::c_int);
    #[no_mangle]
    fn dcgettext(
        __domainname: *const libc::c_char,
        __msgid: *const libc::c_char,
        __category: libc::c_int,
    ) -> *mut libc::c_char;
}
pub type ptrdiff_t = libc::c_long;
pub type R_xlen_t = ptrdiff_t;
#[derive(Copy, Clone)]
#[repr(C)]
pub struct appr_meth {
    pub ylow: libc::c_double,
    pub yhigh: libc::c_double,
    pub f1: libc::c_double,
    pub f2: libc::c_double,
    pub kind: libc::c_int,
}
unsafe extern "C" fn approx1(
    mut v: libc::c_double,
    mut x: *mut libc::c_double,
    mut y: *mut libc::c_double,
    mut n: R_xlen_t,
    mut Meth: *mut appr_meth,
) -> libc::c_double {
    /* Approximate  y(v),  given (x,y)[i], i = 0,..,n-1 */
    if n == 0 {
        return R_NaN;
    }
    let mut i: R_xlen_t = 0 as libc::c_int as R_xlen_t;
    let mut j: R_xlen_t = n - 1 as libc::c_int as libc::c_long;
    /* handle out-of-domain points */
    if v < *x.offset(i as isize) {
        return (*Meth).ylow;
    }
    if v > *x.offset(j as isize) {
        return (*Meth).yhigh;
    }
    /* find the correct interval by bisection */
    while i < j - 1 as libc::c_int as libc::c_long {
        /* x[i] <= v <= x[j] */
        let mut ij: R_xlen_t = (i + j) / 2 as libc::c_int as libc::c_long;
        /* i+1 <= ij <= j-1 */
        if v < *x.offset(ij as isize) {
            j = ij
        } else {
            i = ij
        }
    }
    /* provably have i == j-1 */
    /* interpolation */
    if v == *x.offset(j as isize) {
        return *y.offset(j as isize);
    }
    if v == *x.offset(i as isize) {
        return *y.offset(i as isize);
    }
    /* impossible: if(x[j] == x[i]) return y[i]; */
    if (*Meth).kind == 1 as libc::c_int {
        /* linear */
        return *y.offset(i as isize)
            + (*y.offset(j as isize) - *y.offset(i as isize))
                * ((v - *x.offset(i as isize)) / (*x.offset(j as isize) - *x.offset(i as isize)));
    } else {
        /* 2 : constant */
        return (if (*Meth).f1 != 0.0f64 {
            (*y.offset(i as isize)) * (*Meth).f1
        } else {
            0.0f64
        }) + (if (*Meth).f2 != 0.0f64 {
            (*y.offset(j as isize)) * (*Meth).f2
        } else {
            0.0f64
        });
    };
}
/* approx1() */
/* Testing done only once - in a separate function */
unsafe extern "C" fn R_approxtest(
    mut x: *mut libc::c_double,
    mut y: *mut libc::c_double,
    mut nxy: R_xlen_t,
    mut method: libc::c_int,
    mut f: libc::c_double,
) {
    match method {
        1 => {}
        2 => {
            /* constant */
            if f.is_finite() as i32 == 0
                || f < 0 as libc::c_int as libc::c_double
                || f > 1 as libc::c_int as libc::c_double
            {
                error(dcgettext(
                    b"stats\x00" as *const u8 as *const libc::c_char,
                    b"approx(): invalid f value\x00" as *const u8 as *const libc::c_char,
                    5 as libc::c_int,
                ));
            }
        }
        _ => {
            error(dcgettext(
                b"stats\x00" as *const u8 as *const libc::c_char,
                b"approx(): invalid interpolation method\x00" as *const u8 as *const libc::c_char,
                5 as libc::c_int,
            ));
        }
    }
    /* check interpolation method */
    let mut i: R_xlen_t = 0 as libc::c_int as R_xlen_t;
    while i < nxy {
        if (*x.offset(i as isize)).is_nan() as i32 != 0 as libc::c_int
            || (*y.offset(i as isize)).is_nan() as i32 != 0 as libc::c_int
        {
            error(dcgettext(
                b"stats\x00" as *const u8 as *const libc::c_char,
                b"approx(): attempted to interpolate NA values\x00" as *const u8
                    as *const libc::c_char,
                5 as libc::c_int,
            ));
        }
        i += 1
    }
}
/* R Frontend for Linear and Constant Interpolation, no testing */
unsafe extern "C" fn R_approxfun(
    mut x: *mut libc::c_double,
    mut y: *mut libc::c_double,
    mut nxy: R_xlen_t,
    mut xout: *mut libc::c_double,
    mut yout: *mut libc::c_double,
    mut nout: R_xlen_t,
    mut method: libc::c_int,
    mut yleft: libc::c_double,
    mut yright: libc::c_double,
    mut f: libc::c_double,
) {
    let mut M: appr_meth = {
        let mut init = appr_meth {
            ylow: 0.0f64,
            yhigh: 0.0f64,
            f1: 0.0f64,
            f2: 0.0f64,
            kind: 0 as libc::c_int,
        }; /* -Wall */
        init
    };
    M.f2 = f;
    M.f1 = 1 as libc::c_int as libc::c_double - f;
    M.kind = method;
    M.ylow = yleft;
    M.yhigh = yright;
    let mut i: R_xlen_t = 0 as libc::c_int as R_xlen_t;
    while i < nout {
        *yout.offset(i as isize) = if (*xout.offset(i as isize)).is_nan() as i32 != 0 as libc::c_int
        {
            *xout.offset(i as isize)
        } else {
            approx1(*xout.offset(i as isize), x, y, nxy, &mut M)
        };
        i += 1
    }
}
#[no_mangle]
pub unsafe extern "C" fn ApproxTest(
    mut x: SEXP,
    mut y: SEXP,
    mut method: SEXP,
    mut sf: SEXP,
) -> SEXP {
    let mut nx: R_xlen_t = XLENGTH(x);
    let mut m: libc::c_int = asInteger(method);
    let mut f: libc::c_double = asReal(sf);
    R_approxtest(REAL(x), REAL(y), nx, m, f);
    return R_NilValue;
}
#[no_mangle]
pub unsafe extern "C" fn Approx(
    mut x: SEXP,
    mut y: SEXP,
    mut v: SEXP,
    mut method: SEXP,
    mut yleft: SEXP,
    mut yright: SEXP,
    mut sf: SEXP,
) -> SEXP {
    let mut xout: SEXP = protect(coerceVector(v, 14 as libc::c_int as SEXPTYPE));
    let mut nx: R_xlen_t = XLENGTH(x);
    let mut nout: R_xlen_t = XLENGTH(xout);
    let mut yout: SEXP = protect(allocVector(14 as libc::c_int as SEXPTYPE, nout));
    R_approxfun(
        REAL(x),
        REAL(y),
        nx,
        REAL(xout),
        REAL(yout),
        nout,
        asInteger(method),
        asReal(yleft),
        asReal(yright),
        asReal(sf),
    );
    unprotect(2 as libc::c_int);
    return yout;
}