use crate::cbig::CBig;
use dashu_float::rand::{Uniform01 as FloatUniform01, UniformFBig};
use dashu_float::round::Round;
use dashu_float::FBig;
use dashu_int::rand::BitRng;
use dashu_int::Word;
pub struct UniformCBig<R: Round, const B: Word> {
pub(crate) re: UniformFBig<R, B>,
pub(crate) im: UniformFBig<R, B>,
}
impl<R: Round, const B: Word> UniformCBig<R, B> {
pub fn new(low: &CBig<R, B>, high: &CBig<R, B>, precision: usize) -> Self {
Self {
re: UniformFBig::new(&part_view(low, true), &part_view(high, true), precision),
im: UniformFBig::new(&part_view(low, false), &part_view(high, false), precision),
}
}
pub fn sample_cbig<BR: BitRng + ?Sized>(&self, rng: &mut BR) -> CBig<R, B> {
let re = self.re.sample_fbig(rng);
let im = self.im.sample_fbig(rng);
CBig::from_parts(re, im)
}
}
fn part_view<R: Round, const B: Word>(z: &CBig<R, B>, re: bool) -> FBig<R, B> {
let ctx = z.context().float();
let repr = if re { z.re().clone() } else { z.im().clone() };
FBig::from_repr(repr, ctx)
}
pub struct Uniform01<const BASE: Word> {
pub(crate) re: FloatUniform01<BASE>,
pub(crate) im: FloatUniform01<BASE>,
}
impl<const B: Word> Uniform01<B> {
#[inline]
pub fn new(precision: usize) -> Self {
Self {
re: FloatUniform01::new(precision),
im: FloatUniform01::new(precision),
}
}
#[inline]
pub fn new_closed(precision: usize) -> Self {
Self {
re: FloatUniform01::new_closed(precision),
im: FloatUniform01::new_closed(precision),
}
}
#[inline]
pub fn new_open(precision: usize) -> Self {
Self {
re: FloatUniform01::new_open(precision),
im: FloatUniform01::new_open(precision),
}
}
pub fn sample_cbig<R: Round, BR: BitRng + ?Sized>(&self, rng: &mut BR) -> CBig<R, B> {
let re = self.re.sample01(rng);
let im = self.im.sample01(rng);
CBig::from_parts(re, im)
}
}