r2rs-stats 0.1.1

Statistics programming for Rust based on R's stats package
Documentation
use crate::sexprec::{SEXP, SEXPREC, SEXPTYPE};
use ::libc;
extern "C" {
    #[no_mangle]
    fn R_alloc(_: size_t, _: libc::c_int) -> *mut libc::c_char;
    #[no_mangle]
    fn LENGTH(x: SEXP) -> libc::c_int;
    #[no_mangle]
    fn INTEGER(x: SEXP) -> *mut libc::c_int;
    #[no_mangle]
    fn coerceVector(_: SEXP, _: SEXPTYPE) -> SEXP;
    #[no_mangle]
    fn allocMatrix(_: SEXPTYPE, _: libc::c_int, _: libc::c_int) -> SEXP;
    #[no_mangle]
    fn nrows(_: SEXP) -> libc::c_int;
    #[no_mangle]
    fn protect(_: SEXP) -> SEXP;
    #[no_mangle]
    fn unprotect(_: libc::c_int);
}
pub type Rboolean = libc::c_uint;
pub const TRUE: Rboolean = 1;
pub const FALSE: Rboolean = 0;
pub type size_t = libc::c_ulong;
/*
*  R : A Computer Language for Statistical Data Analysis

*  Copyright (C) 1999-2014   The R Core Team
*
*  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/.
*/
#[no_mangle]
pub unsafe extern "C" fn cutree(mut merge: SEXP, mut which: SEXP) -> SEXP {
    /* Return grouping vector from cutting a (binary) (cluster) tree
     * into which[j] groups.
     * merge = (n-1) x 2  matrix, described in help(hclust) */
    let mut ans: SEXP = 0 as *mut SEXPREC;
    let mut n: libc::c_int = 0;
    let mut k: libc::c_int = 0;
    let mut l: libc::c_int = 0;
    let mut nclust: libc::c_int = 0;
    let mut m1: libc::c_int = 0;
    let mut m2: libc::c_int = 0;
    let mut j: libc::c_int = 0;
    let mut mm: libc::c_int = 0 as libc::c_int;
    let mut found_j: Rboolean = FALSE;
    let mut sing: *mut Rboolean = 0 as *mut Rboolean;
    let mut m_nr: *mut libc::c_int = 0 as *mut libc::c_int;
    let mut z: *mut libc::c_int = 0 as *mut libc::c_int;
    let mut i_merge: *mut libc::c_int = 0 as *mut libc::c_int;
    let mut i_which: *mut libc::c_int = 0 as *mut libc::c_int;
    let mut i_ans: *mut libc::c_int = 0 as *mut libc::c_int;
    merge = coerceVector(merge, 13 as libc::c_int as SEXPTYPE);
    protect(merge);
    i_merge = INTEGER(merge);
    which = coerceVector(which, 13 as libc::c_int as SEXPTYPE);
    protect(which);
    i_which = INTEGER(which);
    n = nrows(merge) + 1 as libc::c_int;
    /* using 1-based indices ==> "--" */
    sing = R_alloc(
        n as size_t,
        ::std::mem::size_of::<Rboolean>() as libc::c_ulong as libc::c_int,
    ) as *mut Rboolean; /* is k-th obs. still alone in cluster ? */
    sing = sing.offset(-1);
    m_nr = R_alloc(
        n as size_t,
        ::std::mem::size_of::<libc::c_int>() as libc::c_ulong as libc::c_int,
    ) as *mut libc::c_int;
    m_nr = m_nr.offset(-1);
    z = R_alloc(
        n as size_t,
        ::std::mem::size_of::<libc::c_int>() as libc::c_ulong as libc::c_int,
    ) as *mut libc::c_int;
    z = z.offset(-1);
    ans = allocMatrix(13 as libc::c_int as SEXPTYPE, n, LENGTH(which));
    protect(ans);
    i_ans = INTEGER(ans);
    k = 1 as libc::c_int;
    while k <= n {
        *sing.offset(k as isize) = TRUE;
        *m_nr.offset(k as isize) = 0 as libc::c_int;
        k += 1
        /* containing last merge-step number of k-th obs. */
    } /* for(k ..) {merge} */
    k = 1 as libc::c_int;
    while k <= n - 1 as libc::c_int {
        /* k-th merge, from n-k+1 to n-k atoms: (m1,m2) = merge[ k , ] */
        m1 = *i_merge.offset((k - 1 as libc::c_int) as isize);
        m2 = *i_merge.offset((n - 1 as libc::c_int + k - 1 as libc::c_int) as isize);
        if m1 < 0 as libc::c_int && m2 < 0 as libc::c_int {
            /* for(j .. which[j] ) */
            /* merging atoms [-m1] and [-m2] */
            let ref mut fresh0 = *m_nr.offset(-m2 as isize);
            *fresh0 = k;
            *m_nr.offset(-m1 as isize) = *fresh0;
            let ref mut fresh1 = *sing.offset(-m2 as isize);
            *fresh1 = FALSE;
            *sing.offset(-m1 as isize) = *fresh1
        } else if m1 < 0 as libc::c_int || m2 < 0 as libc::c_int {
            /* the other >= 0 */
            if m1 < 0 as libc::c_int {
                j = -m1;
                m1 = m2
            } else {
                j = -m2
            }
            /* merging atom j & cluster m1 */
            l = 1 as libc::c_int;
            while l <= n {
                if *m_nr.offset(l as isize) == m1 {
                    *m_nr.offset(l as isize) = k
                }
                l += 1
            }
            *m_nr.offset(j as isize) = k;
            *sing.offset(j as isize) = FALSE
        } else {
            /* both m1, m2 >= 0 */
            l = 1 as libc::c_int;
            while l <= n {
                if *m_nr.offset(l as isize) == m1 || *m_nr.offset(l as isize) == m2 {
                    *m_nr.offset(l as isize) = k
                }
                l += 1
            }
        }
        found_j = FALSE;
        j = 0 as libc::c_int;
        while j < LENGTH(which) {
            if *i_which.offset(j as isize) == n - k {
                if found_j as u64 == 0 {
                    /* does this k-th merge belong to a desired group size which[j] ?
                     * if yes, find j (maybe multiple ones): */
                    /* first match (and usually only one) */
                    found_j = TRUE; /*may want to copy this column of ans[] */
                    l = 1 as libc::c_int;
                    while l <= n {
                        *z.offset(l as isize) = 0 as libc::c_int;
                        l += 1
                    }
                    nclust = 0 as libc::c_int;
                    mm = j * n;
                    l = 1 as libc::c_int;
                    m1 = mm;
                    while l <= n {
                        if *sing.offset(l as isize) as u64 != 0 {
                            nclust += 1;
                            *i_ans.offset(m1 as isize) = nclust
                        } else {
                            if *z.offset(*m_nr.offset(l as isize) as isize) == 0 as libc::c_int {
                                nclust += 1;
                                *z.offset(*m_nr.offset(l as isize) as isize) = nclust
                            }
                            *i_ans.offset(m1 as isize) =
                                *z.offset(*m_nr.offset(l as isize) as isize)
                        }
                        l += 1;
                        m1 += 1
                    }
                } else {
                    /* found_j: another which[j] == n-k : copy column */
                    l = 1 as libc::c_int;
                    m1 = j * n;
                    m2 = mm;
                    while l <= n {
                        *i_ans.offset(m1 as isize) = *i_ans.offset(m2 as isize);
                        l += 1;
                        m1 += 1;
                        m2 += 1
                    }
                }
            }
            j += 1
            /* if ( match ) */
        }
        k += 1
    }
    /* Dealing with trivial case which[] = n : */
    j = 0 as libc::c_int;
    while j < LENGTH(which) {
        if *i_which.offset(j as isize) == n {
            l = 1 as libc::c_int;
            m1 = j * n;
            while l <= n {
                *i_ans.offset(m1 as isize) = l;
                l += 1;
                m1 += 1
            }
        }
        j += 1
    }
    unprotect(3 as libc::c_int);
    return ans;
}