feat: add binomial distribution calc #1
7 changed files with 429 additions and 401 deletions
757
Cargo.lock
generated
757
Cargo.lock
generated
File diff suppressed because it is too large
Load diff
16
Cargo.toml
16
Cargo.toml
|
|
@ -9,18 +9,18 @@ authors = ["Felipe Contreras Salinas <felipe@bstr.cl>"]
|
||||||
[dependencies]
|
[dependencies]
|
||||||
console_error_panic_hook = "0.1.7"
|
console_error_panic_hook = "0.1.7"
|
||||||
console_log = "1.0.0"
|
console_log = "1.0.0"
|
||||||
fluent-templates = "0.13.0"
|
fluent-templates = "0.13.2"
|
||||||
leptos = { version = "0.8.6", features = ["csr", "tracing"] }
|
leptos = { version = "0.8.14", features = ["csr", "tracing"] }
|
||||||
leptos-fluent = "0.2.16"
|
leptos-fluent = "0.2.20"
|
||||||
leptos_meta = { version = "0.8.5" }
|
leptos_meta = { version = "0.8.5" }
|
||||||
leptos_router = { version = "0.8.5" }
|
leptos_router = { version = "0.8.10" }
|
||||||
log = "0.4.27"
|
log = "0.4.29"
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
wasm-bindgen = "0.2.100"
|
wasm-bindgen = "0.2.106"
|
||||||
wasm-bindgen-test = "0.3.50"
|
wasm-bindgen-test = "0.3.56"
|
||||||
web-sys = { version = "0.3.77", features = ["Document", "Window"] }
|
web-sys = { version = "0.3.83", features = ["Document", "Window"] }
|
||||||
|
|
||||||
|
|
||||||
[profile.release]
|
[profile.release]
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ population = Population Size
|
||||||
successes = Successes in Population
|
successes = Successes in Population
|
||||||
sample = Sample Size
|
sample = Sample Size
|
||||||
sample-successes = Successes in Sample
|
sample-successes = Successes in Sample
|
||||||
hyper-description = Hypergeometric distribution measures the probability of getting a given amount of a certain type of elements from a sample on a population. Think on drawing
|
hyper-description = Hypergeometric distribution measures the probability of getting a given amount of a certain type of elements from a sample on a population. Think on drawing a hand of 7 cards (sample size = 7) from a 52 cards deck (population size = 52) and wanting to know the probability of getting a given number of aces (successes in sample = X, successes in population = 4).
|
||||||
success-probability = Success probability
|
success-probability = Success probability
|
||||||
trials-number = Number of trials
|
trials-number = Number of trials
|
||||||
successes-number = Number of successes
|
successes-number = Number of successes
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ population = Tamaño población
|
||||||
successes = Éxitos en la población
|
successes = Éxitos en la población
|
||||||
sample = Tamaño de la muestra
|
sample = Tamaño de la muestra
|
||||||
sample-successes = Éxitos en la muestra
|
sample-successes = Éxitos en la muestra
|
||||||
hyper-description = Hypergeometric distribution measures the probability of getting a given amount of a certain type of elements from a sample on a population. Think on drawing
|
hyper-description = La distribución hipergeométrica mide la probabilidad de obtener una cierta cantidad de elementos de cierto tipo en una muestra de una población. Por ejemplo, si tomamos una mano de 7 cartas (tamaño de la muestra = 7) de un mazo de 52 cartas (tamaño población = 52) y queremos saber la probabilidad de tener cierta cantidad de ases (éxitos en la muestra = X, éxitos en la población = 4).
|
||||||
success-probability = Probabilidad de éxito
|
success-probability = Probabilidad de éxito
|
||||||
trials-number = Número de intentos
|
trials-number = Número de intentos
|
||||||
successes-number = Número de éxitos
|
successes-number = Número de éxitos
|
||||||
|
|
|
||||||
|
|
@ -25,9 +25,10 @@ header {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
|
padding: 0.1em 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
header > select {
|
header select {
|
||||||
margin: 0 1em;
|
margin: 0 1em;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,3 +93,10 @@ div.results > span.right {
|
||||||
grid-column: 4 / 5;
|
grid-column: 4 / 5;
|
||||||
text-align: left;
|
text-align: left;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
div.calc-description {
|
||||||
|
max-width: 55em;
|
||||||
|
text-align: left;
|
||||||
|
hyphens: auto;
|
||||||
|
margin-top: 2em;
|
||||||
|
}
|
||||||
|
|
|
||||||
39
src/calc.rs
39
src/calc.rs
|
|
@ -69,7 +69,13 @@ pub fn binomial(
|
||||||
trials_number: u8,
|
trials_number: u8,
|
||||||
successes_number: u8,
|
successes_number: u8,
|
||||||
) -> Option<BinomialProb> {
|
) -> Option<BinomialProb> {
|
||||||
None
|
if successes_number > trials_number {
|
||||||
|
None
|
||||||
|
} else {
|
||||||
|
let (p_powers, pc_powers) = powers(success_probability, trials_number);
|
||||||
|
let exactly = binom_exactly(success_probability, trials_number, successes_number);
|
||||||
|
None
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Computes the probability of drawing exactly `sample_successes` in a sample of `sample_size`
|
/// Computes the probability of drawing exactly `sample_successes` in a sample of `sample_size`
|
||||||
|
|
@ -140,6 +146,33 @@ fn hyper_geometric_exactly(
|
||||||
top_product / bot_product
|
top_product / bot_product
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Computes the probability of getting exactly `successes_number` within `trials_number` given
|
||||||
|
/// that the success probability is `success_probability`.
|
||||||
|
///
|
||||||
|
/// The formula is choose(successes_number, trials_number) * (success_probability)^successes_number
|
||||||
|
/// * (1 - success_probability)^(trials_number - successes_number)
|
||||||
|
fn binom_exactly(success_probability: f64, trials_number: u8, successes_number: u8) -> f64 {
|
||||||
|
0.0
|
||||||
|
}
|
||||||
|
|
||||||
|
fn powers(p: f64, N: u8) -> (Vec<f64>, Vec<f64>) {
|
||||||
|
let mut p_powers = Vec::with_capacity((N + 1) as usize);
|
||||||
|
let mut pc_powers = Vec::with_capacity((N + 1) as usize);
|
||||||
|
|
||||||
|
let mut p_power = 1.0;
|
||||||
|
let mut pc_power = 1.0;
|
||||||
|
for _ in 0..N + 1 {
|
||||||
|
p_powers.push(p_power);
|
||||||
|
pc_powers.push(pc_power);
|
||||||
|
p_power = p_power * p;
|
||||||
|
pc_power = pc_power * (1.0 - p)
|
||||||
|
}
|
||||||
|
(p_powers, pc_powers)
|
||||||
|
}
|
||||||
|
|
||||||
|
/// Simplify factors for a fraction.
|
||||||
|
///
|
||||||
|
/// This assumes factors are already prime factors.
|
||||||
fn simplify(
|
fn simplify(
|
||||||
mut top_factors: HashMap<u8, u8>,
|
mut top_factors: HashMap<u8, u8>,
|
||||||
mut bot_factors: HashMap<u8, u8>,
|
mut bot_factors: HashMap<u8, u8>,
|
||||||
|
|
@ -175,6 +208,8 @@ fn simplify(
|
||||||
const PRIMES: &[u8] = &[2, 3, 5, 7, 11, 13];
|
const PRIMES: &[u8] = &[2, 3, 5, 7, 11, 13];
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
|
/// Iterator for the prime factors of a number. We obtain this iterator using the `factorize`
|
||||||
|
/// function.
|
||||||
struct FactorIter<'a> {
|
struct FactorIter<'a> {
|
||||||
/// remainder
|
/// remainder
|
||||||
n: u8,
|
n: u8,
|
||||||
|
|
@ -206,7 +241,7 @@ impl Iterator for FactorIter<'_> {
|
||||||
}
|
}
|
||||||
// If we stopped at a factor, we return it.
|
// If we stopped at a factor, we return it.
|
||||||
// If we exhausted the factors, we return the remainder, as it will be a prime (we
|
// If we exhausted the factors, we return the remainder, as it will be a prime (we
|
||||||
// checked primes less than sqrt(MAX).
|
// checked primes less than sqrt(u8::MAX).
|
||||||
match self.f {
|
match self.f {
|
||||||
Some(f) => Some(f),
|
Some(f) => Some(f),
|
||||||
None => Some(self.n),
|
None => Some(self.n),
|
||||||
|
|
|
||||||
|
|
@ -109,7 +109,7 @@ pub fn HyperCalculator() -> impl IntoView {
|
||||||
</span>
|
</span>
|
||||||
<span class="right">{move || display_rounded(result().greater_or_equal)}</span>
|
<span class="right">{move || display_rounded(result().greater_or_equal)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>{move_tr!("hyper-description")}</div>
|
<div class="calc-description">{move_tr!("hyper-description")}</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -199,7 +199,7 @@ pub fn BinomCalculator() -> impl IntoView {
|
||||||
</span>
|
</span>
|
||||||
<span class="right">{move || display_rounded(result().greater_or_equal)}</span>
|
<span class="right">{move || display_rounded(result().greater_or_equal)}</span>
|
||||||
</div>
|
</div>
|
||||||
<div>{move_tr!("binom-description")}</div>
|
<div class="calc-description">{move_tr!("binom-description")}</div>
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue