Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
125 changes: 88 additions & 37 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,56 +1,107 @@
# C++ project template with Google Tests and CI/CD
# ProbabilityTheoryModeling
## Сборка и тесты

```bash
mkdir -p cmake-build-debug
cd cmake-build-debug
cmake ..
cmake --build .
ctest # или ./bin/cpp_tests
```

This is a project template. Feel free to use & fork it. It contains all pre-configured
CMakeLists.txt, so to use it, replace project name with your one in
[main CmakeLists.txt](CMakeLists.txt), and all target and executable names in
[CI/CD script](./.github/workflows/ci_tests.yml). Sample program prints a greeting for the first argument.
---

## How to build and run
## Задание 1. Конечное вероятностное пространство и σ-алгебра

Run the following commands from the project directory.

1. Create CMake cache
* Реализовать конечное пространство исходов `OutcomeSpace`.
* Реализовать класс `Event` (событие как подмножество Ω).
* Реализовать `ProbabilityMeasure`, задающую вероятности атомов и событий.
* Реализовать дискретную случайную величину `DiscreteRandomVariable` и вычисление ее математического ожидания.
* Опционально: проверить, что набор событий образует σ-алгебру.

```shell
cmake -S . -B cmake-build
```
Ожидается, что можно:

2. Build executable target
* Создать Ω (например, исходы броска кубика).
* Задать события (чётные числа и т.п.).
* Посчитать их вероятности и E[X] для простой X.

```shell
cmake --build cmake-build --target cpp_tests
```
---

3. Build tests target
## Задание 2. Распределения и моделирование

```shell
cmake --build cmake-build --target cpp_tests_tests
```
* Есть базовый интерфейс `Distribution` с методами:

4. Run executable target
* `Pdf(x)` / `Cdf(x)`
* `Sample(rng)`
* теоретические `Mean`, `Cariance`
* Реализовать/использовать распределения:

* On Windows:
* Бернулли, биномиальное, геометрическое, Пуассон
* Нормальное, равномерное, экспоненциальное
* Коши, Лапласа (или другое «интересное» распределение)
* Класс `DistributionExperiment`:

```shell
.\cmake-build\cpp_tests.exe World
```
* сэмплирует N значений,
* считает выборочные среднее и дисперсию,
* сравнивает с теорией,
* может строить эмпирическую CDF и считать расстояние Колмогорова.

* On *nix:
Ожидается, что можно:

```shell
./cmake-build/bin/cpp_tests World
```
* Для каждого распределения провести эксперимент.
* Убедиться, что выборочные характеристики приближаются к теоретическим.

5. Run tests
---

* On Windows:
## Задание 3. Закон больших чисел

```shell
.\cmake-build\cpp_tests_tests.exe
```
* Класс `LawOfLargeNumbersSimulator`:

* On *nix:
* принимает `std::shared_ptr<Distribution>`,
* моделирует одну траекторию выборочного среднего
$\overline{X}_n = (X_1 + \dots + X_n)/n$ при $n = \text{step}, 2\text{step}, \dots$,
* возвращает вектор записей `(n, sample_mean, |sample_mean - theoretical_mean|)`.

```shell
./cmake-build/tests/cpp_tests_tests
```
Ожидается, что можно:

* Для разных распределений (Ber, Uniform, Exp, Laplace) показать численно, что
$|\overline{X}_n - \mu|$ уменьшается при росте `n`.
* Обсудить поведение для распределения, у которого матожидание не определено (Коши).

---

## Задание 4. Цепи Маркова и генерация текста

* Класс `MarkovChain`:

* состояния - строки (`std::string`),
* инкрементальное обучение по последовательностям состояний,
* хранение счётчиков переходов и оценка `P(next | current)`,
* генерация цепочки заданной длины.
* Класс `MarkovTextModel`:

* два режима токенизации: `Character` (символы) и `Word` (слова),
* `trainFromText(text)` - токенизировать и обучить цепь Маркова,
* `generateText(num_tokens, rng, start_token)` - сгенерировать текст.
* Интеграционный тест:

* обучить word-level модель на «Войне и мире»,
* проверить размер словаря,
* убедиться, что типичные слова попали в модель,
* проверить, что генерация текста работает.

Ожидается, что можно:

* Обучить Markov-модель на большом корпусе.
* Генерировать текст в стиле корпуса.
* Сравнить word- и char-модели.

---

Краткое резюме:

* Задание 1: моделируем конечное Ω, события и вероятности.
* Задание 2: реализуем и исследуем разные распределения.
* Задание 3: показываем закон больших чисел на численных экспериментах.
* Задание 4: строим цепь Маркова и генерируем текст (в т.ч. по «Войне и миру»).
5 changes: 4 additions & 1 deletion bin/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
add_executable(${PROJECT_NAME} main.cpp)

target_link_libraries(${PROJECT_NAME} PUBLIC
ui
sigma-algebra
distributions
markov-chain
law-of-large-numbers
)

target_include_directories(${PROJECT_NAME} PUBLIC ${PROJECT_SOURCE_DIR})
10 changes: 4 additions & 6 deletions bin/main.cpp
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
#include <iostream>
#include <cstdint>

#include "lib/ui/ui_functions.hpp"

int main(int32_t argc, char** argv) {
std::vector<std::string> args = std::vector<std::string>(argv, argv + argc);
return StartConsoleUI(args, std::cout);
int main(std::int32_t argc, char** argv) {
// You can add anything you want here
return 0;
}
6 changes: 4 additions & 2 deletions lib/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,6 @@
cmake_minimum_required(VERSION 3.12)

add_subdirectory(mylib)
add_subdirectory(ui)
add_subdirectory(sigma-algebra)
add_subdirectory(distributions)
add_subdirectory(law-of-large-numbers)
add_subdirectory(markov-chain)
1 change: 1 addition & 0 deletions lib/distributions/BernoulliDistribution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "BernoulliDistribution.hpp"
28 changes: 28 additions & 0 deletions lib/distributions/BernoulliDistribution.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef PTM_BERNOULLIDISTRIBUTION_HPP_
#define PTM_BERNOULLIDISTRIBUTION_HPP_

#include <random>

#include "Distribution.hpp"

namespace ptm {

// Бернулли Bernoulli(p)
class BernoulliDistribution : public Distribution {
public:
explicit BernoulliDistribution(double p);

[[nodiscard]] double Pdf(double x) const override;
[[nodiscard]] double Cdf(double x) const override;
double Sample(std::mt19937& rng) const override;

[[nodiscard]] double TheoreticalMean() const override;
[[nodiscard]] double TheoreticalVariance() const override;

private:
double p_;
};

} // namespace ptm

#endif // PTM_BERNOULLIDISTRIBUTION_HPP_
1 change: 1 addition & 0 deletions lib/distributions/BinomialDistribution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "BinomialDistribution.hpp"
29 changes: 29 additions & 0 deletions lib/distributions/BinomialDistribution.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
#ifndef PTM_BINOMIALDISTRIBUTION_HPP_
#define PTM_BINOMIALDISTRIBUTION_HPP_

#include <random>

#include "Distribution.hpp"

namespace ptm {

// Биномиальное Binomial(n, p)
class BinomialDistribution : public Distribution {
public:
BinomialDistribution(unsigned int n, double p);

[[nodiscard]] double Pdf(double x) const override;
[[nodiscard]] double Cdf(double x) const override;
double Sample(std::mt19937& rng) const override;

[[nodiscard]] double TheoreticalMean() const override;
[[nodiscard]] double TheoreticalVariance() const override;

private:
unsigned int n_;
double p_;
};

} // namespace ptm

#endif // PTM_BINOMIALDISTRIBUTION_HPP_
12 changes: 12 additions & 0 deletions lib/distributions/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
add_library(distributions STATIC
NormalDistribution.cpp
UniformDistribution.cpp
ExponentialDistribution.cpp
CauchyDistribution.cpp
LaplaceDistribution.cpp
BernoulliDistribution.cpp
BinomialDistribution.cpp
GeometricDistribution.cpp
PoissonDistribution.cpp
DistributionExperiment.cpp
)
1 change: 1 addition & 0 deletions lib/distributions/CauchyDistribution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "CauchyDistribution.hpp"
27 changes: 27 additions & 0 deletions lib/distributions/CauchyDistribution.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
#ifndef PTM_CAUCHYDISTRIBUTION_HPP_
#define PTM_CAUCHYDISTRIBUTION_HPP_

#include "Distribution.hpp"

namespace ptm {

// Распределение Коши (x0, gamma)
class CauchyDistribution : public Distribution {
public:
CauchyDistribution(double x0, double gamma);

[[nodiscard]] double Pdf(double x) const override;
[[nodiscard]] double Cdf(double x) const override;
double Sample(std::mt19937& rng) const override;

[[nodiscard]] double TheoreticalMean() const override;
[[nodiscard]] double TheoreticalVariance() const override;

private:
double x0_;
double gamma_;
};

} // namespace ptm

#endif // PTM_CAUCHYDISTRIBUTION_HPP_
30 changes: 30 additions & 0 deletions lib/distributions/Distribution.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
#ifndef PTM_DISTRIBUTION_HPP_
#define PTM_DISTRIBUTION_HPP_

#include <random>

namespace ptm {

// Базовый класс для распределения
class Distribution { // NOLINT(cppcoreguidelines-special-member-functions)
public:
virtual ~Distribution() = default;

// Для дискретных распределений pdf(x) трактуем как P(X = x)
[[nodiscard]] virtual double Pdf(double x) const = 0;

// F(x) = P(X <= x)
[[nodiscard]] virtual double Cdf(double x) const = 0;

// Генерация выборочного значения
virtual double Sample(std::mt19937& rng) const = 0;

// Теоретическое матожидание и дисперсия (если определены).
// Для распределений, где это не определено - можно вернуть NaN.
[[nodiscard]] virtual double TheoreticalMean() const = 0;
[[nodiscard]] virtual double TheoreticalVariance() const = 0;
};

} // namespace ptm

#endif // PTM_DISTRIBUTION_HPP_
1 change: 1 addition & 0 deletions lib/distributions/DistributionExperiment.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "DistributionExperiment.hpp"
33 changes: 33 additions & 0 deletions lib/distributions/DistributionExperiment.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
#ifndef PTM_DISTRIBUTIONEXPERIMENT_HPP_
#define PTM_DISTRIBUTIONEXPERIMENT_HPP_

#include <memory>
#include <random>

#include "Distribution.hpp"
#include "ExperimentStats.hpp"

namespace ptm {

// Класс для массовых экспериментов по моделированию распределений
class DistributionExperiment {
public:
DistributionExperiment(std::shared_ptr<Distribution> dist, size_t sample_size);

ExperimentStats Run(std::mt19937& rng);

// Эмпирическая CDF на сетке точек
std::vector<double> EmpiricalCdf(const std::vector<double>& grid, std::mt19937& rng, std::size_t sample_size);

// Оценка статистики Колмогорова между эмпирической и теоретической CDF
[[nodiscard]] double KolmogorovDistance(const std::vector<double>& grid,
const std::vector<double>& empirical_cdf) const;

private:
std::shared_ptr<Distribution> dist_;
std::size_t sample_size_;
};

} // namespace ptm

#endif // PTM_DISTRIBUTIONEXPERIMENT_HPP_
11 changes: 11 additions & 0 deletions lib/distributions/ExperimentStats.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#ifndef PTM_EXPERIMENTSTATS_HPP_
#define PTM_EXPERIMENTSTATS_HPP_

struct ExperimentStats {
double empirical_mean = 0.0;
double empirical_variance = 0.0;
double mean_error = 0.0;
double variance_error = 0.0;
};

#endif // PTM_EXPERIMENTSTATS_HPP_
1 change: 1 addition & 0 deletions lib/distributions/ExponentialDistribution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "ExponentialDistribution.hpp"
25 changes: 25 additions & 0 deletions lib/distributions/ExponentialDistribution.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
#ifndef PTM_EXPONENTIALDISTRIBUTION_HPP_
#define PTM_EXPONENTIALDISTRIBUTION_HPP_

#include "Distribution.hpp"

namespace ptm {

class ExponentialDistribution : public Distribution {
public:
explicit ExponentialDistribution(double lambda);

[[nodiscard]] double Pdf(double x) const override;
[[nodiscard]] double Cdf(double x) const override;
double Sample(std::mt19937& rng) const override;

[[nodiscard]] double TheoreticalMean() const override;
[[nodiscard]] double TheoreticalVariance() const override;

private:
double lambda_;
};

} // namespace ptm

#endif // PTM_EXPONENTIALDISTRIBUTION_HPP_
1 change: 1 addition & 0 deletions lib/distributions/GeometricDistribution.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
#include "GeometricDistribution.hpp"
Loading
Loading