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
80 changes: 80 additions & 0 deletions GPUSolver/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
# GPUSolver 🚀

GPU-accelerated CUDA C++ library for solving partial differential equations (PDEs), designed for high-performance
numerical simulations.
> **📝 Note:** This library is developed independently from the Python package `pdesolvers` and is not current currently integrated with it

## 🧩 GPU-Accelerated Features
- **Explicit Method for Black-Scholes PDE**
- **Crank-Nicolson Method for Black-Scholes PDE**
- **Geometric Brownian Motion (GBM) Simulations**

## 🔧 Dependencies
- **cuSPARSE**: For sparse matrix operations.
- **cuBLAS**: For dense matrix operations.
- **cuRAND**: For random number generation.

## Example Usage for GPU-Accelerated PDE Solvers

#### 1. Include the necessary headers for the GPU solvers:
```c++
#include "gpu/bse_solvers_parallel.cuh"
#include "gpu/gbm_parallel.cuh"
```
#### 2. Define parameters for the Black-Scholes PDE and GBM simulation:

```c++
/* Parameters for Black-Scholes PDE */
constexpr OptionType type = OptionType::Call;
double s_max = 300.0;
double expiry = 1;
double sigma = 0.2;
double rate = 0.05;
double strike_price = 100;
int s_nodes = 1000;
int t_nodes = 1000000;

/* Parameters for Geometric Brownian Motion */
double initial_stock_price = 290.0;
double time = 1;
int time_steps = 365;
int num_of_simulations = 800000;
```
#### 3. Perform GPU computations
```c++
/* GPU Computation and timing */
Solution<double> solution1 = solve_bse_explicit<type>(s_max, expiry, sigma, rate, strike_price, s_nodes, t_nodes);
Solution<double> solution2 = solve_bse_cn<type>(s_max, expiry, sigma, rate, strike_price, s_nodes, t_nodes);
SimulationResults<double> solution3 = simulate<double>(initial_stock_price, rate, sigma, time, num_of_simulations, time_steps);
```
#### 4. Output Execution Time
```c++
/* Output timing information */
std::cout << "[GPU] Explicit method finished in " << solution1.m_duration << "s" << std::endl;
std::cout << "[GPU] Crank Nicolson method finished in " << solution2.m_duration << "s" << std::endl;
std::cout << "[GPU] GBM method finished in " << solution3.m_duration << "s" << std::endl;
```
#### 5. Download results from GPU to host memory
```c++
/* 3. Download results from GPU to host */
double *host_grid1 = new double[solution1.grid_size()];
solution1.download(host_grid1);
double *host_grid2 = new double[solution2.grid_size()];
solution2.download(host_grid2);
double *host_grid3 = new double[solution3.grid_size()];
solution3.download(host_grid3);
```
#### 6. Export results to CSV
```c++
/* Export the results to CSV */
std::cout << solution1;
std::cout << solution2;
std::cout << solution3;
```

#### 7. Memory Cleanup
```c++
delete[] host_grid1;
delete[] host_grid2;
delete[] host_grid3;
```
175 changes: 154 additions & 21 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,30 +1,163 @@
# PDE Solvers
# PDESolvers ૮₍ ˶•⤙•˶ ₎ა

This repository contains a collection of numerical solvers for solving Partial Differential Equations (PDEs). As of now, it covers the following equations:
A Python package for solving partial differential equations (PDEs), including the one-dimensional heat equation and the Black-Scholes equation, using numerical methods such as explicit and Crank-Nicolson finite difference schemes. Features include built-in plotting, benchmarking and support for financial applications such as option pricing.

- **1D Heat Equation**
- **Black-Scholes Equation**
## 📦 Installation
The pdesolvers package can be installed using pip. To install the package, run the following command:
```
pip install pdesolvers
```
Updating the package to its latest version can be done with:
```
pip install --upgrade pdesolvers
```

Additional features include:
- **Geometric brownian motion** : used to simulate multiple price paths, given the current price of an asset
It includes two key components:
## 🧩 Supported Features
### Solvers
- ✅ **Explicit method**
- ✅ **Crank-Nicolson method**

- **Python Library**: A general-purpose solver for PDEs implemented using numerical methods.
- **CUDA Library**: A GPU-accelerated version of the solvers for faster and efficient computations.
### Equations
- ✅ **1D Heat Equation**
- ✅ **Black-Scholes Equation for vanilla European options**

Numerical Methods used to solve partial differential equations:
- **Explicit Method**
- **Crank-Nicolson Method**
### Pricing Methods
- ✅ **Monte Carlo Pricing**
- ✅ **Analytical Black-Scholes formula**

## Requirements
## 📁 Project Structure
```plaintext
PDESolvers/
├── pdesolvers/ # Main Python package
│ ├── enums/ # Enum definitions (e.g., option types, greeks)
│ ├── optionspricing/ # Modules for Monte Carlo and Black-Scholes pricing
│ ├── pdes/ # PDE definitions (HeatEquation, BlackScholesEquation, etc.)
│ ├── solution/ # Solution classes (Solution1D, SolutionBlackScholes, etc.)
│ ├── solvers/ # Explicit, Crank-Nicolson, etc.
│ ├── tests/ # Unit tests for Python components
│ ├── utils/ # Helper functions
│ ├── __init__.py # Makes it a package
├── GPUSolver/ # GPU-accelerated module
│ ├── cpu/ # CPU-side implementations (C++)
│ ├── gpu/ # CUDA kernels and GPU logic
│ ├── tests/ # Tests for GPU and C++ logic
```

