Add PDF to RandomDistribution
This commit is contained in:
parent
8badbaa3ca
commit
8459f3110f
|
|
@ -9,4 +9,5 @@ pub use uniform_hemisphere::UniformHemisphere;
|
||||||
|
|
||||||
pub trait RandomDistribution<T> {
|
pub trait RandomDistribution<T> {
|
||||||
fn value(&self) -> T;
|
fn value(&self) -> T;
|
||||||
|
fn pdf(&self, value: T) -> f64;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,3 +1,5 @@
|
||||||
|
use std::f64::consts::PI;
|
||||||
|
|
||||||
use rand::distributions::{Open01, OpenClosed01};
|
use rand::distributions::{Open01, OpenClosed01};
|
||||||
use rand::{thread_rng, Rng};
|
use rand::{thread_rng, Rng};
|
||||||
|
|
||||||
|
|
@ -30,6 +32,10 @@ impl RandomDistribution<Vec3> for UniformHemisphere {
|
||||||
}
|
}
|
||||||
result.normalize()
|
result.normalize()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pdf(&self, _: Vec3) -> f64 {
|
||||||
|
1.0 / (2.0 * PI)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
@ -45,4 +51,16 @@ mod tests {
|
||||||
println!("{}, {}, {}", value.x(), value.y(), value.z());
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -23,6 +23,10 @@ impl RandomDistribution<Vec2> for UniformSquare {
|
||||||
self.corner
|
self.corner
|
||||||
+ Vec2::new(rng.sample::<f64, _>(Open01), rng.sample::<f64, _>(Open01)) * self.size
|
+ 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)]
|
#[cfg(test)]
|
||||||
|
|
@ -41,4 +45,19 @@ mod tests {
|
||||||
println!("{}, {}", value.x(), value.y());
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,10 @@ impl RandomDistribution<Vec2> for UnitDisc {
|
||||||
Vec2::new(angle.cos(), angle.sin()) * radius
|
Vec2::new(angle.cos(), angle.sin()) * radius
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn pdf(&self, _: Vec2) -> f64 {
|
||||||
|
1.0 / PI
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|
@ -47,4 +51,16 @@ mod tests {
|
||||||
println!("{}, {}", value.x(), value.y());
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue