Add PDF to RandomDistribution

This commit is contained in:
Matthew Gordon 2021-10-04 09:01:58 -04:00
parent 8badbaa3ca
commit 8459f3110f
4 changed files with 54 additions and 0 deletions

View File

@ -9,4 +9,5 @@ pub use uniform_hemisphere::UniformHemisphere;
pub trait RandomDistribution<T> {
fn value(&self) -> T;
fn pdf(&self, value: T) -> f64;
}

View File

@ -1,3 +1,5 @@
use std::f64::consts::PI;
use rand::distributions::{Open01, OpenClosed01};
use rand::{thread_rng, Rng};
@ -30,6 +32,10 @@ impl RandomDistribution<Vec3> for UniformHemisphere {
}
result.normalize()
}
fn pdf(&self, _: Vec3) -> f64 {
1.0 / (2.0 * PI)
}
}
#[cfg(test)]
@ -45,4 +51,16 @@ mod tests {
println!("{}, {}, {}", value.x(), value.y(), value.z());
}
}
#[test]
#[ignore]
fn integral_is_near_area() {
let target = UniformHemisphere::new();
let integral = (0..1000)
.map(|_| target.value())
.map(|value| 1.0 / target.pdf(value))
.sum::<f64>()
/ 1000.0;
println!("Area: {}\nIntegral: {}", 2.0 * PI, integral);
}
}

View File

@ -23,6 +23,10 @@ impl RandomDistribution<Vec2> for UniformSquare {
self.corner
+ Vec2::new(rng.sample::<f64, _>(Open01), rng.sample::<f64, _>(Open01)) * self.size
}
fn pdf(&self, _value: Vec2) -> f64 {
1.0 / (self.size * self.size)
}
}
#[cfg(test)]
@ -41,4 +45,19 @@ mod tests {
println!("{}, {}", value.x(), value.y());
}
}
#[test]
#[ignore]
fn integral_is_near_area() {
let target = UniformSquare {
corner: Vec2::new(1.5, -2.5),
size: 3.0,
};
let integral = (0..1000)
.map(|_| target.value())
.map(|value| 1.0 / target.pdf(value))
.sum::<f64>()
/ 1000.0;
println!("Area: {}\nIntegral: {}", 3.0 * 3.0, integral);
}
}

View File

@ -32,6 +32,10 @@ impl RandomDistribution<Vec2> for UnitDisc {
Vec2::new(angle.cos(), angle.sin()) * radius
}
}
fn pdf(&self, _: Vec2) -> f64 {
1.0 / PI
}
}
#[cfg(test)]
@ -47,4 +51,16 @@ mod tests {
println!("{}, {}", value.x(), value.y());
}
}
#[test]
#[ignore]
fn integral_is_near_area() {
let target = UnitDisc::new();
let integral = (0..1000)
.map(|_| target.value())
.map(|value| 1.0 / target.pdf(value))
.sum::<f64>()
/ 1000.0;
println!("Area: {}\nIntegral: {}", PI, integral);
}
}