r2rs-stats 0.1.1

Statistics programming for Rust based on R's stats package
Documentation
use ::libc;
extern "C" {
    #[no_mangle]
    fn dcgettext(
        __domainname: *const libc::c_char,
        __msgid: *const libc::c_char,
        __category: libc::c_int,
    ) -> *mut libc::c_char;

    #[no_mangle]
    fn unif_rand() -> 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 R_CheckUserInterrupt();
}
pub type Rboolean = libc::c_uint;
pub const TRUE: Rboolean = 1;
pub const FALSE: Rboolean = 0;
/* Algorithm AS 159 Applied Statistics (1981), vol. 30, no. 1
   original (C) Royal Statistical Society 1981

   Generate random two-way table with given marginal totals.

   Heavily pretty edited by Martin Maechler, Dec 2003
   use double precision for integer multiplication (against overflow);
*/
#[no_mangle]
pub unsafe extern "C" fn rcont2(
    mut nrow: *mut libc::c_int,
    mut ncol: *mut libc::c_int,
    mut nrowt: *mut libc::c_int,
    mut ncolt: *mut libc::c_int,
    mut ntotal: *mut libc::c_int,
    mut fact: *mut libc::c_double,
    mut jwork: *mut libc::c_int,
    mut matrix: *mut libc::c_int,
) {
    let mut j: libc::c_int = 0; /* -Wall */
    let mut l: libc::c_int = 0;
    let mut m: libc::c_int = 0;
    let mut ia: libc::c_int = 0;
    let mut ib: libc::c_int = 0;
    let mut ic: libc::c_int = 0;
    let mut jc: libc::c_int = 0;
    let mut id: libc::c_int = 0;
    let mut ie: libc::c_int = 0;
    let mut ii: libc::c_int = 0;
    let mut nll: libc::c_int = 0;
    let mut nlm: libc::c_int = 0;
    let mut nr_1: libc::c_int = 0;
    let mut nc_1: libc::c_int = 0;
    let mut x: libc::c_double = 0.;
    let mut y: libc::c_double = 0.;
    let mut dummy: libc::c_double = 0.;
    let mut sumprb: libc::c_double = 0.;
    let mut lsm: Rboolean = FALSE;
    let mut lsp: Rboolean = FALSE;
    nr_1 = *nrow - 1 as libc::c_int;
    nc_1 = *ncol - 1 as libc::c_int;
    ib = 0 as libc::c_int;
    /* Construct random matrix */
    j = 0 as libc::c_int;
    while j < nc_1 {
        *jwork.offset(j as isize) = *ncolt.offset(j as isize);
        j += 1
    }
    jc = *ntotal;
    l = 0 as libc::c_int;
    while l < nr_1 {
        /* -----  matrix[ l, * ] ----- */
        ia = *nrowt.offset(l as isize);
        ic = jc;
        /* last column in row l */
        jc -= ia; /* = n_tot - sum(nr[0:l]) */
        m = 0 as libc::c_int;
        while m < nc_1 {
            id = *jwork.offset(m as isize);
            ie = ic;
            ic -= id;
            ib = ie - ia;
            ii = ib - id;
            if ie == 0 as libc::c_int {
                /* Row [l,] is full, fill rest with zero entries */
                j = m;
                while j < nc_1 {
                    *matrix.offset((l + j * *nrow) as isize) = 0 as libc::c_int;
                    j += 1
                }
                ia = 0 as libc::c_int;
                break;
            } else {
                /* Generate pseudo-random number */
                dummy = unif_rand();
                's_129: loop {
                    /* Outer Loop */
                    /* Compute conditional expected value of MATRIX(L, M) */
                    nlm = (ia as libc::c_double * (id as libc::c_double / ie as libc::c_double)
                        + 0.5f64) as libc::c_int;
                    x = (*fact.offset(ia as isize)
                        + *fact.offset(ib as isize)
                        + *fact.offset(ic as isize)
                        + *fact.offset(id as isize)
                        - *fact.offset(ie as isize)
                        - *fact.offset(nlm as isize)
                        - *fact.offset((id - nlm) as isize)
                        - *fact.offset((ia - nlm) as isize)
                        - *fact.offset((ii + nlm) as isize))
                    .exp();
                    if x >= dummy {
                        break;
                    }
                    if x == 0.0f64 {
                        /* MM: I haven't seen this anymore */
                        error(
                            dcgettext(
                                b"stats\x00" as *const u8 as *const libc::c_char,
                                b"rcont2 [%d,%d]: exp underflow to 0; algorithm failure\x00"
                                    as *const u8
                                    as *const libc::c_char,
                                5 as libc::c_int,
                            ),
                            l,
                            m,
                        );
                    }
                    sumprb = x;
                    y = x;
                    nll = nlm;
                    loop {
                        /* Increment entry in row L, column M */
                        j = ((id - nlm) as libc::c_double * (ia - nlm) as libc::c_double)
                            as libc::c_int;
                        lsp = (j == 0 as libc::c_int) as libc::c_int as Rboolean;
                        if lsp as u64 == 0 {
                            nlm += 1;
                            x = x * j as libc::c_double
                                / (nlm as libc::c_double * (ii + nlm) as libc::c_double);
                            sumprb += x;
                            if sumprb >= dummy {
                                break 's_129;
                            }
                        }
                        loop {
                            R_CheckUserInterrupt();
                            /* Decrement entry in row L, column M */
                            j = (nll as libc::c_double * (ii + nll) as libc::c_double)
                                as libc::c_int;
                            lsm = (j == 0 as libc::c_int) as libc::c_int as Rboolean;
                            if lsm as u64 == 0 {
                                nll -= 1;
                                y = y * j as libc::c_double
                                    / ((id - nll) as libc::c_double * (ia - nll) as libc::c_double);
                                sumprb += y;
                                if sumprb >= dummy {
                                    nlm = nll;
                                    break 's_129;
                                } else if lsp as u64 == 0
                                /* to while (!lsp) */
                                /* else */
                                {
                                    break;
                                }
                            }
                            if !(lsm as u64 == 0) {
                                break;
                            }
                        }
                        if !(lsp as u64 == 0) {
                            break;
                        }
                    }
                    dummy = sumprb * unif_rand()
                }
                *matrix.offset((l + m * *nrow) as isize) = nlm;
                ia -= nlm;
                *jwork.offset(m as isize) -= nlm;
                m += 1
            }
        }
        *matrix.offset((l + nc_1 * *nrow) as isize) = ia;
        l += 1
    }
    /* Compute entries in last row of MATRIX */
    m = 0 as libc::c_int;
    while m < nc_1 {
        *matrix.offset((nr_1 + m * *nrow) as isize) = *jwork.offset(m as isize);
        m += 1
    }
    *matrix.offset((nr_1 + nc_1 * *nrow) as isize) =
        ib - *matrix.offset((nr_1 + (nc_1 - 1 as libc::c_int) * *nrow) as isize);
}