use crate::sexprec::{SEXP, SEXPREC, SEXPTYPE};
use ::libc;
extern "C" {
#[no_mangle]
fn sqrt(_: libc::c_double) -> libc::c_double;
#[no_mangle]
fn memcpy(_: *mut libc::c_void, _: *const libc::c_void, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn memset(_: *mut libc::c_void, _: libc::c_int, _: libc::c_ulong) -> *mut libc::c_void;
#[no_mangle]
fn R_chk_free(_: *mut libc::c_void);
#[no_mangle]
fn R_chk_calloc(_: size_t, _: size_t) -> *mut libc::c_void;
#[no_mangle]
fn norm_rand() -> libc::c_double;
#[no_mangle]
fn PutRNGstate();
#[no_mangle]
fn GetRNGstate();
#[no_mangle]
fn error(_: *const libc::c_char, _: ...) -> !;
#[no_mangle]
fn isReal(s: SEXP) -> Rboolean;
#[no_mangle]
fn INTEGER(x: SEXP) -> *mut libc::c_int;
#[no_mangle]
fn REAL(x: SEXP) -> *mut libc::c_double;
#[no_mangle]
static mut R_DimSymbol: SEXP;
#[no_mangle]
fn asInteger(x: SEXP) -> libc::c_int;
#[no_mangle]
fn asReal(x: SEXP) -> libc::c_double;
#[no_mangle]
fn alloc3DArray(_: SEXPTYPE, _: libc::c_int, _: libc::c_int, _: libc::c_int) -> SEXP;
#[no_mangle]
fn getAttrib(_: SEXP, _: SEXP) -> SEXP;
#[no_mangle]
fn isMatrix(_: SEXP) -> Rboolean;
#[no_mangle]
fn protect(_: SEXP) -> SEXP;
#[no_mangle]
fn unprotect(_: libc::c_int);
#[no_mangle]
fn rchisq(_: libc::c_double) -> libc::c_double;
#[no_mangle]
fn dpotrf_(
uplo: *const libc::c_char,
n: *const libc::c_int,
a: *mut libc::c_double,
lda: *const libc::c_int,
info: *mut libc::c_int,
);
#[no_mangle]
fn dsyrk_(
uplo: *const libc::c_char,
trans: *const libc::c_char,
n: *const libc::c_int,
k: *const libc::c_int,
alpha: *const libc::c_double,
a: *const libc::c_double,
lda: *const libc::c_int,
beta: *const libc::c_double,
c: *mut libc::c_double,
ldc: *const libc::c_int,
);
#[no_mangle]
fn dtrmm_(
side: *const libc::c_char,
uplo: *const libc::c_char,
transa: *const libc::c_char,
diag: *const libc::c_char,
m: *const libc::c_int,
n: *const libc::c_int,
alpha: *const libc::c_double,
a: *const libc::c_double,
lda: *const libc::c_int,
b: *mut libc::c_double,
ldb: *const 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 size_t = libc::c_ulong;
pub type Rboolean = libc::c_uint;
pub const TRUE: Rboolean = 1;
pub const FALSE: Rboolean = 0;
unsafe extern "C" fn std_rWishart_factor(
mut nu: libc::c_double,
mut p: libc::c_int,
mut upper: libc::c_int,
mut ans: *mut libc::c_double,
) -> *mut libc::c_double {
let mut pp1: libc::c_int = p + 1 as libc::c_int;
if nu < p as libc::c_double || p <= 0 as libc::c_int {
error(dcgettext(
b"stats\x00" as *const u8 as *const libc::c_char,
b"inconsistent degrees of freedom and dimension\x00" as *const u8
as *const libc::c_char,
5 as libc::c_int,
));
}
memset(
ans as *mut libc::c_void,
0 as libc::c_int,
((p * p) as libc::c_ulong)
.wrapping_mul(::std::mem::size_of::<libc::c_double>() as libc::c_ulong),
);
let mut j: libc::c_int = 0 as libc::c_int;
while j < p {
*ans.offset((j * pp1) as isize) = sqrt(rchisq(nu - j as libc::c_double));
let mut i: libc::c_int = 0 as libc::c_int;
while i < j {
let mut uind: libc::c_int = i + j * p;
let mut lind: libc::c_int = j + i * p;
*ans.offset(if upper != 0 { uind } else { lind } as isize) = norm_rand();
*ans.offset(if upper != 0 { lind } else { uind } as isize) =
0 as libc::c_int as libc::c_double;
i += 1
}
j += 1
}
return ans;
}
#[no_mangle]
pub unsafe extern "C" fn rWishart(mut ns: SEXP, mut nuP: SEXP, mut scal: SEXP) -> SEXP {
let mut ans: SEXP = 0 as *mut SEXPREC;
let mut dims: *mut libc::c_int = INTEGER(getAttrib(scal, R_DimSymbol));
let mut info: libc::c_int = 0;
let mut n: libc::c_int = asInteger(ns);
let mut psqr: libc::c_int = 0;
let mut scCp: *mut libc::c_double = 0 as *mut libc::c_double;
let mut ansp: *mut libc::c_double = 0 as *mut libc::c_double;
let mut tmp: *mut libc::c_double = 0 as *mut libc::c_double;
let mut nu: libc::c_double = asReal(nuP);
let mut one: libc::c_double = 1 as libc::c_int as libc::c_double;
let mut zero: libc::c_double = 0 as libc::c_int as libc::c_double;
if isMatrix(scal) as u64 == 0
|| isReal(scal) as u64 == 0
|| *dims.offset(0 as libc::c_int as isize) != *dims.offset(1 as libc::c_int as isize)
{
error(dcgettext(
b"stats\x00" as *const u8 as *const libc::c_char,
b"\'scal\' must be a square, real matrix\x00" as *const u8 as *const libc::c_char,
5 as libc::c_int,
));
}
if n <= 0 as libc::c_int {
n = 1 as libc::c_int
}
ans = alloc3DArray(
14 as libc::c_int as SEXPTYPE,
*dims.offset(0 as libc::c_int as isize),
*dims.offset(0 as libc::c_int as isize),
n,
);
protect(ans);
psqr = *dims.offset(0 as libc::c_int as isize) * *dims.offset(0 as libc::c_int as isize);
tmp = R_chk_calloc(
psqr as size_t,
::std::mem::size_of::<libc::c_double>() as libc::c_ulong,
) as *mut libc::c_double;
scCp = R_chk_calloc(
psqr as size_t,
::std::mem::size_of::<libc::c_double>() as libc::c_ulong,
) as *mut libc::c_double;
memcpy(
scCp as *mut libc::c_void,
REAL(scal) as *const libc::c_void,
(psqr as size_t).wrapping_mul(::std::mem::size_of::<libc::c_double>() as libc::c_ulong),
);
memset(
tmp as *mut libc::c_void,
0 as libc::c_int,
(psqr as libc::c_ulong)
.wrapping_mul(::std::mem::size_of::<libc::c_double>() as libc::c_ulong),
);
dpotrf_(
b"U\x00" as *const u8 as *const libc::c_char,
&mut *dims.offset(0 as libc::c_int as isize),
scCp,
&mut *dims.offset(0 as libc::c_int as isize),
&mut info,
);
if info != 0 {
error(dcgettext(
b"stats\x00" as *const u8 as *const libc::c_char,
b"\'scal\' matrix is not positive-definite\x00" as *const u8 as *const libc::c_char,
5 as libc::c_int,
));
}
ansp = REAL(ans);
GetRNGstate();
let mut j: libc::c_int = 0 as libc::c_int;
while j < n {
let mut ansj: *mut libc::c_double = ansp.offset((j * psqr) as isize);
std_rWishart_factor(
nu,
*dims.offset(0 as libc::c_int as isize),
1 as libc::c_int,
tmp,
);
dtrmm_(
b"R\x00" as *const u8 as *const libc::c_char,
b"U\x00" as *const u8 as *const libc::c_char,
b"N\x00" as *const u8 as *const libc::c_char,
b"N\x00" as *const u8 as *const libc::c_char,
dims,
dims,
&mut one,
scCp,
dims,
tmp,
dims,
);
dsyrk_(
b"U\x00" as *const u8 as *const libc::c_char,
b"T\x00" as *const u8 as *const libc::c_char,
&mut *dims.offset(1 as libc::c_int as isize),
&mut *dims.offset(1 as libc::c_int as isize),
&mut one,
tmp,
&mut *dims.offset(1 as libc::c_int as isize),
&mut zero,
ansj,
&mut *dims.offset(1 as libc::c_int as isize),
);
let mut i: libc::c_int = 1 as libc::c_int;
while i < *dims.offset(0 as libc::c_int as isize) {
let mut k: libc::c_int = 0 as libc::c_int;
while k < i {
*ansj.offset((i + k * *dims.offset(0 as libc::c_int as isize)) as isize) =
*ansj.offset((k + i * *dims.offset(0 as libc::c_int as isize)) as isize);
k += 1
}
i += 1
}
j += 1
}
PutRNGstate();
R_chk_free(scCp as *mut libc::c_void);
scCp = 0 as *mut libc::c_double;
R_chk_free(tmp as *mut libc::c_void);
tmp = 0 as *mut libc::c_double;
unprotect(1 as libc::c_int);
return ans;
}