Add random_distributions::LinearWeighted

This commit is contained in:
Matthew Gordon 2021-10-07 11:23:46 -04:00
parent 1f84cde760
commit ed224b18cb
4 changed files with 72 additions and 2 deletions

View File

@ -1,6 +1,6 @@
use crate::math::Vec3;
use crate::colour::{ColourRgbF, Photon, Spectrum};
use crate::materials::MaterialSampleResult;
use crate::math::Vec3;
use crate::raycasting::{IntersectionInfo, Ray};
use crate::sampler::Sampler;
use crate::util::algebra_utils::try_change_of_basis_matrix;

View File

@ -1,6 +1,6 @@
use crate::math::Vec3;
use crate::colour::{Photon, Spectrum};
use crate::materials::MaterialSampleResult;
use crate::math::Vec3;
use crate::raycasting::{IntersectionInfo, Ray};
use crate::sampler::Sampler;
use crate::util::algebra_utils::try_change_of_basis_matrix;

View File

@ -0,0 +1,67 @@
use rand::distributions::Open01;
use rand::{thread_rng, Rng};
use super::RandomDistribution;
pub struct LinearWeighted {
max_value: f64,
}
impl LinearWeighted {
pub fn new(max_value: f64) -> LinearWeighted {
LinearWeighted { max_value }
}
}
impl RandomDistribution<f64> for LinearWeighted {
fn value(&self) -> f64 {
let mut rng = thread_rng();
rng.sample::<f64, _>(Open01).sqrt() * self.max_value
}
fn pdf(&self, value: f64) -> f64 {
2.0 * value / (self.max_value * self.max_value)
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
#[ignore]
fn print_values() {
let target = LinearWeighted::new(2.0);
for _ in 0..1000 {
let value = target.value();
println!("{}", value);
}
}
#[test]
#[ignore]
fn print_buckets() {
let mut buckets = [0; 20];
let target = LinearWeighted::new(20.0);
for _ in 0..10000 {
let value = target.value();
let i = value as usize;
buckets[i] += 1;
}
for count in buckets {
println!("{}", count);
}
}
#[test]
#[ignore]
fn integral_is_near_area() {
let target = LinearWeighted::new(2.0);
let integral = (0..100000)
.map(|_| target.value())
.map(|value| 1.0 / target.pdf(value))
.sum::<f64>()
/ 100000.0;
println!("Area: {}\nIntegral: {}", 2.0, integral);
}
}

View File

@ -10,6 +10,9 @@ pub use uniform_hemisphere::UniformHemisphere;
mod cosine_weighted_hemisphere;
pub use cosine_weighted_hemisphere::CosineWeightedHemisphere;
mod linear_weighted;
pub use linear_weighted::LinearWeighted;
pub trait RandomDistribution<T> {
fn value(&self) -> T;
fn pdf(&self, value: T) -> f64;