### Python Library
## 📊 Export Options
Use **_export=True_** flags in plotting functions or benchmarking methods to export:
- **PDF**: Save plots as PDF files.
- **CSV**: Save benchmark results as CSV files.

- NumPy
- SciPy
- Matplotlib for visualizations
## 🚀 Usage
To use the package, you can import the desired modules and classes and create an instance of the solvers.

Install the required python packages:
```bash
pip install -r requirements.txt
### Example usage of the 1D heat equation solver
```python
from pdesolvers import HeatEquation, Heat1DExplicitSolver, Heat1DCNSolver
import numpy as np

equation = (HeatEquation(1, 100,30,10000, 0.01)
.set_initial_temp(lambda x: np.sin(np.pi * x) + 5)
.set_left_boundary_temp(lambda t: 20 * np.sin(np.pi * t) + 5)
.set_right_boundary_temp(lambda t: t + 5))

solution1 = Heat1DCNSolver(equation).solve()
solution2 = Heat1DExplicitSolver(equation).solve()

result = solution1.get_result()
solution1.plot()
```

### Example usage of the Black-Scholes equation solver
```python
from pdesolvers import BlackScholesEquation, BlackScholesExplicitSolver, BlackScholesCNSolver, OptionType, Greeks

equation = BlackScholesEquation(OptionType.EUROPEAN_CALL, 300, 295, 0.05, 0.2, 1, 100, 10000)

solution1 = BlackScholesExplicitSolver(equation).solve()
solution2 = BlackScholesCNSolver(equation).solve()

solution1.plot()
solution1.plot_greek(Greeks.GAMMA)
solution2.get_execution_time()
```

### Example usage of Monte Carlo Pricing
```python
from pdesolvers import MonteCarloPricing, OptionType

pricing = MonteCarloPricing(OptionType.EUROPEAN_CALL, 300, 290, 0.05, 0.2, 1, 365, 1000, 78)
option_price = pricing.get_monte_carlo_option_price()

pricing.plot_price_paths()
pricing.plot_distribution_of_payoff()
pricing.plot_distribution_of_final_prices()
```

### Example usage of Analytical Black-Scholes formula
```python
from pdesolvers import BlackScholesFormula, OptionType

pricing = BlackScholesFormula(OptionType.EUROPEAN_CALL, 300, 290, 0.05, 0.2, 1)
option_price = pricing.get_black_scholes_merton_price()
```

### Using Real Historical Data
```python
from pdesolvers import HistoricalStockData, MonteCarloPricing, OptionType

ticker = 'NVDA'

historical_data = HistoricalStockData(ticker)
historical_data.fetch_stock_data( "2024-02-28","2025-02-28")

sigma, mu = historical_data.estimate_metrics()
initial_price = historical_data.get_initial_stock_price()
closing_prices = historical_data.get_closing_prices()

pricing = MonteCarloPricing(OptionType.EUROPEAN_CALL, initial_price, 160, mu, sigma, 1, len(closing_prices), 1000, 78)

pricing.plot_price_paths(export=True)
```
> 📝 **Note:** You don't necessarily need to use the HistoricalStockData class — you're free to use raw yfinance data directly.
Use the built-in tools only if you want to estimate metrics like volatility or mean return.

### 📊 Comparing Interpolated Grid Solutions
```python
from pdesolvers import BlackScholesEquation, BlackScholesExplicitSolver, BlackScholesCNSolver, OptionType

equation1 = BlackScholesEquation(OptionType.EUROPEAN_CALL, S_max=300, K=100, r=0.05, sigma=0.2, expiry=1, s_nodes=100, t_nodes=1000)
equation2 = BlackScholesEquation(OptionType.EUROPEAN_CALL, S_max=300, K=100, r=0.05, sigma=0.2, expiry=1)

solution1 = BlackScholesExplicitSolver(equation1).solve()
solution2 = BlackScholesCNSolver(equation1).solve()

error = solution1 - solution2
```

### 📊 Additional Benchmarks
```python
from pdesolvers import MonteCarloPricing, BlackScholesFormula, OptionType

num_simulations_list = [ 20, 50, 100, 250, 500, 1000, 2500]

pricing_1 = BlackScholesFormula(OptionType.EUROPEAN_CALL, 300, 290, 0.05, 0.2, 1)
pricing_2 = MonteCarloPricing(OptionType.EUROPEAN_CALL, 300, 290, 0.05, 0.2, 1, 365, 1000000, 78)

bs_price = pricing_1.get_black_scholes_merton_price()
monte_carlo_price = pricing_2.get_monte_carlo_option_price()

pricing_2.get_benchmark_errors(bs_price, num_simulations_list=num_simulations_list)
pricing_2.plot_convergence_analysis(bs_price, num_simulations_list=num_simulations_list, export=True)
```
> 📝 **Note:** The export flag used in the example above will save the plot as a PDF file in the current working directory.

## 🧠 Limitations
- The package currently supports only one-dimensional PDEs.
- Currently limited to vanilla European options.
- GPU acceleration only implemented for finite difference methods.

> 📝 **Note:** The Python and C++/CUDA libraries are currently developed as separate components and are not integrated. The Python library can be used independently via PyPI, while the GPU-accelerated solvers are available as a standalone C++/CUDA project.

## 🔒 License
This project is licensed under the Apache License 2.0. See the [LICENSE](./LICENSE.md) file for details.
Loading