This commit is contained in:
jacekpoz 2024-02-04 15:07:13 +01:00
commit 92c2f676b6
No known key found for this signature in database
GPG key ID: 94E812A8B12AAE3C
19 changed files with 1334 additions and 0 deletions

1
.gitignore vendored Normal file
View file

@ -0,0 +1 @@
/target

1052
Cargo.lock generated Normal file

File diff suppressed because it is too large Load diff

14
Cargo.toml Normal file
View file

@ -0,0 +1,14 @@
[package]
name = "zd4"
version = "0.1.0"
edition = "2021"
[dependencies]
anyhow = "1.0.79"
plotters = "0.3.5"
rand = "0.8.5"
probability = "0.20.3"
itertools = "0.12.1"
rand_mt = "4.2.2"
lcg-rand = "1.0.0"
serde_json = "1.0.113"

6
results/1 Normal file
View file

@ -0,0 +1,6 @@
===============================================================================================================
| n | a markov | b markov | a chebyshev | b chebyshev | a exact value | b exact value |
| 100 | 0.8333333333333334 | 1.818181818181818 | 0.25 | 1 | 0.028443966820490107 | 0.36820161732671786 |
| 1000 | 0.8333333333333334 | 1.8181818181818181 | 0.025 | 0.1 | 0.00000000013642287299830969 | 0.0017305360849745471 |
| 10000 | 0.8333333333333334 | 1.8181818181818181 | 0.0025 | 0.01 | 0.0000000000000002220446049250313 | 0.00000000000000000000001551064056843765 |
===============================================================================================================

BIN
results/2/10.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 65 KiB

BIN
results/2/100.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
results/2/15.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 81 KiB

BIN
results/2/20.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 96 KiB

BIN
results/2/25.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 74 KiB

BIN
results/2/30.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 83 KiB

BIN
results/2/5.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 72 KiB

1
results/3 Normal file

File diff suppressed because one or more lines are too long

1
results/4/lcg Normal file

File diff suppressed because one or more lines are too long

1
results/4/mt Normal file

File diff suppressed because one or more lines are too long

BIN
sprawozdanie.odt Normal file

Binary file not shown.

BIN
sprawozdanie.pdf Normal file

Binary file not shown.

17
src/3hist.py Executable file
View file

@ -0,0 +1,17 @@
#!/usr/bin/env python
import json
import matplotlib.pyplot as plt
with open(f"./results/3", "r") as file:
data = json.load(file)
for key, values in data.items():
n, bins, _ = plt.hist(values, bins = 20, range = [0, 1], density = True)
plt.title(f"n = {key}")
plt.xlabel("Wartość")
plt.ylabel("Gęstość")
bin_centers = (bins[1:] + bins[:-1]) * 0.5
plt.plot(bin_centers, n, color = "green", linestyle = "-", linewidth = 2)
plt.show()

225
src/main.rs Normal file
View file

@ -0,0 +1,225 @@
use std::{collections::HashMap, path::PathBuf};
use std::fs;
use plotters::{backend::BitMapBackend, chart::ChartBuilder, drawing::IntoDrawingArea, element::Circle, series::PointSeries, style::{Color, BLUE, WHITE}};
use probability::prelude::*;
use rand::{thread_rng, Rng};
use rand_mt::Mt64;
use lcg_rand::rand::LCG;
fn zad1(path: &PathBuf) {
let p = 0.5;
let mut output = String::new();
let top_row = &format!("| {:<5} | {:<18} | {:<8} | {:<11} | {:<11} | {:<18} | {:<18} |\n",
"n", "a markov", "b markov", "a chebyshev", "b chebyshev", "a exact value", "b exact value"
);
let mut border = "=".repeat(top_row.len() - 1);
border.push('\n');
output.push_str(&border);
output.push_str(&top_row);
for n in [100., 1000., 10000.] {
let dist = Binomial::new(n as usize, p);
// E(X)
let ex = n * p;
// var(X)
let varx = n * p * (1. - p);
// 6/5 * E(X)
let a = 1.2 * ex;
let a_exact = 1.0 - ((0..(a as usize))
.map(|k| dist.mass(k))
.sum::<f64>());
// P(X >= 6/5*E(X))
let a_markov = ex / a;
// P(|X-E(X)| >= 6/5*E(X) - E(X))
let a = 0.2 * ex;
let a_chebyshev = varx / (a*a);
// 1/10 * E(X)
let b: f64 = 0.1 * ex;
// P(|X - E(X)| >= 1/10*E(X))
// P(X - E(X) >= 1/10*E(X) P(X - E(X) <= -1/10*E(X))
// P(X >= 11/10*E(X) P(X <= 9/10*E(X))
// P(X <= 9/10*E(X) P(X >= 11/10*E(X))
// P(X <= 9/10*E(X)) + P(X >= 11/10*E(X))
// oba są sobie równe, bo bin ma peak w E(X)
// czyli możemy
// 2 * P(X <= 9/10*E(X))
let b_exact = dist.distribution(0.9 * ex) * 2.0;
// P(|X-E(X)| >= 1/10*E(X))
let b_chebyshev = varx / (b * b);
let b_markov = (ex / (1.1 * ex)) * 2.0;
output.push_str(
format!("| {:<5} | {:<18} | {:<8} | {:<11} | {:<11} | {:<18} | {:<18} |\n",
n, a_markov, b_markov, a_chebyshev, b_chebyshev, a_exact, b_exact
).as_str()
);
}
output.push_str(&border);
let _ = fs::write(path, output);
}
fn zad2(path: &PathBuf) {
let k = 10000000;
let mut sums = vec![0; k];
let mut rng = thread_rng();
for n in [5, 10, 15, 20, 25, 30, 100] {
let intervals = ((-n + 1)..(n + 1))
.map(|n| (-n, -n + 1))
.collect::<Vec<_>>();
for i in 0..k {
sums[i] = (0..n)
.map(|_| ((rng.gen_range(0..=1) as f64 - 0.5) * 2.0) as i32)
.sum();
}
let counts = intervals.iter()
.map(|interval|
sums.iter()
.map(|sum| (*sum <= interval.1) as i32)
.sum::<i32>()
)
.collect::<Vec<_>>();
let xs = intervals.iter()
.map(|i| i.1 as f64)
.collect::<Vec<_>>();
// SAFETY: we can assume it's not empty
let x_max = *xs.iter().max_by(|a, b| a.total_cmp(b)).unwrap();
// SAFETY: we can assume it's not empty
let max_count = *counts.iter().max().unwrap() as f64;
let ys = counts.iter()
.map(|count| *count as f64 / max_count)
.collect::<Vec<_>>();
// SAFETY: we can assume it's not empty
let y_max = *ys.iter().max_by(|a, b| a.total_cmp(b)).unwrap();
let mut n_path = path.clone();
n_path.push(format!("{n}.png"));
let root_drawing_area = BitMapBackend::new(&n_path, (1920, 1080))
.into_drawing_area();
root_drawing_area.fill(&WHITE).unwrap();
let mut chart = ChartBuilder::on(&root_drawing_area)
.x_label_area_size(20)
.y_label_area_size(60)
.build_cartesian_2d(
-x_max..x_max,
0f64..y_max,
)
.unwrap();
chart.configure_mesh()
.x_labels(10)
.y_labels(10)
.draw()
.unwrap();
chart.draw_series(PointSeries::<_, _, Circle<_, _>, _>::new(
xs.iter()
.enumerate()
.map(|(i, x)| (*x as f64, ys[i] as f64)),
2,
BLUE.filled(),
)).unwrap();
sums.clear();
sums = vec![0; k];
}
}
fn random_walk(n: i32) -> i32 {
let mut rng = thread_rng();
let mut position = 0;
let mut last_position = position;
let mut ret = 0;
for _ in 0..n {
let direction = ((rng.gen_range(0..=1) as f64 - 0.5) * 2.0) as i32;
position += direction;
if position > 0 || last_position > 0 {
ret += 1;
}
last_position = position;
}
ret
}
fn zad3(path: &PathBuf) {
let k = 5000;
let mut results = HashMap::new();
for n in [100, 1000, 10000] {
let mut pn = vec![0.0; k];
for i in 0..k {
pn[i] = random_walk(n) as f64 / n as f64;
}
results.insert(n, pn);
}
let _ = fs::write(path, serde_json::to_string(&results).unwrap());
}
fn zad4(path: &PathBuf) {
let n = 10000000;
let mut lcg_path = path.clone();
lcg_path.push("lcg");
let mut output = String::new();
let mut lcg = LCG::from_seed(2137u64);
for _ in 0..n {
output.push_str((lcg.next() % 2).to_string().as_str());
}
let _ = fs::write(lcg_path, output.clone());
output.clear();
let mut mt_path = path.clone();
mt_path.push("mt");
let mut mt = Mt64::new(7312u64);
for _ in 0..n {
output.push_str((mt.gen::<u64>() % 2).to_string().as_str());
}
let _ = fs::write(mt_path, output);
}
fn main() {
zad1(&PathBuf::from("results/1"));
zad2(&PathBuf::from("results/2"));
zad3(&PathBuf::from("results/3"));
zad4(&PathBuf::from("results/4"));
}

16
src/normal.py Executable file
View file

@ -0,0 +1,16 @@
#!/usr/bin/env python
import matplotlib.pyplot as plt
import numpy as np
import scipy.stats as stats
import math
mu = 0
for n in [5, 10, 15, 20, 25, 30, 100]:
variance = n
sigma = math.sqrt(variance)
x = np.linspace(mu - 3*sigma, mu + 3*sigma, 100)
plt.title(f"n = {n}")
plt.plot(x, stats.norm.cdf(x, mu, sigma))
plt.show()