lib

parents
target/*
*.lock
[package]
name = "ait"
version = "0.1.0"
authors = ["afischer@lsv.uni-saarland.de <andrufischer@googlemail.com>"]
[dependencies]
lazy_static = "0.2"
use std::sync::atomic::{AtomicU64 as StdAtomicU64, Ordering};
use std::mem::transmute;
#[derive(Debug)]
pub struct AtomicF64 {
inner: StdAtomicU64,
}
impl AtomicF64 {
pub fn new(val: f64) -> AtomicF64 {
AtomicF64 { inner: StdAtomicU64::new(f64_to_u64(val)) }
}
#[inline]
pub fn get(&self) -> f64 {
u64_to_f64(self.inner.load(Ordering::Relaxed))
}
#[inline]
pub fn set(&self, val: f64) {
self.inner.store(f64_to_u64(val), Ordering::Relaxed)
}
}
fn u64_to_f64(val: u64) -> f64 {
unsafe { transmute(val) }
}
fn f64_to_u64(val: f64) -> u64 {
unsafe { transmute(val) }
}
//// STIRLING APPROXIMATIONS
pub mod stirling_approximation{
use std::f64;
pub fn fac_stirling(n: f64) -> f64{
let result: f64 = (2.0*f64::consts::PI*n).sqrt();
let frac: f64 = (n/f64::consts::E).powf(n);
result * frac / f64::consts::LN_2
}
pub fn log_fac_stirling(n: f64) -> f64{
let result: f64 = n*n.ln() - n;
result / f64::consts::LN_2
}
pub fn log_binomial_coefficient_stirling(n: usize, k: usize) -> f64{
let res: f64;
if n == k{
res = 0.0;
} else {
if (n == 0) || (k == 0) {
res = f64::INFINITY;
} else {
let n = n as f64;
let k = k as f64;
res = log_fac_stirling(n) - log_fac_stirling(k) - log_fac_stirling(n - k);
}
}
res
}
pub fn gammaln_stirling(z: f64) -> f64{
let result: f64 = z*z.ln() - z + 0.5*(2.0*f64::consts::PI/z).ln();
result / f64::consts::LN_2
}
}
//// DATA-TO-MODEL FOR DISTRIBUTIONS
pub mod d2m_codes{
use basic_codes::stirling_approximation;
pub fn d2m_nonzero_distribution_cost(counts: usize, bins: usize) -> f64{
//println!("approximating d2m NONZERO distribution cost: {} counts in {} bins", counts, bins);
if counts < bins{
panic!("Number of counts in non-zero distribution must be >= number of bins!");
}
else if bins == 1
{
return 0.0;
}
stirling_approximation::log_binomial_coefficient_stirling(counts - 1, bins - 1)
}
pub fn d2m_distribution_cost(counts: usize, bins: usize) -> f64{
//println!("approximating d2m distribution cost: {} counts in {} bins", counts, bins);
if bins == 1
{
return 0.0;
}
stirling_approximation::log_binomial_coefficient_stirling(counts + bins - 1, bins - 1)
}
}
//// uic
pub mod uic{
use std;
use atomic_f64::AtomicF64;
const MAX_UIC_MEMOIZATION: usize = 1024*1024;
lazy_static!{
static ref UIC : [AtomicF64; 1024] = {
let mut result : [AtomicF64;1024] = unsafe { std::mem::uninitialized() };
for i in 0..MAX_UIC_MEMOIZATION {
let uninit = std::mem::replace(result.get_mut(i).unwrap(), AtomicF64::new(0.0));
std::mem::forget(uninit)
};
result
};
}
use std::f64;
const UIC_NORMALIZATION_CONSTANT: f64 = 1.5185673663648485;
fn uic_proper(n:usize) -> f64
{
let mut res: f64 = 0.0;
let mut n = n as f64;
n = n.log(2.0);
while n > 0.0{
res = res + n;
n = n.log(2.0);
}
res + UIC_NORMALIZATION_CONSTANT
}
pub fn uic_memoized(n: usize) -> f64 {
if n < MAX_UIC_MEMOIZATION
{
let mut res: f64 = UIC[n-1].get();
if res != 0.0
{
res
}
else
{
res = uic_proper(n);
UIC[n-1].set(res);
res
}
}
else
{
uic_proper(n)
}
}
}
#![feature(integer_atomics)]
#[macro_use]
extern crate lazy_static;
pub mod basic_codes;
pub mod atomic_f64;
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment