Skip to content

Commit

Permalink
added 2d
Browse files Browse the repository at this point in the history
  • Loading branch information
Madhav1729 committed Mar 28, 2024
2 parents 0b0607c + c871581 commit d726459
Show file tree
Hide file tree
Showing 16 changed files with 574 additions and 13 deletions.
1 change: 1 addition & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ include_directories(${PROJECT_SOURCE_DIR}/src/Core)
# Files to be compiled

set(SRC
"src/Core/basicfxn.cpp"
"src/Generators/BBS/blumblumshub.cpp"
"src/Generators/LFSR/LFSR.cpp"
"src/Generators/MT/MT.cpp"
Expand Down
136 changes: 134 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,136 @@
# DiceForge
A C++ library with the same functionality as the *random* library in python.

Go to the **Learning_For_Contributors** folder and then view the **Instructions.md** file to get started on the basics of LaTeX and GitHub.
## Overview
This is a simple C++ library for *Pseudo Random Number Generation (PRNG)*. It provides a functionality similar to that of the python std library *random*.

## Features

- **Ease of Use**: Straightforward API for quick integration into your C++ projects.
- **Versatility**: Supports different PRNG algorithms, allowing you to choose based on your requirements.
- **Seed Control**: Easily set and manipulate the seed for reproducibility.

### Upcoming Features
- Applying distributions to uniform random generators to make biased generators
- Detailed documentation on distrbutions

## Supported PRNG Algorithms

1. Mersenne Twister (MT)
2. Linear Congruential Generator (LCG)
3. XOR-Shift (XOR)
4. Blum Blum Shub (B.B.S.)
5. Naor-Reingold (NR)

## Supported Distrbutions

1. Cauchy
2. Exponential
3. Gaussian
4. Maxwell
5. Weibull
6. Bernoulli
7. Binomial
8. Gibbs
9. Hypergeometric
10. Negative-Hypergeometric
11. Poisson

## Benchmarks

### Statistical Analysis

| Generator | mean | variance |
| --------- | ---- | -------- |
| BBS32 | 0.500189 | 0.0834384 |
| BBS64 | 0.499066 | 0.0834061 |
| XOR32 | 0.499978 | 0.08334 |
| XOR64 | 0.499931 | 0.0833327 |
| MT32 | 0.499956 | 0.0833425 |
| MT64 | 0.500034 | 0.0833241 |
| LFSR32 | 0.500033 | 0.0833329 |
| LFSR64 | 0.49994, | 0.0833352 |
| NR | 0.341687 | 0.0498607 |

### Time Performance
Generating *100000000* random numbers:

#### DiceForge:
| Generator | Time Taken |
| --------- | ---------- |
| XorShift32 | 435.497ms |
| XorShift64 | 410.498ms |
| BBS32 | 14780ms |
| BBS64 | 24568.6ms |
| MT32 | 1738.91ms |
| MT64 | 1811.27ms |
| LFSR | 18540.7ms |
| Naor Reingold | 7143ms|

For comparison, benchmarking other existing standard libraries for the same test.

| Generator | Time Taken |
| --------- | ---------- |
| C++ MT| 4032.7ms |
| C++ rand()| 1388.03ms |
| python randint | 51171.51641845703 ms |
| numpy randint | 194015.43641090393 ms |


## Documentation
Check out the [Documentation](https://www.overleaf.com/project/65d9eea60dbb4690fe6ff8be) for detailed information on library usage, supported algorithms, and more!

## Getting Started

### Prerequisites

- C++ compiler (supporting C++11 or later)
- CMake (>=3.28) [If building library]

### Installation

#### Using a prebuilt library
1. Download the library file from [out](out) folder and add to PATH
2. Make sure the [include](include) folder is PATH
3. Start generating pseudo-random numbers!

#### Building it yourself
1. Clone the repository: `git clone https://github.com/yourusername/prng-library.git`
2. Create the build folder by using the CMakeLists.txt
2. Build library using the given CMake configurations (```cmake --build <build-folder>```)
3. After the build is sucessful, follow the steps mentioned in [Using a prebuilt library](#using-a-prebuilt-library)

## Usage

Here's a quick example to get you started:

```cpp
#include "diceforge.h"

int main() {
// Create a PRNG object
DiceForge::XORShift32 prng = DiceForge::XORShift32(123);

// Generate and print a random number
std::cout << "Random Number: " << prng.next() << std::endl;

return 0;
}
```

Feel free to explore the library and experiment with different algorithms!

## Contributing

Currently, this is an IIT-M Maths CLub exclusive project and we aren't accepting outside contributions.

### For Project Members
- View the [Tasks folder](Contributors_Only/Tasks) to view the tasks to be done.

- Reference materials are provided in the [Contributers_Only](Contributors_Only) folder.

Current TODO
- [ ] Custom pdf
- [ ] Exception handling
- [ ] 2d rv
- [ ] Documentation
- [ ] Testing the RNGs
40 changes: 36 additions & 4 deletions include/diceforge_distributions.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,20 @@ namespace DiceForge {
real_t pdf(real_t x) const override final;
/// @brief Cumulative distribution function of the Cauchy distribution
real_t cdf(real_t x) const override final;
/// @brief Returns x0 (centre of the distribution)
real_t get_x0() const;
/// @brief Returns gamma (scale factor of the distribution)
real_t get_gamma() const;
};

/// @brief Fits the given sample points (x, y=pdf(x)) to a Cauchy distribution using non-linear least squares regression
/// following Gauss-Newton methods
/// @param x list of x coordinates
/// @param y list of corresponding y coordinates where y = pdf(x)
/// @param max_iter maximum iterations to attempt to fit the data (higher to try for better fits)
/// @param epsilon minimum acceptable error tolerance while attempting to fit the data (smaller to try for better fits)
/// @return A Cauchy distribution fit to the given sample points
Cauchy fitToCauchy(const std::vector<real_t>& x, const std::vector<real_t>& y, int max_iter = 10000, real_t epsilon = 1e-6);

/// @brief DiceForge::Exponential - A continuous exponential probability distribution
class Exponential : public Continuous
Expand Down Expand Up @@ -86,12 +99,15 @@ namespace DiceForge {
* @return CDF value at point x.
*/
real_t cdf(real_t x) const override final;
/// @brief Returns the rate parameter of the distribution
real_t get_k() const;
};

/// @brief DiceForge::Gaussian - A Continuous Probability Distribution (Gaussian)
class Gaussian : public Continuous {
private:
real_t mu, sigma;
real_t myerf(real_t x) const;
public:
/// @brief Initializes the Gaussian distribution about location x = mu with standard deviation sigma
/// @param mu mean of the distribution
Expand All @@ -116,6 +132,10 @@ namespace DiceForge {
real_t pdf(real_t x) const override final;
/// @brief Cumulative distribution function of the Gaussian distribution
real_t cdf(real_t x) const override final;
/// @brief Returns mean of the distribution
real_t get_mu() const;
/// @brief Returns standard deviation of the distribution
real_t get_sigma() const;
};

/// @brief DiceForge::Maxwell - A Continuous Probability Distribution (Maxwell)
Expand All @@ -129,8 +149,10 @@ namespace DiceForge {
/// @note a > 0
Maxwell(real_t a = 1);
/// @brief Generates a random number from the Maxwell Distribution
/// @param r A random real number uniformly distributed between 0 and 1
real_t next(real_t r);
/// @param r1 A random real number uniformly distributed between 0 and 1
/// @param r2 A random real number uniformly distributed between 0 and 1
/// @param r3 A random real number uniformly distributed between 0 and 1
real_t next(real_t r1, real_t r2, real_t r3);
/// @brief Returns the theoretical variance of the distribution
real_t variance() const override final;
/// @brief Returns the theoretical expectation value of the distribution
Expand All @@ -145,13 +167,14 @@ namespace DiceForge {
real_t pdf(real_t x) const override final;
/// @brief Cumulative distribution function of the Maxwell distribution
real_t cdf(real_t x) const override final;
/// @brief Returns the scale factor of the distribution
real_t get_a() const;
};

/// @brief DiceForge::WEIBULL - A Continuous Probability Distribution (WEIBULL)
/// @brief DiceForge::Weibull - A Continuous Probability Distribution (Weibull)
class Weibull : public Continuous {
private:
real_t shift, k, lambda;

public:
/// @brief Initializes the Weibull distribution about location x = x0 with scale gamma
/// @param shift shift parameter of distribution
Expand Down Expand Up @@ -187,6 +210,15 @@ namespace DiceForge {

/// @brief Cumulative distribution function of the Weibull distribution
real_t cdf(real_t x) const override final;

/// @brief Returns shift parameter of distribution
real_t get_shift() const;

/// @brief Returns scale factor of the distribution
real_t get_lambda() const;

/// @brief Returns shape factor of the distribution
real_t get_k() const;
};

/// @brief DiceForge::Bernoulli - A Discrete Probability Distribution (Bernoulli)
Expand Down
123 changes: 123 additions & 0 deletions src/Core/basicfxn.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
#include "basicfxn.h"

namespace DiceForge
{
matrix_t::matrix_t(int r, int c)
: r(r), c(c)
{
m = new real_t*[r];
for (size_t i = 0; i < r; i++)
{
m[i] = new real_t[c];
for (size_t j = 0; j < c; j++)
{
m[i][j] = 0;
}
}
}

matrix_t::matrix_t(matrix_t& other)
: r(other.r), c(other.c)
{
m = new real_t*[r];
for (size_t i = 0; i < r; i++)
{
m[i] = new real_t[c];
for (size_t j = 0; j < c; j++)
{
m[i][j] = other.m[i][j];
}
}
}

matrix_t::~matrix_t()
{
for (size_t i = 0; i < r; i++)
{
delete[] m[i];
}
delete[] m;
}

const real_t* matrix_t::operator[](int i) const
{
return m[i];
}

real_t* matrix_t::operator[](int i)
{
return m[i];
}

matrix_t matrix_t::operator*(const matrix_t& other) const
{
matrix_t pdt = matrix_t(r, other.c);
for (size_t i = 0; i < r; i++)
{
for (size_t j = 0; j < other.c; j++)
{
pdt[i][j] = 0;

for (size_t k = 0; k < c; k++)
{
pdt[i][j] += m[i][k] * other.m[k][j];
}
}
}

return pdt;
}

matrix_t matrix_t::operator+(const matrix_t& other) const
{
matrix_t sum = matrix_t(r, c);
for (size_t i = 0; i < r; i++)
{
for (size_t j = 0; j < c; j++)
{
sum.m[i][j] = m[i][j] + other.m[j][i];
}
}
return sum;
}

matrix_t matrix_t::operator-(const matrix_t& other) const
{
matrix_t diff = matrix_t(r, c);
for (size_t i = 0; i < r; i++)
{
for (size_t j = 0; j < c; j++)
{
diff.m[i][j] = m[i][j] - other.m[j][i];
}
}
return diff;
}

matrix_t matrix_t::operator-() const
{
matrix_t neg = matrix_t(r, c);
for (size_t i = 0; i < r; i++)
{
for (size_t j = 0; j < c; j++)
{
neg.m[i][j] = -m[i][j];
}
}
return neg;
}

matrix_t matrix_t::transpose() const
{
matrix_t t = matrix_t(c, r);
for (size_t i = 0; i < r; i++)
{
for (size_t j = 0; j < c; j++)
{
t.m[j][i] = m[i][j];
}
}

return t;
}
}
Loading

0 comments on commit d726459

Please sign in to comment.