diff --git a/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/asian_option.py b/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/asian_option.py new file mode 100644 index 00000000..e69de29b diff --git a/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/fig_1.ipynb b/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/fig_1.ipynb index 230633fa..eb7aa223 100644 --- a/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/fig_1.ipynb +++ b/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/fig_1.ipynb @@ -67,7 +67,7 @@ "outputs": [], "source": [ "S = simulation.S\n", - "psi_T = simulation.terminal_value()\n", + "psi_T = simulation.state()\n", "psi_0 = simulation.run(n_iters=2)\n", "psi_a = settings.analytical_solution(S)" ] diff --git a/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/setup1_european_corridor.py b/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/setup1_european_corridor.py index ed735c7e..459d0e32 100644 --- a/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/setup1_european_corridor.py +++ b/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/setup1_european_corridor.py @@ -21,10 +21,11 @@ def __init__(self, *, n_iters: int = 2, l2_opt: int = 2, C_opt: float = 0.034): self.l2_opt = l2_opt self.C_opt = C_opt + def terminal_condition(self, S: np.ndarray): + return np.exp(-self.r * self.T) * self.payoff(S) + def payoff(self, S: np.ndarray): - return np.exp(-self.r * self.T) * ( - np.maximum(0, self.K2 - S) - np.maximum(0, self.K1 - S) - ) + return np.maximum(0, self.K2 - S) - np.maximum(0, self.K1 - S) def analytical_solution(self, S: np.ndarray): return BS73.p_euro( diff --git a/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/simulation.py b/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/simulation.py index c2cb6fe5..5ad8ee75 100644 --- a/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/simulation.py +++ b/examples/PyMPDATA_examples/Arabas_and_Farhat_2020/simulation.py @@ -108,5 +108,6 @@ def call(self, psi, step): return self.solvers[n_iters].advectee.get() - def terminal_value(self): + def state(self): + """returns the state for MPDATA solution""" return self.solvers[1].advectee.get() diff --git a/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/Mkhize_2007.py b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/Mkhize_2007.py new file mode 100644 index 00000000..345a7ff1 --- /dev/null +++ b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/Mkhize_2007.py @@ -0,0 +1,11 @@ +import numpy as np +from scipy.stats import norm + +def geometric_mkhize(s_t=100, K=100, r=0.008, sigma=0.2, T=30, T_0=0): + d_1 = (np.log(s_t / K) + 0.5 * (r + (sigma ** 2) / 6) * (T - T_0)) / (sigma * np.sqrt((T - T_0) / 3)) + d_2 = d_1 - sigma * np.sqrt((T - T_0) / 3) + C_0 = s_t * np.exp(-0.5 * (r + (sigma ** 2) / 6) * (T - T_0)) * norm.cdf(d_1) - K * np.exp( + -r * (T - T_0)) * norm.cdf(d_2) + P_0 = K * np.exp(-r * (T - T_0)) * norm.cdf(-d_2) - s_t * np.exp( + -0.5 * (r + (sigma ** 2) / 6) * (T - T_0)) * norm.cdf(-d_1) + return C_0 \ No newline at end of file diff --git a/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/__init__.py b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/__init__.py new file mode 100644 index 00000000..e69de29b diff --git a/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/analytic_solution.ipynb b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/analytic_solution.ipynb new file mode 100644 index 00000000..69d0b307 --- /dev/null +++ b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/analytic_solution.ipynb @@ -0,0 +1,714 @@ +{ + "cells": [ + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "[![preview notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyMPDATA/blob/main/examples/PyMPDATA_examples/asian-option/analytic_solution.ipynb)\n", + "[![launch on mybinder.org](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyMPDATA.git/main?urlpath=lab/tree/examples/PyMPDATA_examples/asian-option/analytic_solution.ipynb)\n", + "[![launch on Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyMPDATA/blob/main/examples/PyMPDATA_examples/asian-option/analytic_solution.ipynb)" + ], + "id": "7505cd43445fc1c3" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": [ + "# Asian option analytical solution\n", + "This notebook contains the analytical solution for the Asian option. The solution is based on the following references:\n", + "- [Kemna, A. G. Z., & Vorst, A. C. F. (1990)](https://ideas.repec.org/a/eee/jbfina/v14y1990i1p113-129.html)\n", + "- [Mkhize, N. (2007)](http://hdl.handle.net/10413/429)" + ], + "id": "a0685c1dc4186f3f" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-01-09T23:25:35.911076Z", + "start_time": "2025-01-09T23:25:35.836397Z" + } + }, + "cell_type": "code", + "source": [ + "import sys\n", + "if 'google.colab' in sys.modules:\n", + " !pip --quiet install open-atmos-jupyter-utils\n", + " from open_atmos_jupyter_utils import pip_install_on_colab\n", + " pip_install_on_colab('PyMPDATA-examples')" + ], + "id": "fdb84f8c5aaa41aa", + "outputs": [], + "execution_count": 1 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:08:35.830405Z", + "start_time": "2025-03-02T12:08:29.104822Z" + } + }, + "cell_type": "code", + "source": [ + "import numpy as np\n", + "from scipy.stats import norm\n", + "import matplotlib.pyplot as plt" + ], + "id": "initial_id", + "outputs": [], + "execution_count": 1 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:36:40.001223Z", + "start_time": "2025-03-02T12:36:39.985285Z" + } + }, + "cell_type": "code", + "source": [ + "r = 0.008\n", + "sigma = 0.2\n", + "s_t = 100\n", + "T = 30\n", + "K = 100\n", + "T_0 = 0\n", + "t = 0" + ], + "id": "30dc1eab9cd3b037", + "outputs": [], + "execution_count": 30 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "kemna vorst p 11", + "id": "d359e0f303c92ce0" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:36:40.628643Z", + "start_time": "2025-03-02T12:36:40.612713Z" + } + }, + "cell_type": "code", + "source": [ + "def kemna_vorst(s_t=100, K=100, r=0.008, sigma=0.2, T=30):\n", + " d_star = (1/2)*(r-(sigma**2) / 6)*T\n", + " d = (np.log(s_t/K) + (1/2)*(r - (sigma**2) / 6)*T)/(sigma*np.sqrt(T/3))\n", + " C_val = np.exp(-r*T)*(np.exp(d_star)*s_t*norm.cdf(d) - K*norm.cdf(d-sigma*np.sqrt(T/3)))\n", + " return C_val" + ], + "id": "92b4e2ba2aa9fe45", + "outputs": [], + "execution_count": 31 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:36:41.199663Z", + "start_time": "2025-03-02T12:36:41.167996Z" + } + }, + "cell_type": "code", + "source": "kemna_vorst()", + "id": "c36486141e47980e", + "outputs": [ + { + "data": { + "text/plain": [ + "19.586510526934802" + ] + }, + "execution_count": 32, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 32 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "Mkhize p 70, continuous fixed strike geometric average call option", + "id": "60b556dfa4b1476" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:42:41.481442Z", + "start_time": "2025-03-02T12:42:41.465770Z" + } + }, + "cell_type": "code", + "source": [ + "def geometric_mkhize_general(s_t=100, K=100, r=0.008, sigma=0.2, T=30, t=0):\n", + " s_wave_t = s_t ** ((T-t)/T)\n", + " d1 = (T* np.log(s_wave_t/K) + 0.5 * (r - 0.5 * sigma**2) * (T-t)**2 + (sigma**2 * (T-t)**3)/(3*T))/(sigma * np.sqrt(((T-t)**3)/3))\n", + " d2 = (T * np.log(s_wave_t/K) + 0.5 * (r - 0.5 * sigma**2) * (T-t)**2)/(sigma * np.sqrt(((T-t)**3)/3))\n", + " C_G = np.exp(-r*(T-t)) * (s_t * np.exp(((r-0.5*sigma**2)*((T-t)**2))/(2*T) + (sigma**2*((T-t)**3))/(6*T**2))*norm.cdf(d1) - K*norm.cdf(d2))\n", + " P_G = np.exp(-r*(T-t)) * (K*norm.cdf(-d2) - s_t * np.exp((r-0.5*sigma**2)*((T-t)**2)/(2*T) + (sigma**2*(T-t)**3)/(6*T**2))*norm.cdf(-d1))\n", + " return C_G, P_G" + ], + "id": "8f79b7d8fc8e11e4", + "outputs": [], + "execution_count": 39 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "Mkhize p 69, continuous fixed strike geometric average call option, at t = T_0, should be the same as the previous one", + "id": "41d38b51906947f9" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:42:42.488227Z", + "start_time": "2025-03-02T12:42:42.464874Z" + } + }, + "cell_type": "code", + "source": [ + "def geometric_mkhize(s_t=100, K=100, r=0.008, sigma=0.2, T=30):\n", + " d_1 = (np.log(s_t/K) + 0.5*(r - (sigma**2)/6)*(T-T_0))/(sigma*np.sqrt(T/3))\n", + " d_2 = d_1 - sigma*np.sqrt(T/3)\n", + " C_0 = s_t* np.exp(-0.5 * (r + (sigma**2)/6)*T)*norm.cdf(d_1) - K*np.exp(-r*T)*norm.cdf(d_2)\n", + " P_0 = K*np.exp(-r*T)*norm.cdf(-d_2) - s_t*np.exp(-0.5*(r + (sigma**2)/6)*T)*norm.cdf(-d_1)\n", + " return C_0, P_0" + ], + "id": "e65fc43add329912", + "outputs": [], + "execution_count": 40 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:42:43.070657Z", + "start_time": "2025-03-02T12:42:43.025335Z" + } + }, + "cell_type": "code", + "source": "assert np.allclose(geometric_mkhize(), geometric_mkhize_general(t=0), rtol=1e-5)", + "id": "35b70b81099eee98", + "outputs": [ + { + "ename": "AssertionError", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[1;31mAssertionError\u001B[0m Traceback (most recent call last)", + "Cell \u001B[1;32mIn[41], line 1\u001B[0m\n\u001B[1;32m----> 1\u001B[0m \u001B[38;5;28;01massert\u001B[39;00m np\u001B[38;5;241m.\u001B[39mallclose(geometric_mkhize(), geometric_mkhize_general(t\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m0\u001B[39m), rtol\u001B[38;5;241m=\u001B[39m\u001B[38;5;241m1e-5\u001B[39m)\n", + "\u001B[1;31mAssertionError\u001B[0m: " + ] + } + ], + "execution_count": 41 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:42:53.061909Z", + "start_time": "2025-03-02T12:42:52.598636Z" + } + }, + "cell_type": "code", + "source": [ + "K_s = np.linspace(80, 120, 100)\n", + "C_kemna = []\n", + "C_geometric = []\n", + "for K in K_s:\n", + " C_kemna.append(kemna_vorst(K=K))\n", + " C_geometric.append(geometric_mkhize(K=K)[0])\n", + "\n", + "plt.plot(K_s, C_kemna, label='kemna vorst', color='red')\n", + "plt.plot(K_s, C_geometric, label='geometric', color='blue')\n", + "plt.legend()\n", + "plt.xlabel('strike price')\n", + "plt.ylabel('option price')\n", + "plt.show()" + ], + "id": "b793168df3f837f6", + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjMAAAGwCAYAAABcnuQpAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAABdtElEQVR4nO3dd1xV9eMG8OdetkxRpgwVFVFGoEiAwHVry5GVRo5yNNyZlpVZVmJWalrpt6WZOdI0TUsz9YJsWeJAQEVBBVGJLfN+fn+U9xc5GAKHC8/79bqvl/ecc899Dhe6T2d8jkwIIUBERESkoeRSByAiIiJ6ECwzREREpNFYZoiIiEijscwQERGRRmOZISIiIo3GMkNEREQajWWGiIiINJq21AGamkqlwtWrV2FsbAyZTCZ1HCIiIqoDIQSKiopga2sLufz++15afZm5evUq7O3tpY5BREREDZCVlQU7O7v7LtPqy4yxsTGAv38YJiYmEqchIiKiuigsLIS9vb36e/x+Wn2ZuX1oycTEhGWGiIhIw9TlFBGeAExEREQajWWGiIiINBrLDBEREWm0Vn/ODBERSU+lUqGiokLqGNSC6OjoQEtLq1HWxTJDRERNqqKiAhkZGVCpVFJHoRbGzMwM1tbWDzwOHMsMERE1GSEEsrOzoaWlBXt7+1oHP6O2QQiB0tJS5ObmAgBsbGweaH0sM0RE1GSqqqpQWloKW1tbtGvXTuo41IIYGBgAAHJzc2FpaflAh5xYkYmIqMlUV1cDAHR1dSVOQi3R7YJbWVn5QOthmSEioibHe+PR3TTW7wXLDBEREWk0lhkiIiLSaCwzRERE/6FQKDB37lypY1Adscw8gH3vxKK6olrqGERERC1OcxZClpkGWjZUicff74dprpFQVXEgKCIiajta2mjOLDMN5OSiCy1UYUN6AKb1imChISKqCyGAkhJpHkI0OPb+/fthamqKH3/8EQCQlZWFp59+GmZmZjA3N8fIkSNx8eJF9fKTJ0/GqFGjsGzZMlhZWcHMzAxLly5FVVUVFixYAHNzc9jZ2WHDhg3q11y8eBEymQy7du3CgAED0K5dO3h4eCAqKkq9zM2bNzF+/Hh06tQJ7dq1g5ubG7Zu3XrP3IWFhTAwMMDvv/9eY/ru3bthbGyM0tJSAMDJkycxcOBAGBgYoEOHDpg+fTqKi4vv2J4PP/wQtra2cHZ2BgB8+eWX6N69O/T19WFlZYWxY8eqlw8NDcVnn30GmUwGmUxW4+fT2FhmGuiZz/yweVYs5KjGd+kBeNE1nIWGiKg2paWAkZE0j3++uOtry5YtGD9+PH788UcEBwejsrISw4YNg7GxMY4dO4aIiAgYGRlh+PDhNfZYHDlyBFevXkVYWBhWrlyJJUuW4LHHHkP79u0RExODl156CS+++CIuX75c4/3eeustvPbaa0hKSkKPHj0wfvx4VFVVAQDKysrQp08f7N+/H6dOncL06dMxYcIExMbG3jW7iYkJHnvsMWzZsqXG9B9//BGjRo1Cu3btUFJSgmHDhqF9+/Y4fvw4duzYgT///BMzZ86s8ZrDhw8jNTUVhw4dwr59+xAXF4fZs2dj6dKlSE1NxYEDBxAYGAgA+Oyzz+Dr64tp06YhOzsb2dnZsLe3b9DPv05EK1dQUCAAiIKCgiZZ/5aZEUKOKgEIMa1nqKiurG6S9yEi0kS3bt0SZ86cEbdu3fp7QnGxEH/vI2n+R3FxnXMHBQWJOXPmiM8//1yYmpoKpVKpnvfDDz8IZ2dnoVKp1NPKy8uFgYGBOHjwoBBCiEmTJglHR0dRXf3/3wnOzs4iICBA/byqqkoYGhqKrVu3CiGEyMjIEADEN998o17m9OnTAoBISUm5Z9ZHH31UzJ8//57zd+/eLYyMjERJSYkQ4u/vRX19ffH7778LIYT46quvRPv27UXxv34++/fvF3K5XOTk5Ki3x8rKSpSXl6uX+fnnn4WJiYkoLCy86/ve/hnezx2/H/9Sn+9v3s7gAY1f6wehisCELx/G12cDIXMLw7qT/SHX5k4vIqI7tGsH/OvwRbO/dz3s3LkTubm5iIiIgLe3t3r6iRMncO7cORgbG9dYvqysDOfPn1c/7927d417UVlZWcHV1VX9XEtLCx06dFDfn+g2d3d39b9v37MoNzcXPXv2RHV1NZYtW4affvoJV65cQUVFBcrLy+97q4hHHnkEOjo62Lt3L8aNG4eff/4ZJiYmGDx4MAAgJSUFHh4eMDQ0VL/G398fKpUKqampsLKyAgC4ubnVGMl5yJAhcHR0RNeuXTF8+HAMHz4co0ePluS2FSwzjeDZL/yhUkVg0vqH8dXZQMjcw/BlMgsNEdEdZDLgX1+aLZmnpycSEhLw3XffoW/fvurRaouLi9GnTx/1+TP/ZmFhof63jo5OjXkymeyu0/57N/F/L3P7PW8v8/HHH+Ozzz7D6tWr4ebmBkNDQ8ydO/e+J+Tq6upi7Nix2LJlC8aNG4ctW7bgmWeegbZ2/SqA4X8+N2NjYyQkJECpVOKPP/7AO++8g3fffRfHjx+HmZlZvdb9oPht20ieW+eP71+Khgwq/C8lEK+48xwaIiJN5uTkhKNHj2LPnj2YNWuWerqXlxfS09NhaWmJbt261XiYmpo2aaaIiAiMHDkSzz33HDw8PNC1a1ekpaXV+rrg4GAcOHAAp0+fxpEjRxAcHKye5+LighMnTqCkpKTG+8jlcvWJvveira2NwYMHY8WKFUhOTsbFixdx5MgRAH+XqNv35mpqLDON6Ll1/vj+xUgWGiKiVqJHjx44evQofv75Z/WYKcHBwejYsSNGjhyJY8eOISMjA0qlErNnz77jZN7G1r17dxw6dAiRkZFISUnBiy++iGvXrtX6usDAQFhbWyM4OBhdunSBj4+Pel5wcDD09fUxadIknDp1CkePHsWsWbMwYcIE9SGmu9m3bx/WrFmDpKQkXLp0CZs2bYJKpVIXoM6dOyMmJgYXL17EjRs37tgD1ZhYZhrZhPX9WWiIiFoRZ2dnHDlyBFu3bsX8+fPRrl07hIWFwcHBAWPGjIGLiwumTJmCsrIymJiYNGmWt99+G15eXhg2bBgUCgWsra0xatSoWl8nk8kwfvx4nDhxosZeGeDvO1cfPHgQeXl58Pb2xtixYzFo0CB8/vnn912nmZkZdu3ahYEDB8LFxQXr16/H1q1b0bt3bwDAa6+9Bi0tLfTq1QsWFhbIzMxs8HbXun1CPMCF9xqgsLAQpqamKCgoaPJfsn/74aVwTPqfHwTkmN6TJwUTUdtUVlaGjIwMdOnSBfr6+lLHoRbmfr8f9fn+5rdrE/n3HpqvzgbiJTfuoSEiImoKLDNNaML6/tj0UhTkqMbXZwM5sB4REVETYJlpYs+t88eml6MhRzW+SQ3E9N689QEREVFjYplpBsFf+uOHV/4uNN+mBWAq7+VERETUaFhmmsmzX/jjx1kxkKMaG9ID8ELPSFRXNM/190RERK0Zy0wzGrfGD1vnxkALVfj+fH9M7hnFQkNERPSAWGaa2dOr/LDt1ePQRiU2Z/THhB7RqCqrkjoWERGRxmKZkcDYT33x08J4aKMSWy/547kesSw0REREDcQyI5HRHz2MnYsSoIMKbM/yw7hux1FZWil1LCIiamMmT55cp1GEWzKWGQmNXOaDXYuToIty/HzFF093i0dF8b3vfEpERFQXnTt3xurVq+u07GeffYaNGzc2aZ6mJmmZCQkJgbe3N4yNjWFpaYlRo0YhNTX1juWioqIwcOBAGBoawsTEBIGBgbh165YEiRvfY0v74Zf3kqGHMvyS/TCedEpCeWG51LGIiKiVq66uhkqlgqmpKczMzKSO80AkLTOhoaGYMWMGoqOjcejQIVRWVmLo0KE1bkMeFRWF4cOHY+jQoYiNjcXx48cxc+ZMyOWtZ6fSiHe8sXfZaejjFvbl9sMop2TcymsdZY2ISFMVFRUhODgYhoaGsLGxwapVq6BQKNR3zy4vL8drr72GTp06wdDQED4+PlAqlTXW8fPPP6N3797Q09ND586d8emnn9aY37lzZ3zwwQeYOHEijIyM4OjoiL179+L69esYOXIkjIyM4O7ujri4uBqvCw8PR0BAAAwMDGBvb4/Zs2ervzsVCgUuXbqEefPmQSaTQSaTAQA2btwIMzMz7N27F7169YKenh4yMzPvOMykUqmwYsUKdOvWDXp6enBwcMCHH37YuD/cxiZakNzcXAFAhIaGqqf5+PiIt99+u87rKCsrEwUFBepHVlaWACAKCgqaInKjOvxJgmiHYgEIMdg8TpRcL5E6EhHRA7l165Y4c+aMuHXrlhBCCJVKiOJiaR4qVf2yT506VTg6Ooo///xTnDx5UowePVoYGxuLOXPmqOf7+fmJsLAwce7cOfHxxx8LPT09kZaWJoQQIi4uTsjlcrF06VKRmpoqNmzYIAwMDMSGDRvU7+Ho6CjMzc3F+vXrRVpamnj55ZeFiYmJGD58uPjpp59EamqqGDVqlHBxcRGqfzbg3LlzwtDQUKxatUqkpaWJiIgI4enpKSZPniyEEOLmzZvCzs5OLF26VGRnZ4vs7GwhhBAbNmwQOjo6ws/PT0RERIizZ8+KkpISMWnSJDFy5Eh1poULF4r27duLjRs3inPnzoljx46Jr7/+ugGffu3++/vxbwUFBXX+/m5RZSY9PV0AECdPnhRCCHHt2jUBQKxZs0b4+voKS0tLERgYKI4dO3bPdSxZskQAuOOhCWVGCCFC1yQJQxQJQAiFWYIoyi6SOhIRUYP998uquFgIQJpHcXHdcxcWFgodHR2xY8cO9bT8/HzRrl07MWfOHHHp0iWhpaUlrly5UuN1gwYNEosWLRJCCPHss8+KIUOG1Ji/YMEC0atXL/VzR0dH8dxzz6mfZ2dnCwBi8eLF6mlRUVECgLqUTJkyRUyfPr3Geo8dOybkcrn65+zo6ChWrVpVY5kNGzYIACIpKanG9H+XmcLCQqGnp9dk5eW/GqvMtJhjNSqVCnPnzoW/vz9cXV0BABcuXAAAvPvuu5g2bRoOHDgALy8vDBo0COnp6Xddz6JFi1BQUKB+ZGVlNds2NIbAWR44+OUFGKMQynxPDO9xAYWXC6WORUTUply4cAGVlZXo16+fepqpqSmcnZ0BACdPnkR1dTV69OgBIyMj9SM0NBTnz58HAKSkpMDf37/Gev39/ZGeno7q6v8fMNXd3V39bysrKwCAm5vbHdNyc3MBACdOnMDGjRtrvO+wYcOgUqmQkZFx3+3S1dWt8X7/lZKSgvLycgwaNOi+62lptKUOcNuMGTNw6tQphIeHq6epVH/fv+jFF1/E888/DwDw9PTE4cOH8d133yEkJOSO9ejp6UFPT695QjcR/5fdcUj3FIZNtUdEkTuG9jyFA6ftYeZoKnU0IqIH0q4dUFws3Xs3luLiYmhpaSE+Ph5aWlo15hkZGdVrXTo6Oup/3z6/5W7Tbn8nFhcX48UXX8Ts2bPvWJeDg8N938vAwEC9vnvN10QtoszMnDkT+/btQ1hYGOzs7NTTbWxsAAC9evWqsbyLiwsyMzObNWNz85niiiP6KRgyoRoxJa4Y3OsM/khWwdypvdTRiIgaTCYDDA2lTlG7rl27QkdHB8ePH1cXhIKCAqSlpSEwMBCenp6orq5Gbm4uAgIC7roOFxcXRERE1JgWERGBHj163FGA6sPLywtnzpxBt27d7rmMrq5ujb0/ddW9e3cYGBjg8OHDmDp1aoMzNjdJDzMJITBz5kzs3r0bR44cQZcuXWrM79y5M2xtbe+4XDstLQ2Ojo7NGVUSXsEuOLLtOjrKbiC+tBcGuObiesoNqWMREbV6xsbGmDRpEhYsWICjR4/i9OnTmDJlCuRyOWQyGXr06IHg4GBMnDgRu3btQkZGBmJjYxESEoL9+/cDAObPn4/Dhw/j/fffR1paGr7//nt8/vnneO211x4o2+uvv47IyEjMnDkTSUlJSE9Px549ezBz5kz1Mp07d0ZYWBiuXLmCGzfq/r2hr6+P119/HQsXLsSmTZtw/vx5REdH49tvv32gzE1N0jIzY8YMbN68GVu2bIGxsTFycnKQk5OjHkNGJpNhwYIFWLNmDXbu3Ilz585h8eLFOHv2LKZMmSJl9Gbj8bQzlLvzYSXPRXKZMxSe+chOuiZ1LCKiVm/lypXw9fXFY489hsGDB8Pf3x8uLi7Q19cHAGzYsAETJ07E/Pnz4ezsjFGjRtXYk+Pl5YWffvoJ27Ztg6urK9555x0sXboUkydPfqBc7u7uCA0NRVpaGgICAuDp6Yl33nkHtra26mWWLl2KixcvwsnJCRYWFvVa/+LFizF//ny88847cHFxwTPPPKM+X6elkgkhhGRvfo/jdhs2bKjxYS9fvhxffPEF8vLy4OHhgRUrVqB///51eo/CwkKYmpqioKAAJiYmjRFbEmkHMzDwEX1cUdmgu04GjkTow87bRupYRET3VVZWhoyMDHTp0kVdAjRVSUkJOnXqhE8//bTN/A91U7vf70d9vr8lLTPNobWUGQC4oMzEwMFyXKq2QxftTBw5Kkfn/na1v5CISCKaXGYSExNx9uxZ9OvXDwUFBVi6dCmUSiXOnTuHjh07Sh2vVWisMtNiLs2m2nVVOCA0FHDSvoSMKgcEKmRIP3RR6lhERK3WJ598Ag8PDwwePBglJSU4duwYi0wL1CKuZqK6c/S3Q2hUNgb5X0BqRVcEDc/Bn7vPodcT9z6rnYiI6s/T0xPx8fFSx6A64J4ZDdSprw1C443hpp+GbJU1gkaZIWn7nTfoJCIiagtYZjSUlasFjiZ3hJdBCm6Ijhgw3grHvz8jdSwiortq5adnUgM11u8Fy4wG69DdHIdTbOFrdBL5wgyDJtsh/MtkqWMREandHhyuoqJC4iTUEpWWlgKoOeJxQ/CcGQ1n5miKP9K74HGXRCjzPTFshhP2liRg0AIvqaMREUFbWxvt2rXD9evXoaOjA7mc/w9Nf++RKS0tRW5uLszMzB5oRGSAl2a3GqU3SjGm5xkcvNkXeijDzsXJeGxpv9pfSETUxCoqKpCRkaG+txDRbWZmZrC2tr7ruHMcZ+Zf2kqZAYDywnKM65mIX7IfhjYqsWVeHJ5a6St1LCIiqFQqHmqiGnR0dO67R6Y+3988zNSK6Jno4adzfTCpVwS2XvLHuFX9cKs4HBO/qttoyURETUUul2vcoHmkOXjwspXRaaeDH9IexpQex6CCFiZ93R/rxodJHYuIiKjJsMy0Qlq6WvjqtD9me4QCAF7ZFoiPH1VKG4qIiKiJsMy0UnJtOVYnBOJNPyUAYOFvCiwJUkKoWvUpUkRE1AaxzLRiMrkMH0YosGyoEgCwNEyB+d6hLDRERNSqsMy0AYsOKrDmyb8POa1KUOCl3sdQXVEtcSoiIqLGwTLTRszaGYRvJx+DHNX46mwgJvSIRmVppdSxiIiIHhjLTBvywoYAbJ0bA21UYuslf4x1SkBZfpnUsYiIiB4Iy0wb8/QqP/yyJAn6uIW9OT54rOsZFOcUSx2LiIiowVhm2qBH3/XG76tSYYQiHP7LC0O7ZyD/UoHUsYiIiBqEZaaNUsx9CIe/y0R72V+IKnaDomcOrp26LnUsIiKiemOZacP6Pd8boTuuw0qeixNlzgjwKkZm1BWpYxEREdULy0wb5/ZkD4T/cQuOWpeRXtkF/QOA1N8vSB2LiIiozlhmCN0GOSI8Sgs9dc8jq7oTAh41RtL2VKljERER1QnLDAEA7LxtEJZkCk+DFFwXFlCMs0bEumSpYxEREdWKZYbULFw64uhZW/Q3OYECmGLIK91w8MM4qWMRERHdF8sM1WDqYIqD57tjeMfjuIV2ePxtd+x4NUrqWERERPfEMkN3aNexHfZkeOAZ+0hUQhfjVvXDN5OOSR2LiIjorlhm6K50jXTx4zkfTO8ZBhW0MG1TAD5+VCl1LCIiojuwzNA9aelqYf3pALzuowQALPxNgUW+SgiVkDYYERHRv7DM0H3J5DIsj1bgoxFKAMDyaAVe7H0M1RXV0gYjIiL6B8sM1cnC3xT4euIxyFGNr88GYrxTLMoLy6WORURExDJDdTf1+wBsfzUWOqjAjsu+eLzLKd5xm4iIJMcyQ/Uy9lNf7A85CUMU41BeHwzudhE30/OkjkVERG0YywzV25A3+uDwNxdhLstDTIkrAlz/wuXj2VLHIiKiNoplhhrEZ4orjv2Sh07ybKRUOMHftxppBzOkjkVERG0Qyww1WK8nuiEirBo9dDKQWW2H/iOMEL85RepYRETUxrDM0ANx9LfDsUQjeP1zg8oBEzrh6MpEqWMREVEbwjJDD8yytwWOpnXCALNEFMEEw+f3wq6F0VLHIiKiNoJlhhqFiZ0JfstwwRjbaFRAD0997I2vnguTOhYREbUBLDPUaPTN9PFThrf6fk4v/hiID4fw9gdERNS0WGaoUd2+n9Pb/ZUAgLf/VGCOZxhUVSppgxERUavFMkONTiaX4f1jCnw2JhQAsDY5CMFO0agorpA4GRERtUYsM9RkZv8chC0zI6GDCmzL9MNjjidRdLVI6lhERNTKsMxQkxq/1g/7lv3/7Q8Gds/C9ZQbUsciIqJWRNIyExISAm9vbxgbG8PS0hKjRo1CamrqXZcVQmDEiBGQyWT45ZdfmjcoPZChi/rgyHeX0EF2E3GlveDvUYSMsCypYxERUSshaZkJDQ3FjBkzEB0djUOHDqGyshJDhw5FSUnJHcuuXr0aMplMgpTUGPo93xsR+wvgoHUZ6ZVd4DdAFyd+untxJSIiqg9tKd/8wIEDNZ5v3LgRlpaWiI+PR2BgoHp6UlISPv30U8TFxcHGxua+6ywvL0d5ebn6eWFhYeOGpgZzHtEVUbE5GO6fhpNlPRD4jD72XE2CYu5DUkcjIiIN1qLOmSkoKAAAmJubq6eVlpbi2WefxRdffAFra+ta1xESEgJTU1P1w97evsnyUv3Zelkj7KwVAk2TUAhTDJvngp3zo6SORUREGqzFlBmVSoW5c+fC398frq6u6unz5s2Dn58fRo4cWaf1LFq0CAUFBepHVhbPzWhpzBxNcfBiT4y2+Xu04KdX+uDLcaFSxyIiIg0l6WGmf5sxYwZOnTqF8PBw9bS9e/fiyJEjSEys+40L9fT0oKen1xQRqRHpm+ljx0VvzPQMw/ozgZixPQhXLyvxflgQZHKeG0VERHXXIvbMzJw5E/v27cPRo0dhZ2ennn7kyBGcP38eZmZm0NbWhrb2393rySefhEKhkCgtNRYtXS18eTIASwcqAQAfRigwtWc4qsqqpA1GREQaRSaEkOzGOUIIzJo1C7t374ZSqUT37t1rzM/JycGNGzXHJHFzc8Nnn32Gxx9/HF26dKn1PQoLC2FqaoqCggKYmJg0an5qPN9MOoYXN/lBBS08ahmL7Sd7w9DSUOpYREQkkfp8f0t6mGnGjBnYsmUL9uzZA2NjY+Tk5AAATE1NYWBgAGtr67ue9Ovg4FCnIkOaY+r3AbByiMUzH7hif24/DOp6Cr8et4aFS0epoxERUQsn6WGmdevWoaCgAAqFAjY2NurH9u3bpYxFEnn8/X44/L/zMJflIabEFf4eRbigzJQ6FhERtXCS7plpyBEuCY+KUTPwne6GCLsLGP5E6d+D6w3KxW+bUuAV7CJ1NCIiaqFaxAnARP/W85GuiIzVhod+Kq6pLBH0nB3+CImXOhYREbVQLDPUItl6WSMs3QaD2iegGMZ49E13bJoeXvsLiYiozWGZoRbLxM4Ev2W64lnHCFRBB5O+7o9lQ5UQKh5qJCKi/8cyQy2arpEufjjniwXeSgDAW4cUeMXtGMeiISIiNZYZavHk2nKsiFVgzZOhkEGF9WcCMaZzPEpvlEodjYiIWgCWGdIYs3YGYeeCWOjjFn695oOBnS/gesqN2l9IREStGssMaZQxKx7Gn1+mq8ei8fMoxrnDl6SORUREEmKZIY3j/7I7Ivfno7N2Fs5VdobvEEPEfHtK6lhERCQRlhnSSM4juiIqXg992p3BDdERA6Z2xd63YqSORUREEmCZIY1l7W4J5XkHPGJxHLfQDqOX9cWX40KljkVERM2MZYY0mpG1EfZkemJazzCooIUZ24OwsJ8SqiqV1NGIiKiZsMyQxtPW18b/TgfgwyFKAMDHxxUY3zUaZfll0gYjIqJmwTJDrYJMLsObfyjww0sR0EEFfsrywxDHVNxMz5M6GhERNTGWGWpVnlvnj4OfnoYpChBe6AG/3gW4oMyUOhYRETUhlhlqdQa86omIX67DXusK0iq74OGBBrx0m4ioFWOZoVap98huiI7VgqdBCq4LCwyY2hW7X4+WOhYRETUBlhlqtWy9rBF2wV596faTK/ph9Wheuk1E1NqwzFCrdvvS7Zd6hUFAjnm/BGHOQ6GorqiWOhoRETUSlhlq9bT1tfHlyQCseEQJAFhzIghjHONQklsibTAiImoULDPUJsjkMizYr8BP86KghzLszfFBUJdLyE66JnU0IiJ6QCwz1KY8tdIXR/+Xjo6yG4gv7YWH+1bi1O50qWMREdEDYJmhNsd3uhui/yxBD50MZFbbwX+MJQ4tj5c6FhERNRDLDLVJTgMdEZVihkDTJBTCFCMWeeDriWFSxyIiogZgmaE2y9ypPf7IdMFzXcJRDW1M/yEQr/vwJpVERJqGZYbaND0TPWw65493FUoAwIpYBZ7uHIPSG6XSBiMiojpjmaE2TyaXYcnRv29SqYty/HzFFwM6X0BOcq7U0YiIqA5YZoj+8dw6f/y59izMZXmILXHFw14VvNKJiEgDsMwQ/UvATA9EHyxEd50MXKq2g98YKxz8ME7qWEREdB8sM0T/0X1IZ0SnmCHINAlFMMGjbz+EdeN5pRMRUUvFMkN0F+ZO7fHH5V6Y5PT3lU6vbAvEPC/e04mIqCVimSG6B10jXWxI88cHg5UAgNWJQRhlH4+iq0XSBiMiohpYZojuQyaX4a1DCmyfGwl93MK+3H7o73QVWTFXpY5GRET/YJkhqoOnV/lB+c15WMlzkVzmjH5+WojdcFrqWEREBJYZojrzmeKKmLAKuOmnIUdlhaAXuuKneZFSxyIiavNYZojqwdHfDuHp1njE4jjKYIBnVvvhg8FKCJWQOhoRUZvFMkNUTyZ2Jth72QtzPUMBAIsPKzDBKRJl+WUSJyMiaptYZogaQEtXC6sSgvC/4DBooxI/XvTHQPt0XDt1XepoRERtDssM0QOYvjkQBz85BTNZPqKK3dDvoXIk70yTOhYRUZvCMkP0gAbO90TM73+hu04GMqvt4P+UDX5dHCt1LCKiNoNlhqgR9BjWBdEpZhjYPgHFMMbID/rik8d4YjARUXNgmSFqJOZO7XHgshtedAmDgBwL9iswpWc4ygvLpY5GRNSqscwQNSKddjpYdyoAa54MhRzV2JAegMH2Z3E95YbU0YiIWi1Jy0xISAi8vb1hbGwMS0tLjBo1Cqmpqer5eXl5mDVrFpydnWFgYAAHBwfMnj0bBQUFEqYmuj+ZXIZZO4Pw2weJMEUBwgs94O1WhpM/88RgIqKmIGmZCQ0NxYwZMxAdHY1Dhw6hsrISQ4cORUlJCQDg6tWruHr1Kj755BOcOnUKGzduxIEDBzBlyhQpYxPVybC3+iJ6/01007mIS9V28BvLE4OJiJqCTAjRoDMUz507h/PnzyMwMBAGBgYQQkAmkz1QmOvXr8PS0hKhoaEIDAy86zI7duzAc889h5KSEmhra9e6zsLCQpiamqKgoAAmJiYPlI+oIfLO/4WnvDNw5C8vyKBCyPAwLNwfBJn8wf5eiIhas/p8f9d7z8zNmzcxePBg9OjRA4888giys7MBAFOmTMH8+fMblvgftw8fmZub33cZExOTexaZ8vJyFBYW1ngQSen2icEv9fr7xOA3DigwsVsERwwmImok9S4z8+bNg7a2NjIzM9GuXTv19GeeeQYHDhxocBCVSoW5c+fC398frq6ud13mxo0beP/99zF9+vR7rickJASmpqbqh729fYMzETUWnXY6WHc6EJ8/FQotVGFzRn8o7M4hO+ma1NGIiDRevQ8zWVtb4+DBg/Dw8ICxsTFOnDiBrl274sKFC3B3d0dxcXGDgrz88sv4/fffER4eDjs7uzvmFxYWYsiQITA3N8fevXuho6Nz1/WUl5ejvLy8xuvs7e15mIlajMMfJ+Cp17vgL9EeneTZ+GXDX+g7sZfUsYiIWpQmPcxUUlJSY4/MbXl5edDT06vv6gAAM2fOxL59+3D06NG7FpmioiIMHz4cxsbG2L179z2LDADo6enBxMSkxoOoJRm0wAuxhwrhonseV1Q2CJjUBdtmR0odi4hIY9W7zAQEBGDTpk3q5zKZDCqVCitWrMCAAQPqtS4hBGbOnIndu3fjyJEj6NKlyx3LFBYWYujQodDV1cXevXuhr69f38hELU63QY6ISu+IRyyOowwGGL/WD2/5K6GqUkkdjYhI49T7MNOpU6cwaNAgeHl54ciRI3jiiSdw+vRp5OXlISIiAk5OTnVe1yuvvIItW7Zgz549cHZ2Vk83NTWFgYGBusiUlpZi9+7dMDQ0VC9jYWEBLS2tWt+DVzNRS1ZdUY03A45hRawCAPC4VQw2x7nAxI6/q0TUttXn+7tBl2YXFBTg888/x4kTJ1BcXAwvLy/MmDEDNjY29VrPvS7l3rBhAyZPngylUnnPvT0ZGRno3Llzre/BMkOaYPPLEZi6vg/KoY9eeuew9zcdOA10lDoWEZFkmrzMaBKWGdIUsRtOY/RUc1xV2cBcloefPrqIQQu8pI5FRCSJJj0BeMOGDdixY8cd03fs2IHvv/++vqsjon/0e743jh+XoZ/hKeQJcwxb6I7PxoTyzttERLWod5kJCQlBx44d75huaWmJZcuWNUooorbK1ssaoZe7YWLXcFRDG3N3B/HO20REtah3mcnMzLzrVUeOjo7IzMxslFBEbZm+mT42pvtj5Uil+s7bik5pHGCPiOge6l1mLC0tkZycfMf0EydOoEOHDo0Siqitk8llmPeLAr8vS4KZLB/RxW7o20eFmG9PSR2NiKjFqXeZGT9+PGbPno2jR4+iuroa1dXVOHLkCObMmYNx48Y1RUaiNmvooj44fqgAvfTO4arKBoFTu2Pj1HCpYxERtSj1vpqpoqICEyZMwI4dO9Q3e1SpVJg4cSLWr18PXV3dJgnaULyaiVqDoqtFmNDnDPbk+AAAZnuE4pNIP+i0u/do2EREmqxZLs1OS0vDiRMnYGBgADc3Nzg6tswxMVhmqLVQVamwdHAY3gtVAAAGmCXip2gHdHTm4V0ian04zsy/sMxQa7P79WhMXNEbxTCGo9Zl/PJjCR56xrn2FxIRaZBGLzOvvvoq3n//fRgaGuLVV1+977IrV66sX9omxjJDrdHpPecw6iltnKvsDAOU4rtZSRi3xk/qWEREjaY+39/adVlhYmIiKisrAQAJCQn3vA3BvaYTUePqPbIbYlPz8Wy/4zhwwxvj1/ohMUaJZccCoKVb+z3LiIhaEx5mItJg1RXVeDvoGJZHKwAAQ8zjsS22K8yd2ksbjIjoATXZ7QwqKyuhra2NU6c41gVRS6Clq4WQKAW2z41EO5TgUF4f9O1ZhOSdaVJHIyJqNvUqMzo6OnBwcEB1dXVT5SGiBnh6lR+idlxBV+1LyKhygO9TnbB9TqTUsYiImkW9B81766238OabbyIvL68p8hBRA7mP7YHjZ00wtEMcSmGIcWv8sLCfElVlVVJHIyJqUvU+Z8bT0xPnzp1DZWUlHB0dYWhoWGN+QkJCowZ8UDxnhtqa6opqvBV4DB/FKAAAg83jsTWyM8ejISKN0uhXM/3bqFGjGpqLiJqBlq4Wlkcr0OfVKDy/yg1/5vVB396Xsev7FHgFu0gdj4io0fFqJqJW7NTudIx+RgfnKjtDH7fwv2nxmPhVf6ljERHVqllGAI6Li0NKSgoAoFevXujTp09DVtPkWGaorcu/VIBg7zT8dt0bADDTLRSfRvpC16hl3UeNiOjfmrTMXL58GePHj0dERATMzMwAAPn5+fDz88O2bdtgZ2fX4OBNgWWG6O/7Or03KAxLwxQAAH/jZOwIs4LNQ1bSBiMiuocmG2cGAKZOnYrKykqkpKQgLy8PeXl5SElJgUqlwtSpUxscmoiajlxbjvdCFdj7dixMUICIInd49QEi1iVLHY2I6IHVe8+MgYEBIiMj4enpWWN6fHw8AgICUFpa2qgBHxT3zBDVlH7oIkY/XonT5d2hjUqsGhuJGdsDIZPzdiRE1HI06Z4Ze3t79X2a/q26uhq2trb1XR0RNbPuQzoj+qINnraPRBV0MGtnECZ2i0DpjZb1PyJERHVV7zLz8ccfY9asWYiLi1NPi4uLw5w5c/DJJ580ajgiahpG1kbYdtEXnzymhBaqsDmjP/zss3D+yCWpoxER1Vu9DzO1b98epaWlqKqqgrb238PU3P73fwfQawmjBPMwE9H9HV2ZiHGv2SFXWMBMlo/N76Tj0Xe9pY5FRG1ckw6at3r16obmIqIWaMCrnogPyMZTA08iutgNj73njXeOKvHOoQBo6WpJHY+IqFYcNI+IAAAVxRV41S8KX5wMAgAM73gcmyOd0KG7ucTJiKgtatITgImoddI10sXnyUHY9GI4DFCKAze80celFPGbU6SORkR0XywzRFTDhPX9Eb3jMpy0L+FStR38J3TBN5OOSR2LiOieWGaI6A7uY3sg7pwZnrCOQTn0MW1TAKb0OIZbebekjkZEdAeWGSK6KzNHU+zO8sayoUrIUY3v0gPgZ3eJl28TUYvDMkNE9yTXlmPRQQX+WHECFrLrSLrVE30GmeHXxbFSRyMiUqv31UwlJSVYvnw5Dh8+jNzcXKhUqhrzL1y40KgBHxSvZiJqHJePZ+PpgTcQVewGAHjjYSXeP9of2vr1HuGBiKhWTTrOzNSpUxEaGooJEybAxsYGMhnv50LUFth520CZ3QEL+odizYkgLI9WIMYmEVuP2cHK1ULqeETUhtV7z4yZmRn2798Pf3//psrUqLhnhqjxbZsdialr3VECI9jIc7D9s2sImOkhdSwiakWadJyZ9u3bw9ycg2gRtWXj1vjh+K/X4KJ7HtkqawyY1RufPKaEULXqMTiJqIWqd5l5//338c4776C0lHfYJWrLXB5zQuwlKzzrGIFqaGPBfgWetItB/qUCqaMRURtT78NMnp6eOH/+PIQQ6Ny5M3R0dGrMT0hIaNSAD4qHmYiallAJrA8+hrnbfFABPXTVvoSdm27Bc3xPqaMRkQZr0hOAR40a1dBcRNQKyeQyvLw1EN4jzmDsCya4UOUI32fLsGZ/GKZtCoBMzosEiKhp8UaTRNRo8s7/hUl+6diX2w8A8FyXcKyP9oShpaHEyYhI0zTLjSbj4+OxefNmbN68GYmJiQ1dDRG1IuZO7bHnSl8sH66EFqqwOaM/+jlk48zec1JHI6JWrN57ZnJzczFu3DgolUqYmZkBAPLz8zFgwABs27YNFhYta7wJ7pkhkkbY2hMYN9cK2SprtEMJ/vdSEp5bpxlDOhCR9Jp0z8ysWbNQVFSE06dPIy8vD3l5eTh16hQKCwsxe/bsBocmotYlcJYHEk9oYVD7BJTCEBPW+2O6SxhvVklEja7ee2ZMTU3x559/wtvbu8b02NhYDB06FPn5+Y2Z74FxzwyRtKorqvH+0GNYGhoIATk89FOxY68eug/pLHU0ImrBmnTPjEqluuNybADQ0dG54z5NtQkJCYG3tzeMjY1haWmJUaNGITU1tcYyZWVlmDFjBjp06AAjIyM8+eSTuHbtWn1jE5FEtHS18K5SgYMhibCQXceJMmd4De2A7XMipY5GRK1EvcvMwIEDMWfOHFy9elU97cqVK5g3bx4GDRpUr3WFhoZixowZiI6OxqFDh1BZWYmhQ4eipKREvcy8efPw66+/YseOHQgNDcXVq1cxZsyY+sYmIokNeaMPkuKqEWiahGIYY9waP7ziGoay/DKpoxGRhqv3YaasrCw88cQTOH36NOzt7dXTXF1dsXfvXtjZ2TU4zPXr12FpaYnQ0FAEBgaioKAAFhYW2LJlC8aOHQsAOHv2LFxcXBAVFYWHH3641nXyMBNRy1JVVoUlg8KxLFIBAPA0SMFPv7ZDt0GO0gYjohalSQfNs7e3R0JCAv7880+cPXsWAODi4oLBgwc3LO2/FBT8PQz67Xs/xcfHo7Kyssa6e/bsCQcHh3uWmfLycpSXl6ufFxYWPnAuImo82vra+DBCgYAP4vDcO12QeMsFXoML8c3cSDy9yk/qeESkgepdZgBAJpNhyJAhGDJkSKMFUalUmDt3Lvz9/eHq6goAyMnJga6urvoS8NusrKyQk5Nz1/WEhITgvffea7RcRNQ0hr/dF0nDsjF+8AmEF3rgmdV+UB4Kw8rwftA305c6HhFpkDqVmTVr1mD69OnQ19fHmjVr7rtsQy/PnjFjBk6dOoXw8PAGvf62RYsW4dVXX1U/LywsVB8OI6KWxc7bBkevWeCdgUqERCmw7nQgomzP4qc9+rzaiYjqrE5lZtWqVQgODoa+vj5WrVp1z+VkMlmDyszMmTOxb98+hIWF1TjnxtraGhUVFcjPz6+xd+batWuwtra+67r09PSgp6dX7wxEJA1tfW0si1Qg6MM4TFjsiKRbPeE1tAhfzYzE+LU87EREtZP03kxCCMyaNQu7d++GUqlE9+7da8y/fQLw1q1b8eSTTwIAUlNT0bNnT54ATNQKXU3IwbMDcxBa8BAAYKpzGD4L74t2HdtJG4yIml2TjjOzdOlSlJaW3jH91q1bWLp0ab3WNWPGDGzevBlbtmyBsbExcnJykJOTg1u3/h4h1NTUFFOmTMGrr76Ko0ePIj4+Hs8//zx8fX3rVGSISLPYelnjzxxXvBOohAwqfJMaiH52V3hvJyK6r3rvmdHS0kJ2djYsLS1rTL958yYsLS1RXV1d9zeXye46fcOGDZg8eTKAvwfNmz9/PrZu3Yry8nIMGzYMX3755T0PM/0X98wQaaYjnyYieKEtclRWaIcSrJ2cgOe/7Q+Z/O7/3SCi1qU+39/1LjNyuRzXrl2744aSR44cwTPPPIPr16/XP3ETYpkh0lzXTl3HhKBMHMrrAwAI7hyBdRHuMLY1ljgZETW1JjnM1L59e5ibm0Mmk6FHjx4wNzdXP0xNTTFkyBA8/fTTDxyeiOg2K1cLHLjmiWVDldBCFX686I8+nW8gcetZqaMRUQtS5z0z33//PYQQeOGFF7B69WqYmpqq5+nq6qJz587w9fVtsqANxT0zRK1DxLpkjJ/VAVnVnaCLcnw8JhqzdgTysBNRK9Wkh5lCQ0Ph5+d315tNtkQsM0StR975v/B8/zTszfEBADxhHYPvwrqjQ3dziZMRUWNr0jIDANXV1di9ezdSUlIAAL169cLIkSOhrd2gAYWbFMsMUesiVAJrnwrDgl0PowJ6sNO6ih9XXUfgLA+poxFRI2rSMnP69Gk88cQTyMnJgbOzMwAgLS0NFhYW+PXXX9W3ImgpWGaIWqfErWcxbpIe0iq7QI5qLBlwDG8dCICWrpbU0YioETTpODNTp05F7969cfnyZSQkJCAhIQFZWVlwd3fH9OnTGxyaiKg+PMf3RHymBSY5hUMFLSw5qsAgy5O4fDxb6mhE1MzqvWfGwMAAcXFx6N27d43pp06dgre3t3rAu5aCe2aIWr/NL0fg5fXuKIYxzGV5+O6NdIxc5iN1LCJ6AE26Z6ZHjx64du3aHdNzc3PRrVu3+q6OiOiBPbfOH4l/5qFvuzPIE+YYFeKDWe6hKMsvkzoaETWDepeZkJAQzJ49Gzt37sTly5dx+fJl7Ny5E3PnzsVHH32EwsJC9YOIqLl0G+SIiGvd8FpfJQDg85NB6GeTyVshELUBDRoBWP3if25HcHsV/34uk8nqdWuDpsLDTERtz4EP4jDpHUfkCgsYoBSrno3D9B8COCYNkQZp8nFm6iooKKg+q24SLDNEbVNOci4mDczEHzf7AgDG2Ebj6zBnmDu1lzgZEdVFk48zo0lYZojaLlWVCqtGh2HRPj9UQhd2Wlex+dNcBM15SOpoRFSLJi8z+fn5+Pbbb9WD5vXu3RsvvPBCjVsctBQsM0QUvzkF41/QR3plF8igwlv9w/DOQX/otNOMkcyJ2qImvZopLi4OTk5OWLVqFfLy8pCXl4eVK1fCyckJCQkJDQ5NRNRU+jzngoRMCzzf/RgE5PggXIFAq7O4oMyUOhoRNYJ675kJCAhAt27d8PXXX6tvX1BVVYWpU6fiwoULCAsLa5KgDcU9M0T0bz/Ni8T01b1RAFMYoxDrXj6J4C/9pY5FRP/RpIeZDAwMkJiYiJ49e9aYfubMGfTt2xelpaX1T9yEWGaI6L8uRVzGc4/cRHjh3/dzCu4cgS9CXWHq0PIOlRO1VU16mMnExASZmXfums3KyoKxsXF9V0dE1Owc/e1w9FpvLB2ohBaq8ONFfzzkVIiIdclSRyOiBqh3mXnmmWcwZcoUbN++HVlZWcjKysK2bdswdepUjB8/vikyEhE1Om19bSw+rMCx/6Wgi3YmLlbZI/CV3nhXoURVWZXU8YioHup9mKmiogILFizA+vXrUVX19x+8jo4OXn75ZSxfvhx6enpNErSheJiJiGpTeLkQM4OS8cOF/gAAX6OT2PyrKboqHCRORtR2Ncs4M6WlpTh//jwAwMnJCe3atWvIapocywwR1dWWGRF4+UtXFP5zcvDn05IxYb0/Rw4mkgAHzfsXlhkiqo+L4Zcx4dH/Pzn4aftIrA/thfZdzKQNRtTGNOkJwERErVnn/nZQXnfFh0OU0EYlfsryg3v3UhxdmSh1NCK6B5YZIqL/0NLVwpt/KBC5MR3ddTJwudoWg+Z7YGE/JcoLy6WOR0T/wTJDRHQP3pN6ISHTAtN6hkFAjo+PK/CwdQbO7D0ndTQi+heWGSKi+zCyNsJXKYHY/UYMOshuIulWT/QZ2Qlrx4ZCVaWSOh4RgWWGiKhORoX44GRCFYZ3PI4yGGD2z0EYYZ2Aqwk5UkcjavNYZoiI6sjmISv8dq0v1o4NhT5u4Y+bfeHWVxc750dJHY2oTWOZISKqB5lchpk7gpDw61V4GaQgT5jjqZW+mOQUjoLMAqnjEbVJLDNERA3g8pgTonKdsMhXCRlU2HShPzy6FiFs7QmpoxG1OSwzREQNpGuki2WRCoR9cQqdtbNwqdoOitluvISbqJmxzBARPaD+r7jjRIYpXuh+TH0Jdz+rizj5c5rU0YjaBJYZIqJGYGJngm/TAvDLohhYyK4jucwZfcc64uNHlaiuqJY6HlGrxjJDRNSIRi7zwclk4HGrGFRADwt/U2CAxSlkhGVJHY2o1WKZISJqZFauFthztR++nngMRijCsUIPuAeZ4bvnj0GoWvW9fYkkwTJDRNQEZHIZpn4fgBNH/4K/cTKKYYwpGwMw0jYW105dlzoeUavCMkNE1IS6KhwQeqM3lg9XQhfl+PWaD1zdZfh5AQfaI2osLDNERE1MS1cLr/+uwPEdl+Cun4oboiPGfuKLCV3DkX+JA+0RPSiWGSKiZuI+tgeOX++CN/2UkKMamzP6w7VrKf4IiZc6GpFGY5khImpGuka6+DBCgfD/nUE3nYu4orLBsDf74BXXMJTklkgdj0gjscwQEUnAd7obki5bYKZbKABg3elAeHS6gYh1yRInI9I8LDNERBIxtDTE2uQgHPooAfZaV3C+yhEBr7hiYT8lyvLLpI5HpDFYZoiIJDZ4oRdOXjDCJKdw9e0Q+lhfRtymM1JHI9IILDNERC2AqYMpNp7rjz1vxsBKnosz5d3w8KQeeCdQiYriCqnjEbVokpaZsLAwPP7447C1tYVMJsMvv/xSY35xcTFmzpwJOzs7GBgYoFevXli/fr00YYmImsETH/rg9FltPGMfiWpo4/1jCvSzyMCJn1KljkbUYklaZkpKSuDh4YEvvvjirvNfffVVHDhwAJs3b0ZKSgrmzp2LmTNnYu/evc2clIio+XTobo5tmX74aV4UOshu4kSZM7yf6YIPBitRWVopdTyiFkfSMjNixAh88MEHGD169F3nR0ZGYtKkSVAoFOjcuTOmT58ODw8PxMbGNnNSIqLm99RKX5xOVmGUTTQqoYvFhxXwtUjH6T3npI5G1KK06HNm/Pz8sHfvXly5cgVCCBw9ehRpaWkYOnToPV9TXl6OwsLCGg8iIk1l5WqBXZd9sPnlCLSX/YX40l7wGmWPj0YoUVVWJXU8ohahRZeZtWvXolevXrCzs4Ouri6GDx+OL774AoGBgfd8TUhICExNTdUPe3v7ZkxMRNT4ZHIZgr/0x6m4cjxmGYsK6OGNAwr4dzyLlH3npY5HJLkWX2aio6Oxd+9exMfH49NPP8WMGTPw559/3vM1ixYtQkFBgfqRlZXVjImJiJqOrZc19mZ7Y+PUcJiiALElrvB8vBNWPKJEdUW11PGIJCMTQgipQwCATCbD7t27MWrUKADArVu3YGpqit27d+PRRx9VLzd16lRcvnwZBw4cqNN6CwsLYWpqioKCApiYmDRFdCKiZnclLhvTH7mM3657AwB8DE9hwzYDuDzmJHEyosZRn+/vFrtnprKyEpWVlZDLa0bU0tKCSqWSKBURUcvQqa8N9uX0xYYpf++liflnLw3PpaG2SNIyU1xcjKSkJCQlJQEAMjIykJSUhMzMTJiYmCAoKAgLFiyAUqlERkYGNm7ciE2bNt3z6iciorZEJpdh8jf9cSq2FI9YHEc59PHGAQX8OqbyiidqUyQ9zKRUKjFgwIA7pk+aNAkbN25ETk4OFi1ahD/++AN5eXlwdHTE9OnTMW/ePMhksjq9Bw8zEVFbIFQCm16MwJxv3FAAU+iiHEuGRGHh3v7Q1teWOh5RvdXn+7vFnDPTVFhmiKgtuRKXjRcfzcL+3H4AAC+DFGzYpAX3sT0kTkZUP63inBkiIqq/Tn1t8Gu2Nza9GI72sr+QcMsFfZ/qjPcG8B5P1HqxzBARtTIyuQwT1vfH6YQKjLSOQSV08a5SAW+LDCT8mCJ1PKJGxzJDRNRK2Txkhd1X+mHrrEh0kN1Ecpkz+j3XHW/6KVGWXyZ1PKJGwzJDRNSKyeQyjFvjhzMnVXj6nztxh0Qp4Gl1BVFfnZQ6HlGjYJkhImoDLHtbYHumH3YtjIa1/BrOVjjB/8XemOcVipLcEqnjET0QlhkiojZk9EcP48w5PUzudgwCcqxODIJbp5s4/HGC1NGIGoxlhoiojWnfxQwb0gPw+/txcNC6jIwqBwxe6IVpPcOQf6lA6nhE9cYyQ0TURg1/uy9OZZpihlsoAOCb1ED07lqKvW/FSJyMqH5YZoiI2jBjW2N8nhyEsLUn0F0nA1dVNhi5zAfPOETi2qnrUscjqhOWGSIiQsBMD5zIscYbDyuhhSr8lOWHXu5a+OGlcAhVqx4onloBlhkiIgIAGJgbICRKgdjN6XjI4CzyhDkm/q8/RljG42L4ZanjEd0TywwREdXgFeyC2BtOWDZUCT2U4eDNvugd0B6rR4eiuqJa6nhEd2CZISKiO+i008Gigwqc+O0qAk2TUApDzPslCH7mKTj5c5rU8YhqYJkhIqJ7ch7RFUdvuGP9s2EwQQFiS1zhNbYLFgfwlgjUcrDMEBHRfcm15Xjxx0CcOV6KkdYxqIIOPghX4CGrqwhbe0LqeEQsM0REVDed+tpg95V+2PlaFKzl15Ba0RVBsz3wogsH2yNpscwQEVGdyeQyPPmxL86c08O0nmEAgK/OBqJX11v4eUEUL+MmSbDMEBFRvbXvYoavUgKhXJ2EHjoZyFZZY+wnvhjVKRaXj2dLHY/aGJYZIiJqsKA5D+FErg3e7q+ENiqxN8cHvfoZ4vOneBk3NR+WGSIieiD6Zvp4/5gCibsuwtfoJIpgglk7g+BvnoLknbyMm5oeywwRETUK19HdEf5Xb3z+VCiMUYiYElf0eaoL3nhYidIbpVLHo1aMZYaIiBqNXFuOGT8FIeV4CcbYRqMKOvgoRgE3m+v4IyRe6njUSrHMEBFRo+vU1wY/X3kYe96MgZ3WVVyocsSwN/sguHME78ZNjY5lhoiImswTH/rgTKYx5jwUCjmqseWSP3q66+DriWFQVamkjketBMsMERE1KWNbY6xODELM96nwMkhBvjDD9B8CEWh+Cqf3nJM6HrUCLDNERNQs+k7shZi87lg1KhSGKEZEkTseGuWIRb48QZgeDMsMERE1G219bczdHYQzkQV44p/7PC2PVsDV5gYOfBAndTzSUCwzRETU7Bx8O2FPtg92v/H3CcIZVQ4YsbgvnnGIxNWEHKnjkYZhmSEiIsmMCvn7BOF5XkrIUY2fsvzg0seAIwhTvbDMEBGRpIxtjbEyXoG4LenoZ3gKhTDFrJ1B8GmfivjNKVLHIw3AMkNERC2C5/ieiMxzwbrxYTBFAeJLe6HfhB6Y5R6KgswCqeNRC8YyQ0RELYaWrhZe2hKIsyfKEdw5Aipo4fOTQejZpQxbZ0VCqITUEakFYpkhIqIWx9rdEpsz/PHnigT00MlAjsoKz37uhyEdE5H6+wWp41ELwzJDREQt1qAFXki+YYv3Bymhj1s4/JcX3B/phMUBStzKuyV1PGohWGaIiKhF0zPRw9t/KnD66HWMsDiOCujhg3AFeltdx/53j0sdj1oAlhkiItIIXRUO2J/TFz8viFaPTfPYe94YbRuNzKgrUscjCbHMEBGRxpDJZRiz4mGkXDbBAm8ltFGJX7IfhoufGZYPV6KiuELqiCQBlhkiItI4RtZGWBGrQOKuiwgwOYFSGGLRQQU8OmThyKeJUsejZsYyQ0REGst1dHeE/uWOTS+Gw1J2HWcrnDDoNU+Md4zElbhsqeNRM2GZISIijSaTyzBhfX+kZuhiplso5KjGtkw/9PQ2wqePK1FZWil1RGpiLDNERNQqmDmaYm1yEOK2pONho5MohjFe26fAQ+aXcHQlDz21ZiwzRETUqniO74mIv3rj28nH0FF2A2fKu2HgfB56as1YZoiIqNWRa8vxwoYApKZr4RXXUMigUh96+vhRXvXU2khaZsLCwvD444/D1tYWMpkMv/zyyx3LpKSk4IknnoCpqSkMDQ3h7e2NzMzM5g9LREQax9ypPb44GYS4zanqQ08Lf/v7qqfDHydIHY8aiaRlpqSkBB4eHvjiiy/uOv/8+fPo378/evbsCaVSieTkZCxevBj6+vrNnJSIiDSZV7ALIv7qje+ePwaLf656GrzQC0/bR3HAvVZAJoRoEbcglclk2L17N0aNGqWeNm7cOOjo6OCHH36o83rKy8tRXl6ufl5YWAh7e3sUFBTAxMSkMSMTEZEGyr9UgHeeSMIXyf2hghbaoQRvDTmO+Tt9oWeiJ3U8+kdhYSFMTU3r9P3dYs+ZUalU2L9/P3r06IFhw4bB0tISPj4+dz0U9W8hISEwNTVVP+zt7ZsnMBERaQQzR1OsORGEhO3n1APuvXVIgd4dcnivJw3VYstMbm4uiouLsXz5cgwfPhx//PEHRo8ejTFjxiA0NPSer1u0aBEKCgrUj6ysrGZMTUREmsLjaWeE/uWOH1+JgK08G+erHPHYe954zCoW5w5fkjoe1UOLLTMqlQoAMHLkSMybNw8PPfQQ3njjDTz22GNYv379PV+np6cHExOTGg8iIqK7kcllePYLf5zNMsLCfkrooAL7c/uh92BrvOmnRHFOsdQRqQ5abJnp2LEjtLW10atXrxrTXVxceDUTERE1KmNbY3wUo8DJ3y5jeMfjqIAeQqIU6NmpCFtnRUKoWsTppXQPLbbM6OrqwtvbG6mpqTWmp6WlwdHRUaJURETUmjmP6IrfrvXFnjdj0EU7E1dUNnj2cz8Etk9G0vbU2ldAkpC0zBQXFyMpKQlJSUkAgIyMDCQlJan3vCxYsADbt2/H119/jXPnzuHzzz/Hr7/+ildeeUXC1ERE1JrJ5DI88aEPzly3xPuDlGiHEoQXeqDPuG54uXcYbqTelDoi/Yekl2YrlUoMGDDgjumTJk3Cxo0bAQDfffcdQkJCcPnyZTg7O+O9997DyJEj6/we9bm0i4iI6L+yYq5i4dMXsS3TDwDQXvYX3huTjJc3+0NbX1vidK1Xfb6/W8w4M02FZYaIiBpD2NoTmL1QHyfKnAEAvfXS8dn7RRi0wEviZK1TqxhnhoiIqCUJnOWB+IJuWDc+DB1kN3G6vDsGL/TCGNtoXFDywhQpscwQERHVkZauFl7aEoi0dDlmuYdCC1XYnf0weg2wxJt+ShRdLZI6YpvEMkNERFRP5k7tseZEEJJ2ZWBQ+wSUQx8hUQo425dg0/RwqKpUUkdsU1hmiIiIGsh1dHccuuGJXxbFwEn7ErJV1pj0dX/4mp1B1FcnpY7XZrDMEBERPQCZXIaRy3xw+qY1PhqhhBGKEFviCr8X3RDcOQJZMVeljtjqscwQERE1Aj0TPSz8TYH0E7fwQvdjkEGFLZf84fywGd4boETpjVKpI7ZaLDNERESNyNrdEt+mBSBucyr6m5zALbTDu0oFnK3z8eMrETyfpgmwzBARETUBr2AXhP3ljp/mRcFR6zIuV9viuXX+8DM7g+hvTkkdr1VhmSEiImoiMrkMT630RUpuB3w4RAlDFCOmxBW+01wR3DkCmVFXpI7YKrDMEBERNTEDcwO8+YcC6YklNc+n8TPH4gAlinOKpY6o0VhmiIiImonNQ1bq82kCTZNQBgN8EK5Aj07F2PDCMZ5P00AsM0RERM3MK9gFyjwP/LwgGl3/GZ/mhQ0B6GuSiqMrE6WOp3FYZoiIiCQgk8swZsXDOHPTGp88poQpCpB4ywUD53tilE0M0g5mSB1RY7DMEBERSUjPRA/zf1Xg3NkqzHT7+35Pe3J80Hu4HeZ6hiLv/F9SR2zxWGaIiIhagI7OHbA2OQgnf72ERy1jUQUdfJYUBKfuMqwcqUR5YbnUEVsslhkiIqIWxOUxJ+y71g+HPkqAu34q8oUZ5u9VoFeHHOycHwWhElJHbHFYZoiIiFqgwQu9kFDQDd9MOgZr+TVcqHLEUyt90d/sJAfd+w+WGSIiohZKS1cLUzYGIP2KId4JVMIApYgscofvNFeMc4hERliW1BFbBJYZIiKiFs7I2gjvhSqQfrxAPeje9iw/9AyyxGt9lfgrI1/qiJJimSEiItIQnfra4Nu0ACRuT8cQ83hUQA+fxivg5CTa9EnCLDNEREQaxuNpZ/xxsw8OfBAHV710/CXaY/5eBVw6XMO22ZFt7iRhlhkiIiINNeytvkgq7IpvJx+DrTwbGVUOGL/WDz4mZxC29oTU8ZoNywwREZEG09LVwgsbApCWbYKlA5UwQhGOl/RG0GwPPGEdgzN7z0kdscmxzBAREbUChpaGWHxYgXMny/By7zBooQq/XvOB28gumO4Shuyka1JHbDIsM0RERK2IlasFvjwViNO/ZWK0TTRU0MLXZwPRzdMIiwOUKLxcKHXERscyQ0RE1Ao5j+iKXVcfRviXyfA1OolSGOKDcAWcHCqwdmwoKoorpI7YaFhmiIiIWjH/l90RUeCKXQuj0UMnAzdER8z+OQi92mdj+5xIqKpUUkd8YCwzRERErZxMLsPojx7GqXw7rBsfBit5Ls5XOWLcGj/0Mz2LI58mSh3xgbDMEBERtRE67XTw0pZAnLvSTn3lU3xpLwx6zRPDO8YhaXuq1BEbhGWGiIiojTGyNsLiwwqcP1WGWe6h0EEFDt7sC89xzniuS4TG3fOJZYaIiKiNsuxtgTUngpByOBvjHCIBAD9e9IdzkBVme4Qi9/R1iRPWDcsMERFRG+c00BFbL/khfnMKhnaIQyV0sTY5CE6u+nhXoUTR1SKpI94XywwREREBALyCXXDwRl8c/iQRfdudQTGM8V6oAl3tyvHZmNAWeyNLlhkiIiKqYeB8T8QWuWDHq1Hqy7nn7g6Cs/l1bJoejuqKaqkj1sAyQ0RERHeQyWUY+6kvTuXb4X/BYbCVZ+NStR0mfd0fHiYXsOfNmBZzd26WGSIiIronnXY6mL45EOnXTLF8uBJmsnycLu+OUSE+8DM9BeXqJKkjsswQERFR7dp1bIfXf1fgwnlgka8SBihFdLEbBsx7CC+6hEmajWWGiIiI6qx9FzMsi1TgfGIRXnENhTYqEThAS9JMMiFEyzjg1UQKCwthamqKgoICmJiYSB2HiIioVckIy4KjXyfItRt3/0h9vr+1G/WdiYiIqE3pEmgvdQQeZiIiIiLNxjJDREREGo1lhoiIiDSapGUmLCwMjz/+OGxtbSGTyfDLL7/cc9mXXnoJMpkMq1evbrZ8RERE1PJJWmZKSkrg4eGBL7744r7L7d69G9HR0bC1tW2mZERERKQpJL2aacSIERgxYsR9l7ly5QpmzZqFgwcP4tFHH611neXl5Sgv//8bYRUWFj5wTiIiImq5WvQ5MyqVChMmTMCCBQvQu3fvOr0mJCQEpqam6oe9vfSXjBEREVHTadFl5qOPPoK2tjZmz55d59csWrQIBQUF6kdWVlYTJiQiIiKptdhB8+Lj4/HZZ58hISEBMpmszq/T09ODnp5eEyYjIiKilqTF7pk5duwYcnNz4eDgAG1tbWhra+PSpUuYP38+OnfuLHU8IiIiaiFa7J6ZCRMmYPDgwTWmDRs2DBMmTMDzzz8vUSoiIiJqaSQtM8XFxTh37pz6eUZGBpKSkmBubg4HBwd06NChxvI6OjqwtraGs7Nzc0clIiKiFkrSMhMXF4cBAwaon7/66qsAgEmTJmHjxo0SpSIiIiJNImmZUSgUEELUefmLFy/W+z1ur5/jzRAREWmO29/bdekJLfacmcZSVFQEABxvhoiISAMVFRXB1NT0vsvIRH12jWgglUqFq1evwtjYuF6XeNdFYWEh7O3tkZWVBRMTk0Zdd0vA7dN8rX0buX2ar7VvI7ev4YQQKCoqgq2tLeTy+1983er3zMjlctjZ2TXpe5iYmLTKX9LbuH2ar7VvI7dP87X2beT2NUxte2Rua7HjzBARERHVBcsMERERaTSWmQegp6eHJUuWtNrbJ3D7NF9r30Zun+Zr7dvI7Wserf4EYCIiImrduGeGiIiINBrLDBEREWk0lhkiIiLSaCwzREREpNFYZmpRXV2NxYsXo0uXLjAwMICTkxPef//9GveKEELgnXfegY2NDQwMDDB48GCkp6dLmLru6rJ9kydPhkwmq/EYPny4hKnrp6ioCHPnzoWjoyMMDAzg5+eH48ePq+dr8ud3W23bqEmfYVhYGB5//HHY2tpCJpPhl19+qTG/Lp9XXl4egoODYWJiAjMzM0yZMgXFxcXNuBX31xjb2Llz5zs+0+XLlzfjVtxbbdu3a9cuDB06FB06dIBMJkNSUtId6ygrK8OMGTPQoUMHGBkZ4cknn8S1a9eaZwNq0Rjbp1Ao7vj8XnrppebZgDq43zZWVlbi9ddfh5ubGwwNDWFra4uJEyfi6tWrNdbRnH+HLDO1+Oijj7Bu3Tp8/vnnSElJwUcffYQVK1Zg7dq16mVWrFiBNWvWYP369YiJiYGhoSGGDRuGsrIyCZPXTV22DwCGDx+O7Oxs9WPr1q0SJa6/qVOn4tChQ/jhhx9w8uRJDB06FIMHD8aVK1cAaPbnd1tt2whozmdYUlICDw8PfPHFF3edX5fPKzg4GKdPn8ahQ4ewb98+hIWFYfr06c21CbVqjG0EgKVLl9b4TGfNmtUc8WtV2/aVlJSgf//++Oijj+65jnnz5uHXX3/Fjh07EBoaiqtXr2LMmDFNFbleGmP7AGDatGk1Pr8VK1Y0RdwGud82lpaWIiEhAYsXL0ZCQgJ27dqF1NRUPPHEEzWWa9a/Q0H39eijj4oXXnihxrQxY8aI4OBgIYQQKpVKWFtbi48//lg9Pz8/X+jp6YmtW7c2a9aGqG37hBBi0qRJYuTIkc2crHGUlpYKLS0tsW/fvhrTvby8xFtvvaXxn58QtW+jEJr7GQIQu3fvVj+vy+d15swZAUAcP35cvczvv/8uZDKZuHLlSrNlr6uGbKMQQjg6OopVq1Y1Y9KG+e/2/VtGRoYAIBITE2tMz8/PFzo6OmLHjh3qaSkpKQKAiIqKasK09deQ7RNCiKCgIDFnzpwmzdZY7reNt8XGxgoA4tKlS0KI5v875J6ZWvj5+eHw4cNIS0sDAJw4cQLh4eEYMWIEACAjIwM5OTkYPHiw+jWmpqbw8fFBVFSUJJnro7btu02pVMLS0hLOzs54+eWXcfPmTSni1ltVVRWqq6uhr69fY7qBgQHCw8M1/vMDat/G2zT1M/y3unxeUVFRMDMzQ9++fdXLDB48GHK5HDExMc2eub7q8zu5fPlydOjQAZ6envj4449RVVXV3HGbRHx8PCorK2v8DHr27AkHBweN+busix9//BEdO3aEq6srFi1ahNLSUqkjNVhBQQFkMhnMzMwANP/fYau/0eSDeuONN1BYWIiePXtCS0sL1dXV+PDDDxEcHAwAyMnJAQBYWVnVeJ2VlZV6XktW2/YBfx+eGDNmDLp06YLz58/jzTffxIgRIxAVFQUtLS0J09fO2NgYvr6+eP/99+Hi4gIrKyts3boVUVFR6Natm8Z/fkDt2who9mf4b3X5vHJycmBpaVljvra2NszNzTXiM63r7+Ts2bPh5eUFc3NzREZGYtGiRcjOzsbKlSubNW9TyMnJga6urvqL8TZN+ruszbPPPgtHR0fY2toiOTkZr7/+OlJTU7Fr1y6po9VbWVkZXn/9dYwfP159s8nm/jtkmanFTz/9hB9//BFbtmxB7969kZSUhLlz58LW1haTJk2SOt4Dq8v2jRs3Tr28m5sb3N3d4eTkBKVSiUGDBkkVvc5++OEHvPDCC+jUqRO0tLTg5eWF8ePHIz4+Xupojaa2bdT0z5Du9Oqrr6r/7e7uDl1dXbz44osICQmRfGh5qt2/zx1xc3ODjY0NBg0ahPPnz8PJyUnCZPVTWVmJp59+GkIIrFu3TrIcPMxUiwULFuCNN97AuHHj4ObmhgkTJmDevHkICQkBAFhbWwPAHWfZX7t2TT2vJatt++6ma9eu6NixI86dO9eMSRvOyckJoaGhKC4uRlZWFmJjY1FZWYmuXbtq/Od32/228W407TO8rS6fl7W1NXJzc2vMr6qqQl5enkZ8pg39nfTx8UFVVRUuXrzYlPGahbW1NSoqKpCfn19juqb9XdaHj48PAGjU3+TtInPp0iUcOnRIvVcGaP6/Q5aZWpSWlkIur/lj0tLSgkqlAgB06dIF1tbWOHz4sHp+YWEhYmJi4Ovr26xZG6K27buby5cv4+bNm7CxsWnqeI3K0NAQNjY2+Ouvv3Dw4EGMHDlS4z+//7rbNt6Npn6Gdfm8fH19kZ+fX2PP25EjR6BSqdRfGC1ZQ38nk5KSIJfL79i1r4n69OkDHR2dGj+D1NRUZGZmauTfZV3cvnxbU/4mbxeZ9PR0/Pnnn+jQoUON+c3+d9jopxS3MpMmTRKdOnUS+/btExkZGWLXrl2iY8eOYuHCheplli9fLszMzMSePXtEcnKyGDlypOjSpYu4deuWhMnrprbtKyoqEq+99pqIiooSGRkZ4s8//xReXl6ie/fuoqysTOL0dXPgwAHx+++/iwsXLog//vhDeHh4CB8fH1FRUSGE0OzP77b7baOmfYZFRUUiMTFRJCYmCgBi5cqVIjExUX2VRF0+r+HDhwtPT08RExMjwsPDRffu3cX48eOl2qQ7POg2RkZGilWrVomkpCRx/vx5sXnzZmFhYSEmTpwo5Wap1bZ9N2/eFImJiWL//v0CgNi2bZtITEwU2dnZ6nW89NJLwsHBQRw5ckTExcUJX19f4evrK9Um1fCg23fu3DmxdOlSERcXJzIyMsSePXtE165dRWBgoJSbVcP9trGiokI88cQTws7OTiQlJYns7Gz1o7y8XL2O5vw7ZJmpRWFhoZgzZ45wcHAQ+vr6omvXruKtt96q8YGpVCqxePFiYWVlJfT09MSgQYNEamqqhKnrrrbtKy0tFUOHDhUWFhZCR0dHODo6imnTpomcnByJk9fd9u3bRdeuXYWurq6wtrYWM2bMEPn5+er5mvz53Xa/bdS0z/Do0aMCwB2PSZMmCSHq9nndvHlTjB8/XhgZGQkTExPx/PPPi6KiIgm25u4edBvj4+OFj4+PMDU1Ffr6+sLFxUUsW7asxZTT2rZvw4YNd52/ZMkS9Tpu3bolXnnlFdG+fXvRrl07MXr06BplR0oPun2ZmZkiMDBQmJubCz09PdGtWzexYMECUVBQIN1G/cf9tvH2Jed3exw9elS9jub8O5QJ8a+hXomIiIg0DM+ZISIiIo3GMkNEREQajWWGiIiINBrLDBEREWk0lhkiIiLSaCwzREREpNFYZoiIiEijscwQERGRRmOZIaJmtXHjRpiZmamfv/vuu3jooYcky/Nv/81GRJqBZYaIHtjkyZMxatSoOi37zDPPIC0trWkDNVBLzkZE96YtdQAiajsqKythYGAAAwMDqaPcoSVnI6L7454ZIqqTnTt3ws3NDQYGBujQoQMGDx6MkpISvPvuu/j++++xZ88eyGQyyGQyKJVKXLx4ETKZDNu3b0dQUBD09fXx448/1noo5/z58+jatStmzpwJIQTKy8vx2muvoVOnTjA0NISPjw+USuV9s8pkMqxbtw4jRoyAgYEBunbtip07d6rn1yfbr7/+Cm9vb+jr66Njx44YPXq0el5DshFR42OZIaJaZWdnY/z48XjhhReQkpICpVKJMWPGQAiB1157DU8//TSGDx+O7OxsZGdnw8/PT/3aN954A3PmzEFKSgqGDRt23/dJTk5G//798eyzz+Lzzz+HTCbDzJkzERUVhW3btiE5ORlPPfUUhg8fjvT09Puua/HixXjyySdx4sQJBAcHY9y4cUhJSamxTG3Z9u/fj9GjR+ORRx5BYmIiDh8+jH79+qnnNzQbETWyJrkXNxG1KvHx8QKAuHjx4l3nT5o0SYwcObLGtIyMDAFArF69usb0DRs2CFNTU/XzJUuWCA8PDxERESHat28vPvnkE/W8S5cuCS0tLXHlypUa6xg0aJBYtGjRPfMCEC+99FKNaT4+PuLll1+uVzZfX18RHBx81/doaDYianw8Z4aIauXh4YFBgwbBzc0Nw4YNw9ChQzF27Fi0b9++1tf27du31mUyMzMxZMgQfPjhh5g7d656+smTJ1FdXY0ePXrUWL68vBwdOnS47zp9fX3veJ6UlFSvbElJSZg2bdpd5z1INiJqXCwzRFQrLS0tHDp0CJGRkfjjjz+wdu1avPXWW4iJiUGXLl3u+1pDQ8Na129hYQFbW1ts3boVL7zwAkxMTAAAxcXF0NLSQnx8PLS0tGq8xsjIqOEbVMds9zsZuKmzEVHd8ZwZIqoTmUwGf39/vPfee0hMTISuri52794NANDV1UV1dXWD121gYIB9+/ZBX18fw4YNQ1FREQDA09MT1dXVyM3NRbdu3Wo8rK2t77vO6OjoO567uLjUK5e7uzsOHz5813kPko2IGhfLDBHVKiYmBsuWLUNcXBwyMzOxa9cuXL9+XV0OOnfujOTkZKSmpuLGjRuorKys93sYGhpi//790NbWxogRI1BcXIwePXogODgYEydOxK5du5CRkYHY2FiEhIRg//79913fjh078N133yEtLQ1LlixBbGwsZs6cWa9MS5YswdatW7FkyRKkpKTg5MmT+OijjwDggbIRUeNimSGiWpmYmCAsLAyPPPIIevTogbfffhuffvopRowYAQCYNm0anJ2d0bdvX1hYWCAiIqJB72NkZITff/8dQgg8+uijKCkpwYYNGzBx4kTMnz8fzs7OGDVqFI4fPw4HB4f7ruu9997Dtm3b4O7ujk2bNmHr1q3o1atXvfIoFArs2LEDe/fuxUMPPYSBAwciNjZWPb+h2YioccmEEELqEEREjUkmk2H37t11HpWYiDQb98wQERGRRmOZISIiIo3GS7OJqNXh0XOitoV7ZoiIiEijscwQERGRRmOZISIiIo3GMkNEREQajWWGiIiINBrLDBEREWk0lhkiIiLSaCwzREREpNH+D57t4cpMF6QCAAAAAElFTkSuQmCC" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 42 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:42:54.996298Z", + "start_time": "2025-03-02T12:42:54.642919Z" + } + }, + "cell_type": "code", + "source": [ + "St_s = np.linspace(80, 120, 100)\n", + "C_kemna = []\n", + "C_geometric = []\n", + "\n", + "for St in St_s:\n", + " C_kemna.append(kemna_vorst(s_t=St))\n", + " C_geometric.append(geometric_mkhize(s_t=St)[0])\n", + " \n", + "plt.plot(St_s, C_kemna, label='kemna vorst', color='red')\n", + "plt.plot(St_s, C_geometric, label='geometric', color='blue')\n", + "plt.legend()\n", + "plt.xlabel('stock price')\n", + "plt.ylabel('option price')\n", + "plt.show()" + ], + "id": "50ce1e3547b56ac0", + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "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PVv4aHsABnb4ljnG9x8n0On5QLNDExEp9pQAiRRBO3+O5vHBduxJDwTgqXobmRXUElfvGuYGJiJSQugRmEgRkp2RzXs9g2j3qC970utR1XKW314L55sDnXH1djU7PBGREkMtQCJFRMz6owzpm0jYxUAA+niF8+Xa2ng00ertIiL5TS1AIiYzrAZfPh5Ci66VCbvYHFeS+PbJjSw92R6PJlXNDk9EpERSC5CIieKiTjO8+zH+879JDbu4RzF3RRVqdepscmQiIiWbWoBETPLzi5to2ros//nfpIYz+gSx/lxzanXSOl4iIgVNLUAihexCzF+MvHs/i45dXrqitfN+flhUlsa9A80NTESkFFELkEghWjl1G03rp7PoWAfsyWJyQBBbztWlcW9NaigiUpjUAiRSCC6eushL3Xbw7/2X+/o0cDjMD1+m0W5IoLmBiYiUUmoBEilgIZ/upEXNv2zJzwstg9kRV412QxqbHJmISOmlFiCRAnLpwiVevyecWZGXl7KoaX+C76af5a5xWsBURMRsSoBECsC2efsYPMKRPzMCARhWfyMz1rXArbpGeImIFAVKgETyUUZyBlN7buK9sE5kUwYvu9N8PekY903RvD4iIkWJqX2AQkJCeOCBB/D29sZisbBs2bIcx4cOHYrFYsmx9ezZ84blfvbZZ9SqVQsnJyf8/PzYunVrAdVA5P/t/Dma9lVjeScskGzKMKDGJvb8WZb7prQzOzQREfkHUxOglJQUWrRowWeffXbNc3r27ElcXJxtW7hw4XXL/Omnnxg3bhxvvPEGkZGRtGjRgh49enDmzJn8Dl8EgKy0LN655/ICpjvTGlDZcp6fX9zMwqMdqFyvktnhiYhILkx9BNarVy969ep13XMcHR3x8vK66TJnzJjB008/zZNPPgnAF198wR9//MG3337Lq6++mus16enppKen214nJSXd9PtJ6bZ/RQxDBqSxLSUQgL7VtvDFf+vg2dTf3MBEROS6ivww+KCgIDw8PGjQoAHPPfcc58+fv+a5GRkZRERE0K1bN9s+Ozs7unXrxubNm6953bRp03B3d7dtPj4++VoHKXmyM7L58P4gWj1wB9tSmuBOIvOeDmXJCT88m2oBUxGRoq5IJ0A9e/bk+++/Z926dbz//vsEBwfTq1cvsrOzcz3/3LlzZGdn4+npmWO/p6cn8fHx13yf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BB555BF69uxJXFwccXFxdOjQgZSUFHr06EHFihXZtm0bixcvZu3atTkSnDlz5jBy5EhGjBjB7t27Wb58OXXr1r3q/Q3DYPTo0Xz//fds3LiR5s2bXzPWQ4cO8fPPP/P777+zatUqduzYwfPPP5/jnHXr1hEdHc2aNWtyJDVXWK1WevXqRVhYGD/++CP79u3jvffew97eHoCYmBh69uxJ//792bVrFz/99BOhoaHXTd5EpIAUyBrzIiKGYURERBiAceTIkVyPDxkyxOjTp0+OfV9++aVRsWJFIzk52bbvjz/+MOzs7Iz4+HjDMAzD29vbeP3116/5voCxePFi47HHHjMaNWpknDhx4rpxvvHGG4a9vX2O81auXGnY2dkZcXFxtlg9PT2N9PT0HNfWrFnTmDlzpmEYhrF69WrDzs7OiI6OzvV9hg0bZowYMSLHvo0bNxp2dnbGpUuXrhujiOQv9QESkQLTokULunbtSrNmzejRowfdu3fnoYceomLFite8Zv/+/bRo0SJHx+KOHTtitVqJjo7GYrFw6tQpunbtet33fvHFF3F0dGTLli1UqVLlhrHWqFGDO+64w/ba39/f9p5eXl4ANGvWDAcHh2uWERUVRfXq1alfv36ux3fu3MmuXbuYP3++bZ9hGFitVmJjY2nUqNEN4xSR/KFHYCJSYOzt7VmzZg0rV66kcePGfPrppzRo0IDY2NhbLtPZ2fmmzrvnnns4efIkq1evvuX3+qcbjfa6UWzJyck888wzREVF2badO3dy8OBB6tSpk29xisiNKQESkQJlsVjo2LEjb775Jjt27MDBwYGlS5cC4ODgQHZ2do7zGzVqxM6dO3N0DA4LC8POzo4GDRrg6upKrVq1WLdu3XXft3fv3ixYsIDhw4ezaNGiG8Z57NgxTp06ZXu9ZcsW23verObNm3PixAkOHDiQ6/HWrVuzb98+6tate9V2vZYlEcl/SoBEpMCEh4fz7rvvsn37do4dO8aSJUs4e/as7VFPrVq12LVrF9HR0Zw7d47MzEwGDRqEk5MTQ4YMYc+ePWzYsIHRo0fzxBNP4OnpCVwetfXRRx/xySefcPDgQSIjI/n000+vev8HH3yQH374gSeffJJffvnlurFeec+dO3eyceNGxowZwyOPPGJ7/HUzunTpQkBAAP3792fNmjXExsaycuVKVq1aBcArr7zCpk2bGDVqFFFRURw8eJDffvtNnaBFTKA+QCJSYNzc3AgJCWHWrFkkJSVRs2ZNPvroI3r16gXA008/TVBQEG3btiU5OZkNGzYQGBjI6tWreeGFF2jXrh0uLi7079+fGTNm2ModMmQIaWlpzJw5kwkTJlClShUeeuihXGN46KGHsFqtPPHEE9jZ2dGvX79cz6tbty79+vXj3nvv5cKFC9x///18/vnnea7zr7/+yoQJExg4cCApKSnUrVuX9957D7jcQhQcHMzrr79O586dMQyDOnXq8Oijj+b5fUTk9lgMwzDMDkJExExTpkxh2bJlREVFmR2KiBQSPQITERGRUkcJkIiIiJQ6egQmIiIipY5agERERKTUUQIkIiIipY4SIBERESl1lACJiIhIqaMESEREREodJUAiIiJS6igBEhERkVJHCZCIiIiUOv8H+yFsDf8giOsAAAAASUVORK5CYII=" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 43 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "Kemna Vorst p 12, asian is allways cheaper or equal to european", + "id": "1c756eed94c18fc6" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:42:59.960246Z", + "start_time": "2025-03-02T12:42:59.946705Z" + } + }, + "cell_type": "code", + "source": [ + "def european_option(s_t=100, K=100, r=0.008, sigma=0.2, T=30):\n", + " d_1 = (np.log(s_t/K) + (r + 0.5*sigma**2)*T)/(sigma*np.sqrt(T))\n", + " d_2 = d_1 - sigma*np.sqrt(T)\n", + " C_0 = s_t*norm.cdf(d_1) - K*np.exp(-r*T)*norm.cdf(d_2)\n", + " P_0 = K*np.exp(-r*T)*norm.cdf(-d_2) - s_t*norm.cdf(-d_1)\n", + " return C_0, P_0" + ], + "id": "66e30bebcf590a3", + "outputs": [], + "execution_count": 44 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:43:00.401213Z", + "start_time": "2025-03-02T12:43:00.384456Z" + } + }, + "cell_type": "code", + "source": "european_option()", + "id": "3bcf51f6f44727a", + "outputs": [ + { + "data": { + "text/plain": [ + "(48.63941024359666, 27.302196350252007)" + ] + }, + "execution_count": 45, + "metadata": {}, + "output_type": "execute_result" + } + ], + "execution_count": 45 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:43:00.777970Z", + "start_time": "2025-03-02T12:43:00.755692Z" + } + }, + "cell_type": "code", + "source": "assert np.all(european_option() >= geometric_mkhize())", + "id": "7b0faeacd51db9e4", + "outputs": [], + "execution_count": 46 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:43:01.993528Z", + "start_time": "2025-03-02T12:43:01.370483Z" + } + }, + "cell_type": "code", + "source": [ + "sigmas = np.linspace(0.01, 1, 100)\n", + "# r = np.linspace(0, 0.05, 100)\n", + "r = 0.008\n", + "asian_call = []\n", + "european_call = []\n", + "asian_put = []\n", + "european_put = []\n", + "for sigma in sigmas:\n", + " asian_call.append(geometric_mkhize(sigma=sigma)[0])\n", + " european_call.append(european_option(sigma=sigma)[0])\n", + " asian_put.append(geometric_mkhize(sigma=sigma)[1])\n", + " european_put.append(european_option(sigma=sigma)[1])\n", + "\n", + "plt.plot(sigmas, asian_call, label='asian call', color='red')\n", + "plt.plot(sigmas, asian_put, label='asian put', color='red', linestyle='--')\n", + "plt.plot(sigmas, european_call, label='european call', color='blue')\n", + "plt.plot(sigmas, european_put, label='european put', color='blue', linestyle='--')\n", + "plt.legend()\n", + "plt.xlabel('sigma')\n", + "plt.ylabel('option price')\n", + "plt.show()" + ], + "id": "e68bac6b65ae2c04", + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjsAAAGwCAYAAABPSaTdAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAACGSUlEQVR4nO3dd1hT5xcH8G9AQFCmg2FR0bp3XcVRbaVqratatdZabdUOV9U666paf27r6rStaKviqHvX3boXdW8UHIiDjczc3x+nSYiCEgRuEr6f57kP5OYSTiKSw/ue97waRVEUEBEREVkpG7UDICIiIspNTHaIiIjIqjHZISIiIqvGZIeIiIisGpMdIiIismpMdoiIiMiqMdkhIiIiq1ZA7QDMgVarxZ07d+Ds7AyNRqN2OERERJQFiqIgNjYWPj4+sLHJfPyGyQ6AO3fuwNfXV+0wiIiIKBvCwsLw0ksvZXo/kx0Azs7OAOTFcnFxUTkaIiIiyoqYmBj4+vrq38czw2QH0E9dubi4MNkhIiKyMM8rQWGBMhEREVk1JjtERERk1ZjsEBERkVVjzU4WabVaJCcnqx0GWRA7OzvY2tqqHQYRUb7HZCcLkpOTERISAq1Wq3YoZGHc3Nzg5eXF/k1ERCpisvMciqLg7t27sLW1ha+v7zObFhHpKIqChIQEREREAAC8vb1VjoiIKP9isvMcqampSEhIgI+PD5ycnNQOhyyIo6MjACAiIgLFixfnlBYRkUo4TPEcaWlpAAB7e3uVIyFLpEuQU1JSVI6EiCj/UjXZ2b9/P9q0aQMfHx9oNBqsW7fO6H5FUTBu3Dh4e3vD0dERAQEBuHLlitE1jx49Qrdu3eDi4gI3Nzf06tULcXFxOR4ray4oO/hzQ0SkPlWTnfj4eNSoUQPfffddhvdPnz4d8+bNw48//ogjR46gUKFCaNGiBRITE/XXdOvWDefOncNff/2FTZs2Yf/+/fjkk0/y6ikQERGRmVO1Zuett97CW2+9leF9iqJgzpw5GDNmDNq1awcAWLJkCTw9PbFu3Tq89957uHDhArZt24Zjx46hTp06AID58+ejVatWmDlzJnx8fPLsuRAREZF5MtuanZCQEISHhyMgIEB/ztXVFfXr18ehQ4cAAIcOHYKbm5s+0QGAgIAA2NjY4MiRI5k+dlJSEmJiYowOMpbRtKK5uXHjBjQaDYKDgwEAe/fuhUajQVRUlKpxERGReTHb1Vjh4eEAAE9PT6Pznp6e+vvCw8NRvHhxo/sLFCgADw8P/TUZmTJlCiZMmJDDEVuXu3fvwt3dXe0wiIjIAikKkJgIPH4sR2IiULIkYGenTjxmm+zkplGjRmHIkCH627ot4snAy8tL7RCIiCgXabVAfDwQGytHXFzGR3y84WN8PJCQIEf6z9MfugTnSdeuAWXK5P3zBMw42dG92d67d8+oIdu9e/dQs2ZN/TW6pm06qampePTo0TPfrB0cHODg4JC9wBRF/jXV4OQEZHF1z7Zt2/DNN9/g7NmzsLW1hb+/P+bOnYuyZcsCkK7QQ4YMwZ9//onIyEh4enris88+w6hRowDINNbatWvRvn17AMCIESOwdu1a3Lp1C15eXujWrRvGjRsHu//S9K+//hrr1q3Dl19+ibFjxyIyMhJvvfUWFi5cCGdn50zjPHDgAEaPHo2jR4/CwcEB9erVQ1BQENzd3Z/7HIiI8iutFoiOBiIjgagoOaKjjT9Pf8TEGB+65EZRcj9WW1vA0RFQc8cls012/Pz84OXlhV27dumTm5iYGBw5cgSff/45AMDf3x9RUVE4ceIEateuDQDYvXs3tFot6tevnzuBJSQAhQvnzmM/T1wcUKhQli6Nj4/HkCFDUL16dcTFxWHcuHF45513EBwcDBsbG8ybNw8bNmzAypUrUbJkSYSFhSEsLCzTx3N2dkZgYCB8fHxw5swZ9OnTB87Ozhg+fLj+mmvXrmHdunXYtGkTIiMj0blzZ0ydOhWTJ0/O8DGDg4PRrFkzfPzxx5g7dy4KFCiAPXv26HsbPe85EBFZg4QE4P594MEDOR4+NHx8+BB49EgO3ee6BCenEhUbG8DZWd7adB8LF5a3m/Sfpz+cnAyfOzrKbd3h6Gh8qDV1lZ6qyU5cXByuXr2qvx0SEoLg4GB4eHigZMmSGDRoEL755huUK1cOfn5+GDt2LHx8fPSjDZUqVULLli3Rp08f/Pjjj0hJSUH//v3x3nvv5fuVWB07djS6/dtvv6FYsWI4f/48qlatitDQUJQrVw6NGjWCRqNBqVKlnvl4Y8aM0X9eunRpDB06FEFBQUbJjlarRWBgoH4kp3v37ti1a1emyc706dNRp04dfP/99/pzVapUyfJzICIyR1qtJCXh4cC9e4aPERFy6D6/f1+OF5kscHQE3N0BNzfD4eqa8eHiYjicneVj4cLyGNbeEkzVZOf48eN4/fXX9bd1dTQ9evRAYGAghg8fjvj4eHzyySeIiopCo0aNsG3bNhQsWFD/NUuXLkX//v3RrFkz2NjYoGPHjpg3b17uBe3kJCMsajBhu4orV65g3LhxOHLkCB48eKDfxDQ0NBRVq1ZFz5498eabb6JChQpo2bIlWrdujebNm2f6eCtWrMC8efNw7do1xMXFITU1FS4uLkbXlC5d2mjKytvb+6lpxvSCg4PRqVOnbD8HIqK8pCgyonL7thx37hg+3rkD3L0rH8PDgdRU0x7b3h4oWtRwFCkiHz085HPdR3d3+dzdXY7sVmTkN6omO02bNoXyjHE4jUaDiRMnYuLEiZle4+HhgWXLluVGeJkFleWpJDW1adMGpUqVwsKFC+Hj4wOtVouqVasi+b9J01deeQUhISHYunUrdu7cic6dOyMgIACrV69+6rEOHTqEbt26YcKECWjRogVcXV0RFBSEWbNmGV1n98RYpUajeeZO8bq9o7L7HIiIclJiIhAWBoSGAjdvysfQUDkXFgbcuiVFuVlVpAjg6Ql4eclHT0+geHHjo1gxSWqcna1/dEVNZluzQ9n38OFDXLp0CQsXLkTjxo0BAP/8889T17m4uKBLly7o0qUL3n33XbRs2RKPHj2Ch4eH0XUHDx5EqVKlMHr0aP25mzdvvnCc1atXx65duzJsA5DV50BElFVpaZK0XL8uK4NCQoAbNwzH3btZexwPD6BECcPh4wN4exs+entLYsMtFc0Hkx0r5O7ujiJFiuDnn3+Gt7c3QkNDMXLkSKNrZs+eDW9vb9SqVQs2NjZYtWoVvLy84Obm9tTjlStXDqGhoQgKCkLdunWxefNmrF279oXjHDVqFKpVq4a+ffvis88+g729Pfbs2YNOnTrBw8Pjuc+BiOhJqamSxFy5Aly9avh49aokNM+bXnJyAkqVkp4wpUoBvr7Gx0svSY0LWRYmO1bIxsYGQUFBGDhwIKpWrYoKFSpg3rx5aNq0qf4aZ2dnTJ8+HVeuXIGtrS3q1q2LLVu2ZLjKqW3bthg8eDD69++PpKQkvP322xg7diy+/vrrF4qzfPny2LFjB7766ivUq1cPjo6OqF+/Prp27Zql50BE+VdUFHDhghwXLwKXLslx7dqzExp7e8DPT/q9+PnJUbq0fCxVSqaeOJ1kfTTKs4pm8omYmBi4uroiOjr6qaLbxMREhISEwM/Pz6gwmigr+PND9GIiI4Fz54yP8+elCDgzjo7Ayy8D5crJ8fLLcpQtK9NO7FxhPZ71/p0eR3aIiEh1qakyMvPvv8Dp04bj9u3Mv6ZECaBSJaBiRaBCBcPx0ktMaMgYkx0iIspTCQmS1Jw6JUdwMHDmDJCUlPH1vr5AlSpA1arysXJlSXCe8Yc8kREmO0RElGsSEyWxOXYMOH4cOHFC6mz+a5RuxNkZqF5djmrV5GPVqtIQj+hFMNkhIqIcoSiy6unQIeDoUeDIEUl0UlKevtbTE6hdG6hVC6hZUz76+XH6iXIHkx0iIsqWx48lqTlwQBKcw4dlT6cnFS0K1K0rR+3acvj4cNUT5R0mO0RElCWRkcDff8vxzz8yJfXkqI2DgyQz9evLUa+eLO1mYkNqYrJDREQZevQI2LdPjr17ZXXUk81KvL2BRo2ABg0Af3+ZkuJ+TWRumOwQEREA2ffp77+BXbuA3btlpdSTyU2FCkDjxnI0aiR1Nhy1IXPHZIcypNFosHbtWrRv317tUIgol2i1wMmTwF9/ATt2SO3Nk9NSlSoBTZsCTZrI4eWlSqhEL4TJDmXo7t27cHd3VzuMLGnatClq1qyJOXPmqB0Kkdm7fx/Ytg3YulUSnIcPje8vVQpo1kyO11+XaSoiS8dkhzLkxT/fiKyCbvRm0yZJcI4dM56acnYG3ngDaN5cjrJlOS1F1ocdDazUtm3b0KhRI7i5uaFIkSJo3bo1rl27pr8/OTkZ/fv3h7e3NwoWLIhSpUphypQp+vs1Gg3WrVunvz1ixAiUL18eTk5OKFOmDMaOHYuUdOPdX3/9NWrWrInff/8dpUuXhqurK9577z3ExsZmGmNgYCDc3Nywbt06lCtXDgULFkSLFi0QFhamv6Znz55PTaUNGjRIvyFoz549sW/fPsydOxcajQYajQY3btzI3otGZCUeP5bk5tNPpftw3brAhAmyTFxRpIj4q6+A/ftlZGfdOqBvX9k/iokOWSOO7GRXfHzm99naAuk3fXzWtTY2smvd864tVMjE8OIxZMgQVK9eHXFxcRg3bhzeeecdBAcHw8bGBvPmzcOGDRuwcuVKlCxZEmFhYUZJxpOcnZ0RGBgIHx8fnDlzBn369IGzszOGDx+uv+batWtYt24dNm3ahMjISHTu3BlTp07F5MmTM33chIQETJ48GUuWLIG9vT369u2L9957DwcOHMjS85w7dy4uX76MqlWrYuLEiQCAYsWKZfFVIrIeUVGS4KxdK9NUCQmG+woXllGb1q2Bli05NUX5D5Od7CpcOPP7WrUCNm823C5e3Pg3T3pNmsiaTp3SpTPuymXi5vQdO3Y0uv3bb7+hWLFiOH/+PKpWrYrQ0FCUK1cOjRo1gkajQalSpZ75eGPGjEkXYmkMHToUQUFBRsmOVqtFYGAgnJ2dAQDdu3fHrl27npnspKSkYMGCBahfvz4AYPHixahUqRKOHj2KevXqPfd5urq6wt7eHk5OTpx6o3zn/n1JblavBvbskc00dXx9gTZtgLZtpcCYy8EpP2OyY6WuXLmCcePG4ciRI3jw4AG0Wi0AIDQ0FFWrVkXPnj3x5ptvokKFCmjZsiVat26N5s2bZ/p4K1aswLx583Dt2jXExcUhNTUVLk/swle6dGl9ogMA3t7eiIiIeGacBQoUQN26dfW3K1asCDc3N1y4cCFLyQ5RfnP/PrBmDbBqlfydlH6PqSpVgHfekaNWLU5JEekw2cmuuLjM77O1Nb79rDf8JzeCyaF6kzZt2qBUqVJYuHAhfHx8oNVqUbVqVSQnJwMAXnnlFYSEhGDr1q3YuXMnOnfujICAAKxevfqpxzp06BC6deuGCRMmoEWLFnB1dUVQUBBmzZpldJ2dnZ3RbY1Go0+yssvGxgbKE6NaKRlttENkxaKjZQRn+XLpgZM+wXnlFaBTJ6BjR6BcOfViJDJnTHayy5Qamty6NhMPHz7EpUuXsHDhQjRu3BgA8M8//zx1nYuLC7p06YIuXbrg3XffRcuWLfHo0SN4eHgYXXfw4EGUKlUKo0eP1p+7efPmC8cJAKmpqTh+/Lh+FOfSpUuIiopCpUqVAEj9zdmzZ42+Jjg42Cixsre3R1pGWygTWbCkJKnBWboU2LJFbuvUri0JTqdOQJky6sVIZCmY7Fghd3d3FClSBD///DO8vb0RGhqKkSNHGl0ze/ZseHt7o1atWrCxscGqVavg5eUFNze3px6vXLlyCA0NRVBQEOrWrYvNmzdj7dq1ORKrnZ0dBgwYgHnz5qFAgQLo378/Xn31VX3y88Ybb2DGjBlYsmQJ/P398ccff+Ds2bOoVauW/jFKly6NI0eO4MaNGyhcuDA8PDxgw62TyQIpijT2+/13YOVKKTrWqVwZ6NoV6NKFIzhEpuI7ghWysbFBUFAQTpw4gapVq2Lw4MGYMWOG0TXOzs6YPn066tSpg7p16+LGjRvYsmVLhklC27ZtMXjwYPTv3x81a9bEwYMHMXbs2ByJ1cnJCSNGjMD777+Phg0bonDhwlixYoX+/hYtWmDs2LEYPnw46tati9jYWHz44YdGjzF06FDY2tqicuXKKFasGEJDQ3MkNqK8EhoKTJokS78bNwZ+/lkSnZdeAkaMAP79Fzh7FhgzhokOUXZolCcLIvKhmJgYuLq6Ijo6+qmi28TERISEhMDPzw8F0y8npxcWGBiIQYMGISr9n69Whj8/lJnHj6UOZ9EiqcPR/SYuXBh4912ge3dZrPlkCSARGTzr/Ts9TmMREeWhc+eAhQuBJUuAyEjD+ddfBz76COjQIUdK94goHSY7RES57PFjWSr+889Sk6NTsiTQs6ccfn5qRUdk/ZjskGp69uyJnj17qh0GUa65dg348Ufgt9+AR4/knK2tNPr75BPgzTc5TUWUF5jsEBHlIK1WNtxcsEC2bdApVUoSnI8+4nYNRHmNyQ4RUQ6IjQUCA4H584ErVwznW7YE+vUD3nqLozhEamGyQ0T0Am7cAObOlamqmBg55+oK9OolO4mXLatqeEQEJjtERNly9Cgwa5ZswqnbFaVCBWDgQODDD5+9VzAR5S0mO0REWaTVAps3AzNmAH//bTj/5pvAkCFA8+ZPb3dHROpjskNE9BwpKcCKFcDUqdInBwDs7GT7hiFDgBo11I2PiJ6Nf4MQmeDGjRvQaDQIDg4GAOzduxcajcaqu0DnZ48fy6qqcuWko/G5c4CzMzB8OBASAixezESHyBJwZIeI6Anx8dIfZ8YM4N49OVe8ODBoEPD550AG++USkRljskNZlpycDHt7e7XDIMo1sbHAd99J4fGDB3KuVCkZyfnoI8DRUd34iCh7OI1lpbRaLaZMmQI/Pz84OjqiRo0aWL16tf7+wMBAuD3x5+m6deug0Wj0t7/++mvUrFkTv/zyi9FGlqGhoWjXrh0KFy4MFxcXdO7cGfd0f/6m+7qffvoJvr6+cHJyQufOnREdHW30/X755RdUqlQJBQsWRMWKFfH9998b3T9ixAiUL18eTk5OKFOmDMaOHYuUlJSnvs/vv/+O0qVLw9XVFe+99x5iY2Of+docOHAATZs2hZOTE9zd3dGiRQtE/rdJ0bZt29CoUSO4ubmhSJEiaN26Na5du5aFV5wsWVyc1OOULg2MGiWJTtmywK+/Ss+cvn2Z6BBZMo7smEhRgIQEdb63kxOQLhd5pilTpuCPP/7Ajz/+iHLlymH//v344IMPUKxYMTRp0iTL3/Pq1av4888/sWbNGtja2kKr1eoTnX379iE1NRX9+vVDly5dsHfvXqOvW7lyJTZu3IiYmBj06tULffv2xdKlSwEAS5cuxbhx47BgwQLUqlULp06dQp8+fVCoUCH06NEDAODs7IzAwED4+PjgzJkz6NOnD5ydnTF8+HD997l27RrWrVuHTZs2ITIyEp07d8bUqVMxefLkDJ9PcHAwmjVrho8//hhz585FgQIFsGfPHqSlpQEA4uPjMWTIEFSvXh1xcXEYN24c3nnnHQQHB8OGy2ysTkIC8MMPwLRpwP37cq5CBWD0aCk+LsDfkETWQSElOjpaAaBER0c/dd/jx4+V8+fPK48fP1YURVHi4hRFUp68P+LisvZ8EhMTFScnJ+XgwYNG53v16qV07dpVURRFWbRokeLq6mp0/9q1a5X0PxLjx49X7OzslIiICP25HTt2KLa2tkpoaKj+3Llz5xQAytGjR/VfZ2trq9y6dUt/zdatWxUbGxvl7t27iqIoStmyZZVly5YZff9JkyYp/v7+mT6vGTNmKLVr1zaKz8nJSYmJidGfGzZsmFK/fv1MH6Nr165Kw4YNM73/Sffv31cAKGfOnFEURVFCQkIUAMqpU6cURVGUPXv2KACUyMjIDL/+yZ8fMg9JSYoyf76ieHkZ/n+VLasoS5YoSmqq2tERUVY96/07Pf7dYoWuXr2KhIQEvPnmm0bnk5OTUatWLZMeq1SpUihWrJj+9oULF+Dr6wtfX1/9ucqVK8PNzQ0XLlxA3bp1AQAlS5ZEiRIl9Nf4+/tDq9Xi0qVLcHZ2xrVr19CrVy/06dNHf01qaipcXV31t1esWIF58+bh2rVriIuLQ2pqKlxcXIziK126NJydnfW3vb29ERERkenzCQ4ORqdOnTK9/8qVKxg3bhyOHDmCBw8eQPtft7jQ0FBUrVo1068jy5CWBixfDowbJ6upAKnJGTdOGgFyJIfIOvG/tomcnGR+X63vnRVx/wW4efNmo4QDABwcHAAANjY2UBTF6L709TA6hQoVykakWYtv4cKFqF+/vtF9tv9tHnTo0CF069YNEyZMQIsWLeDq6oqgoCDMmjXL6Ho7Ozuj2xqNRp+gZMTxOYUXbdq0QalSpbBw4UL4+PhAq9WiatWqSE5OzvLzI/OjKNIM8KuvgDNn5JyXFzB2LNC7N8C6eyLrxmTHRBoNkAvv/zmqcuXKcHBwQGhoaKb1OcWKFUNsbCzi4+P1CY2ud8yzVKpUCWFhYQgLC9OP7pw/fx5RUVGoXLmy/rrQ0FDcuXMHPj4+AIDDhw/DxsYGFSpUgKenJ3x8fHD9+nV069Ytw+9z8OBBlCpVCqNHj9afu3nzZpae/7NUr14du3btwoQJE5667+HDh7h06RIWLlyIxo0bAwD++eefF/6epK5jx4Bhw4B9++S2mxswYgQwYID5/18mopzBZMcKOTs7Y+jQoRg8eDC0Wi0aNWqE6OhoHDhwAC4uLujRowfq168PJycnfPXVVxg4cCCOHDmCwMDA5z52QEAAqlWrhm7dumHOnDlITU1F37590aRJE9SpU0d/XcGCBdGjRw/MnDkTMTExGDhwIDp37gwvLy8AwIQJEzBw4EC4urqiZcuWSEpKwvHjxxEZGYkhQ4agXLlyCA0NRVBQEOrWrYvNmzdj7dq1L/zajBo1CtWqVUPfvn3x2Wefwd7eHnv27EGnTp3g4eGBIkWK4Oeff4a3tzdCQ0MxcuTIF/6epI6QEBnJCQqS2wULAl98IYmOu7u6sRFR3uLyEis1adIkjB07FlOmTEGlSpXQsmVLbN68GX5+fgAADw8P/PHHH9iyZQuqVauG5cuX4+uvv37u42o0Gqxfvx7u7u547bXXEBAQgDJlymDFihVG17388svo0KEDWrVqhebNm6N69epGS8t79+6NX375BYsWLUK1atXQpEkTBAYG6uNr27YtBg8ejP79+6NmzZo4ePAgxo4d+8KvS/ny5bFjxw78+++/qFevHvz9/bF+/XoUKFAANjY2CAoKwokTJ1C1alUMHjwYM2bMeOHvSXkrOlr64lSsKImORiP1OJcuyfJyJjpE+Y9GebJwIx+KiYmBq6sroqOjnyqATUxMREhIiFGfGXq2r7/+GuvWrcvStJi1489P3klLk744Y8YYlpEHBADTpwMm1uUTkYV41vt3epzGIiKLt2ePbOVw+rTcrlBBuiC3apX13lREZL04jUVEFis0FOjUCXjjDUl03N2BuXNlxdXbbzPRISLBZIdy3Ndff80pLMpViYnAN99IXc7q1YCNDdC/v2ztMHAg8ERHAiLK5ziNRUQWZfNmSWiuX5fbr70GzJ8PVK+ublxEZL44skNEFiEsDOjQAWjdWhIdHx9g2TJg714mOkT0bEx2iMispaRIsXGlSsDatYCtLTB0KHDxomzWybocInoeTmMRkdk6cgT45BPDKquGDWWX8mrV1I2LiCwLR3aIyOzExkpdjr+/JDoeHtJDZ/9+JjpEZDqO7BCRWdm0CejbV2p0AOl+PGsWULSounERkeViskNEZuH+fdmcU7fzSJkywI8/Am++qW5cRGT5OI1FlA1NmzbFoEGD1A7DKiiK7GFVubIkOra2srfVmTNMdIgoZ3Bkh7IsOTkZ9vb2aodBVuTuXeDzz4H16+V29erAokXAK6+oGxcRWRezHtlJS0vD2LFj4efnB0dHR5QtWxaTJk1C+r1LFUXBuHHj4O3tDUdHRwQEBODKlSsqRm0etFotpkyZon/tatSogdWrV+vvDwwMhJubm9HXrFu3Dpp063i//vpr1KxZE7/88ovRRpahoaFo164dChcuDBcXF3Tu3Bn37t176ut++ukn+Pr6wsnJCZ07d0Z0dLTR9/vll19QqVIlFCxYEBUrVjTaFR0ARowYgfLly8PJyQllypTB2LFjkZKS8tT3+f3331G6dGm4urrivffeQ2xsbKavi+55r1u3DuXKlUPBggXRokULhOkKRAD07NkT7du3N/q6QYMGoWnTpvr79+3bh7lz50Kj0UCj0eDGjRuZfk96mqIAf/whoznr1wMFCgBffw0cO8ZEh4hynlmP7EybNg0//PADFi9ejCpVquD48eP46KOP4OrqioEDBwIApk+fjnnz5mHx4sXw8/PD2LFj0aJFC5w/fz5Xd5mOj8/8PltbIP23fta1NjaAo+Pzry1UyLT4pkyZgj/++AM//vgjypUrh/379+ODDz5AsWLF0KRJkyw/ztWrV/Hnn39izZo1sLW1hVar1Sc6+/btQ2pqKvr164cuXbpg7969Rl+3cuVKbNy4ETExMejVqxf69u2LpUuXAgCWLl2KcePGYcGCBahVqxZOnTqFPn36oFChQujRowcAwNnZGYGBgfDx8cGZM2fQp08fODs7Y/jw4frvc+3aNaxbtw6bNm1CZGQkOnfujKlTp2Ly5MmZPqeEhARMnjwZS5Ysgb29Pfr27Yv33nsPBw4cyNJrMnfuXFy+fBlVq1bFxIkTAQDFihXL8mua392/D3z2GbBmjdx+5RUZzWFjQCLKNYoZe/vtt5WPP/7Y6FyHDh2Ubt26KYqiKFqtVvHy8lJmzJihvz8qKkpxcHBQli9fnuXvEx0drQBQoqOjn7rv8ePHyvnz55XHjx8bnZe/TTM+WrUyfgwnp8yvbdLE+NqiRTO+zhSJiYmKk5OTcvDgQaPzvXr1Urp27aooiqIsWrRIcXV1Nbp/7dq1SvofifHjxyt2dnZKRESE/tyOHTsUW1tbJTQ0VH/u3LlzCgDl6NGj+q+ztbVVbt26pb9m69atio2NjXL37l1FURSlbNmyyrJly4y+/6RJkxR/f/9Mn9eMGTOU2rVrG8Xn5OSkxMTE6M8NGzZMqV+/fqaPsWjRIgWAcvjwYf25CxcuKACUI0eOKIqiKD169FDatWtn9HVffPGF0iTdP1aTJk2UL774ItPvo5PZz09+tXatohQrJj/TBQooyqRJipKcrHZURGSpnvX+nZ5Zj+w0aNAAP//8My5fvozy5cvj33//xT///IPZs2cDAEJCQhAeHo6AgAD917i6uqJ+/fo4dOgQ3nvvvQwfNykpCUlJSfrbMTExuftE8tjVq1eRkJCAN5+o7kxOTkatWrVMeqxSpUoZjVpcuHABvr6+8PX11Z+rXLky3NzccOHCBdStWxcAULJkSZQoUUJ/jb+/P7RaLS5dugRnZ2dcu3YNvXr1Qp8+ffTXpKamwtXVVX97xYoVmDdvHq5du4a4uDikpqbCxcXFKL7SpUvD2dlZf9vb2xsRERHPfE4FChTQxwkAFStW1Mdfr169rL40ZILoaOmbs2SJ3K5aVT438ceRiChbzDrZGTlyJGJiYlCxYkXY2toiLS0NkydPRrdu3QAA4eHhAABPT0+jr/P09NTfl5EpU6ZgwoQJLxRbXFzm99naGt9+1nuvzRNVUzlR+hH3X3CbN282SjgAwMHB4b/va2NU+wTAqB5Gp5Cp82cmxLdw4ULUr1/f6D7b/168Q4cOoVu3bpgwYQJatGgBV1dXBAUFYdasWUbX2z2xvbVGo4FWq32h+LL62lDW/P030L07cPOm/LwPHy71Of/9KBIR5TqzTnZWrlyJpUuXYtmyZahSpQqCg4MxaNAg+Pj46Os6smPUqFEYMmSI/nZMTIzRSEVWmJID5Na1malcuTIcHBwQGhqaaX1OsWLFEBsbi/j4eH1CExwc/NzHrlSpEsLCwhAWFqZ/zc6fP4+oqChUrlxZf11oaCju3LkDHx8fAMDhw4dhY2ODChUqwNPTEz4+Prh+/bo+cX3SwYMHUapUKYwePVp/7ubNm1l6/s+TmpqK48eP60dxLl26hKioKFSqVAmAvDZnz541+prg4GCjxMre3h5paWk5Eo+1Sk6WpGbqVJmM9fOTouQGDdSOjIjyG7NOdoYNG4aRI0fqp6OqVauGmzdvYsqUKejRowe8vLwAAPfu3YO3t7f+6+7du4eaNWtm+rgODg76EQ5r5OzsjKFDh2Lw4MHQarVo1KgRoqOjceDAAbi4uKBHjx6oX78+nJyc8NVXX2HgwIE4cuQIAgMDn/vYAQEBqFatGrp164Y5c+YgNTUVffv2RZMmTVCnTh39dQULFkSPHj0wc+ZMxMTEYODAgejcubP+32zChAkYOHAgXF1d0bJlSyQlJeH48eOIjIzEkCFDUK5cOYSGhiIoKAh169bF5s2bsXbt2hx5fezs7DBgwADMmzcPBQoUQP/+/fHqq6/qk5833ngDM2bMwJIlS+Dv748//vgDZ8+eNZoCLF26NI4cOYIbN26gcOHC8PDwgM2Tw3T52KVLwPvvAydPyu2PPgLmzgXSzTgSEeUZs/7tnJCQ8NQbiG5FEAD4+fnBy8sLu3bt0t8fExODI0eOwN/fP09jNTeTJk3C2LFjMWXKFFSqVAktW7bE5s2b4efnBwDw8PDAH3/8gS1btqBatWpYvnw5vv766+c+rkajwfr16+Hu7o7XXnsNAQEBKFOmDFbo2t7+5+WXX0aHDh3QqlUrNG/eHNWrVzdaWt67d2/88ssvWLRoEapVq4YmTZogMDBQH1/btm0xePBg9O/fHzVr1sTBgwcxduzYHHltnJycMGLECLz//vto2LAhChcubBR/ixYtMHbsWAwfPhx169ZFbGwsPvzwQ6PHGDp0KGxtbVG5cmUUK1YMoaGhORKbpVMU4LffZIXVyZOyp9Xq1XKOiQ4RqSZPyqWzqUePHkqJEiWUTZs2KSEhIcqaNWuUokWLKsOHD9dfM3XqVMXNzU1Zv369cvr0aaVdu3aKn5+fSatfsrMaizI3fvx4pUaNGmqHkaGMVqHlpvz08xMZqShduhhWEDZrpii3b6sdFRGpLTU19x7bKlZjzZ8/H2PHjkXfvn0REREBHx8ffPrppxg3bpz+muHDhyM+Ph6ffPIJoqKi0KhRI2zbti1Xe+wQkbFDh2Ta6sYNKdD/5hspRObMHpH5S00FYmOBx4+B/8osAQD//CMb8sbHy6Kc+Hg5EhKAtDRg/nzDtUOHAnv3yn0JCfJYuiM1FdBqgXQ9a/OcWSc7zs7OmDNnDubMmZPpNRqNBhMnTtQ3dyOivKPVyo7ko0bJLz8/P2DZMuDVV9WOjCj/CA8HHj4EoqIMR3S0HDY2wIgRhms/+ww4ckSSm5gY+ZiYKPe5uwOPHhmunTAB2Lkz4+9pYwPMm2dIYK5dA06cyDzGxETjBrp5TaMoT6yxzYdiYmLg6uqK6Ojop/q4JCYmIiQkxGi7BKKssuafn4cPgR49gM2b5XaXLsBPPwHpWiURURalpADpO2ls2iTtGh4+lATk0SPD5y4uwPbthmvr1Mk80XgygQkIANKVuRopVMi4rcqIEbKFS+HCcl/6w8lJ/sjRtVo5ehR48EDOOzo+fXh45M7IzrPev9Mz65EdIjJPBw9KcnPrlvTLmTcP6NNH3WFqInOi1cqoSfrk/5dfgKtXgXv3pP/a/fuGw8cHuHzZcO24ccCpUxk/toeH8e2iReVwc5PD1dVwPHnthAky5eTsLEmTs7PheHKf52nTsv58zb0fK5OdLOIAGGWHtf3cKIpMW40cKdNW5csDK1cCNWqoHRlR3lAU46R+2TJJUu7eBe7ckY9370pCU6aMcQLzww+GdgxPun/f+PYbb8jXe3gARYoYPrq7y8f0tm3LevwNG2b9WmvCZOc5dB19k5OT4ajmhCNZpISEBABPd3q2RNHRwMcfGzbw7NpVpq24pJyszYULUoMSGirHrVtSqHvrlkzhnD5tuHbWrMwTmHv3jG937gy89hpQvDhQrJjho+5Ib+bMnH1O+R2TnecoUKAAnJyccP/+fdjZ2bFxHGWJoihISEhAREQE3Nzc9EmzpTp9GujYUYbg7e2BOXOk0JHTVmRpEhKAkBBJZkJCZAVhSgqwYIHhmm7dMp9CcnIyHt155x2gbl3A2/vpo3hx469NXyhMeYvJznNoNBp4e3sjJCQkx7YroPzDzc1N3zXaUv3+O/Dpp7KEtGRJYNUq85+fp/wtJkZGYdLtYIMePYAdO2Tl0pMcHWUZtS6BqVFDPi9ZEvD1NRwvvSRHemPG5N7zoJzDZCcL7O3tUa5cOSQnJ6sdClkQOzs7ix7RSUkBhgwx/MXbvDmwdKkUQhKZg5s3gTNngIsXpTbm0iX5GB4u002xsYYEJjbWkOi4ugJly0qrBN2RmmpYDbVokTrPh3IPl54j60vXiPKL8HCpL/j7b7k9bpwcFpy7kYVKSwOuXwfOnpVp1GHDDPe1aSNLtDPi6QmcO2co5j19WjanLVtWinzJOnDpORFly+HDUp9z544sTf39d6BtW7WjovzixAlg/35JTk6fBs6fNzS9A2Q6SlcLU6uWjO5UqgRUqGA4ypeXn930qlfPu+dA5ofJDhHp/for0Lev/AVcqRKwdq28eRDlJEWR0ZpTp+QYNUoa1wGSXM+da3y9o6P8PFapYpz4TJwoB9HzMNkhIqSmSn2Obq+bd94BFi/msnLKGXfvyj5Lx4/LyM3Jk0BkpOH+Vq0M/V9ee02WeVevLke1alJTwylUehFMdojyuYcPpRuyroX8xInA6NHcxJOyJzJS9l6qVUvqZgBgxQpg8GDj6+ztJZGpVct4yqlDBzmIchKTHaJ87Nw5oF076TlSqJBMIbzzjtpRkaVQFFkJdeCA7Hx/6JA05AOAwECprwEAf3+gdm3pR1O7thxVqjy9PQFRbmGyQ5RPbd4sXZBjY4HSpYENG+QvbaKsOHwYaN1aRgafVLasJEI69evLFBaRWpjsEOUziiIFoF9+KZsVNmkCrF7N/jn0tORk2fV63z45mjeXnxtAEpqHD4GCBSWZadAAePVVOZ7sHEykNiY7RPlISgowYIDsaQUAvXsD333H6QQSWi0QHCz1W7t3S5+l+HjD/amphmSnWDEpNq5alT8/9AwrVwJLlgDr16taZc5khyifiIwEOnWSNzKNRjYaHDyY+1vld7GxhlV3aWky0hcXZ7i/aFE516QJ8Prrxl/7yit5FyeZsdu3ZQhQd3z3HVCunNx365bMmV+6ZLx/Rx5jskOUD1y/Drz9thSTFioELF8u3Wcp/0lMlCmprVuBbdtkNOfyZbnPzk7qcOLigGbNgDfekJEbrswjI1evytz3kSPA0aPSgTS9w4cNyU6rVtJESeW5TSY7RFbuyBFJbO7fl80MN26UjQ4p/wgLk3/3LVtkeurxY8N9NjayPYhuv9rly9WJkcyQVisjMocPy1K6qlXl/Llz0glSx8ZGltfVrStH48aG+ypWlENlTHaIrNiaNUC3bvLX/CuvyBuej4/aUVFu02plelI3RTlhgnTH1vHxAd56S45mzQA3N1XCJHOTkCAjNQcPGvoJ6Lo/jh9vSHZefVXmxOvXB+rVk18uhQqpF3cWMNkhskKKAnz7LTB0qHz+9ttAUJChJT9Zn+RkYO9e2eJj/Xr5WL++3Ne+vUxhtm4tCU716qzVIkjFeYH/0oDLl2V0JjXV+BpHR6BOHaBkScM5T08pPLYgTHaIrExamhQe67Z+6NtXlpoX4P92q5OYKHU3q1fL7t/R0Yb7Nm82JDutW8tB+dytW1KwtX+/HPXrS/dHQHoJODlJtXrDhnI0aCBz3nZ2qoadE/jrj8iKJCYCH3wA/Pmn3J45U/a84l/x1ufcOZlNSL9yqnhx6Yj9zjtSXEz5nKIAf/wB7Nkjw34hIcb3JycbPre1lVbqVtpwi8kOkZV49EimK/7+W/qeLF4MvPee2lFRTkhJAf76S0ZuunaVcxUqSEM/d3egY0c5/P25YWa+dveuZMEBAXJbowGmTwfOnpXbtrZSX/Paa9JLQLf7qo6VJjoAkx0iqxAaCrRsKfsSuboC69YBTZuqHRW9CEWRncKXLpVpqocPgRIlZNNWGxuZljx2TEopuDQ8n4qKklEbXRfICxckA46MlI8A8PHHwL178guhYUNDU6V8hskOkYU7exZo0UJaXZQoIf1TuMeV5bpyRTZk/f134MYNw/nixWV6Kj7e8H5VurQaEZLqfv9dGvcdOyZL73Q0GikyvnsX8POTc09uN59PMdkhsmAHDkjhaVSU/I7bulV66ZDlmjMH+P57+bxwYeDdd4H335fuxSwyz2cURRr4bd8OdO5saMwXHi4NtACZzwwIkB4CTZoAHh7qxWvG+F+HyEJt2iStLhITZdHExo38PWdJtFqZgVi0COjXT+ptAKBHD6kj7d5dio2dnNSNk/JYXJxMSW3bJoeuqNjVVX4oAKBDB6mvCQjgXzdZxGSHyAIFBsomnmlp0kNn5Uq+KVqKu3clwfnlF8P7mIODIdmpV086HVM+c/687NL7999Ska5jbw80aiSV6Dply8pBWcZkh8jCzJ5t2Hm6Rw9g4UKraINh1bRaYMcO4OefgQ0bJEkFABcXmaLq1Uvd+CiPJSbKsJ6Dg6FHQJEiMqIDAGXKSPfHli1l/tLMuxNbAiY7RBZCUYBx44BvvpHbQ4fKqlL20DF/igJ8+qmsmgNkUUyfPjINyRG5fCI8XDo9btwofQQSEiTR0SU7np7SE6duXdlEk/+xcxSTHSILoNUCX3wBLFggt6dMAUaOVDcmytzx49LnaPZsGXWztZXk9No1SXKqVFE7Qsozs2YBq1YZCop1SpQAKlWSTFiX2HTrlvfx5RNMdojMXGoq8NFH8kefRiMrTj//XO2o6EkpKbLx6ty5sn8iIL3bOnWSzwcMUC82yiNpaUBwMFC7tuHczp2GRKduXVk+2aYNULMmR2/yEJMdIjOWlCRdkNetk9GBxYv5x5+5efQI+OknSUJv35ZzdnayUrhCBXVjozyQmChN/daulYKs+/dlvlK3SmrgQGlt3qaNbDdPqmCyQ2SmEhKkidyOHVLHuGqV/L4k83HrliQ0CQlyu3hx4LPP5PD2Vjc2ykXx8dLU6s8/pQ4nNtZwn5ubdDLWJTtvvaVKiGSMyQ6RGYqNldHu/ftlIcaGDdzY0VzcugW89JJ8/tJLstVQbKxsuNqliySmZOXWrzceYi1RQkZv2reXxn5cHml2mOwQmZnISFlxevSoLE3eulWaBpJ6FEUW0EyZIv8uN28a9kxcv15aoLD8wgrFxsrqqVWrJIkZNEjOt24NVKwoHzt2lOZI3KDMrDHZITIj9+8DzZtLjaOHh0xhpa91pLyVliZFx1OnAidPyrkCBaTv2zvvyG12rbYy8fHSnnzFCunumJQk58PCDMmOi4tMVZHFYLJDZCbCw2V7m/PnpeXGzp1A1apqR5U/paYCQUHA5MnAxYtyzskJ+OQTma5ih34r9fHHkuToirAA6XnTubNhWR1ZJCY7RGbgzh2pybl0Sab/d+8GypdXO6r8Kzxc3vdSUmSKauBAWTpepIjakVGOSUsDDh+WDo86cXGS6JQpIwlOly5AjRqco7QCGkVRFLWDUFtMTAxcXV0RHR0NFxcXtcOhfObWLUl0rlyREYM9e7jtTV5LTQX27pV9FXW++kpmK/r2lY9kBRRFOj4uXSpDd/fuyVBqpUpy/+nTQHKyzB0zwbEIWX3/5sgOkYpCQ2Xrm+vXgdKlZUTHz0/tqPKPtDRg+XJgwgTg6lWpy6lVS+773//UjY1y0PXr0pVz6VLg8mXDeQ8P+StDl+xUr65OfJTrmOwQqeTmTaBpU+DGDRk137MHKFlS7ajyB61WWqSMG2eoySlaVJJPXbJDVmLPHuO+DY6OQLt2snS8eXPZVZysHpMdIhWkT3TKlZMRHV3vFso9uiXkX30FnDgh5zw8gGHDgP79gcKF1Y2PXlBKCrB9u3Q1fvddOdeggWSytWoBH3wgy+icndWNk/Ickx2iPHbzpkxd6RKdPXukKJlyX2Ii8OGHUqpRuDDw5Zeyuoo1ORbu9GkgMFCmqSIiZKi0Y0epu3FwAEJCmMnmc0x2iPKQrkYnJAR4+WUmOnnh5k2ZHtRoZAZj4kRpkfLVV0CxYmpHR9n28CGwbBmwaBFw6pThfPHiMk31+LH0CwCY6BCTHaK8EhoqU1chIbLaiolO7nr4EJg0Cfj+e+D332UVMSC9csgKDBsmiQ4g2zO0bQv07Am0aMHtGugp7G9NlAdu3zaM6JQtK8ucWaOTO5KSgJkz5XWeO1fKOHbvVjsqeiE3bkg1+ZkzhnM9ewI1awLz5gF37wKrV8v2DUx0KAMc2SHKZXfvymKQ69dlWfmePUx0coOiyD5VQ4cC167JuZo1genTgTffVDU0yo7kZGDdOmDhQmDXLvkHfvQIWLBA7m/c2Hj6iugZmOwQ5aKICGlUd/my1I3s2cOtBnJL//4yZQUAXl7SJ6dHD+7PaHEuX5YEZ/Fi2SxOJyDAOGtl0z8yAZMdolzy8KH8fj5/Xmpz9uwBSpVSOyrr1bEj8NtvssJq5EjWpFqktDTZXTw8XG77+AAffQT06sVum/RCmOwQ5YKoKOlXduaMjDLs3i2rYSlnpKVJYpOSIts5ADJVePOmLMYhC3Htmqyo+uorwNZWjt69geBgoE8foFUr2Wae6AXxp4goh8XFAW+9JVsPFCsm5Qbc1DPnHD0K9OsnWxwVKiSrjHWr2pjoWIDUVGDTJplz/OsvOVe7tiQ2gPQG4BQV5TAmO0Q56PFjWQF7+LDslr1zJ1C5stpRWYfISBkA+OknqVV1cZE9rZjgWIi7d4FffgF+/ll2vwUkqWnRQv6z6DDRoVzAZIcohyQnS4f6PXukG/327dxXMCcoiuzhOHSoFHwD0gV5+nTA01Pd2CiLLl8GqlSRUR1Atm/o1UuaHnF+l/JAtpOdq1ev4tq1a3jttdfg6OgIRVGgYUZO+VRqKvD++8CWLdKld/NmoG5dtaOyDiEh8r6YkiKbU//wg9SwkhmLj5e6m4YN5Xa5ckDVqjLv+Pnn8leBg4OqIVL+YnKy8/DhQ3Tp0gW7d++GRqPBlStXUKZMGfTq1Qvu7u6YNWtWbsRJZLa0Wnkz/vNP2UB5/XppAULZpyiG2YwyZYCxY6VX3JAh3KTarIWESC3OL7/IXwC3b8t8o0YD7NvHTchINSZ3oBg8eDAKFCiA0NBQOOn2HQHQpUsXbNu2LUeDA4Dbt2/jgw8+QJEiReDo6Ihq1arh+PHj+vsVRcG4cePg7e0NR0dHBAQE4MqVKzkeB1FGFAUYNAhYskQWkqxcyQZ2L+rQIdmgOn2/uLFjZTk5Ex0zpChShd++vbStnjlTliN6ekonTR0mOqQik5OdHTt2YNq0aXjpiRaw5cqVw82bN3MsMACIjIxEw4YNYWdnh61bt+L8+fOYNWsW3NMVs02fPh3z5s3Djz/+iCNHjqBQoUJo0aIFEhMTczQWooyMHw/Mny9/uC5ZIiuDKHvi4oCBA2Xm499/pRiZzNyRI0C1atJQav16SXxatJDVVpcvSwtrIjNg8jRWfHy80YiOzqNHj+CQw3Ow06ZNg6+vLxbpNnsD4JeusZSiKJgzZw7GjBmDdv+9yyxZsgSenp5Yt24d3nvvvQwfNykpCUlJSfrbMTExORo35Q+zZ8tGkwDw3XdSs0PZs2uXtFe5cUNu9+gBcEbcTGm1hrbUXl6yhXyhQrJXVf/+QMWKqoZHlBGTR3YaN26MJUuW6G9rNBpotVpMnz4dr7/+eo4Gt2HDBtSpUwedOnVC8eLFUatWLSxcuFB/f0hICMLDwxEQEKA/5+rqivr16+PQoUOZPu6UKVPg6uqqP3zZv59M9Ouv0qkXACZPlppLMl1MDPDppzIwcOOGbKmxfTsQGAgUKaJ2dGTkxAnggw+Azp0N50qVAtaulaXkCxYw0SHzpZjozJkzSvHixZWWLVsq9vb2yrvvvqtUqlRJ8fT0VK5evWrqwz2Tg4OD4uDgoIwaNUo5efKk8tNPPykFCxZUAgMDFUVRlAMHDigAlDt37hh9XadOnZTOnTtn+riJiYlKdHS0/ggLC1MAKNHR0TkaP1mn1asVxcZGUQBFGTZMUbRatSOyXD/+KK8joCh9+ypKTIzaEZGR1FRFWbdOUV57zfAPpdEoSmio2pERKYqiKNHR0Vl6/zZ5Gqtq1aq4fPkyFixYAGdnZ8TFxaFDhw7o168fvL29czQR02q1qFOnDv73v/8BAGrVqoWzZ8/ixx9/RI8ePbL9uA4ODjk+5Ub5w+7dMl2l1cq0y7Rp7IH2Ivr0AQ4cAD7+GGjaVO1oSC8hQYbXvv0WuHpVzhUoAHTpAgwezN1syeJkq8+Oq6srRo8endOxPMXb2xuVn2g/W6lSJfz5558AAC8vLwDAvXv3jBKte/fuoSYL4yiHHT8uBcjJybLp5I8/MtEx1d9/y27kf/4JODlJ6Ue6WXEyF0uWyJ4cgHQ3/vRTqcfR7ctBZGFMrtlZtGgRVq1a9dT5VatWYfHixTkSlE7Dhg1x6dIlo3OXL19Gqf+2jvbz84OXlxd27dqlvz8mJgZHjhyBv79/jsZC+dulS7LfVVycbDi5dKksNaesSUoChg2TZoDbtgFTpqgdERm5fBk4eNBwu3t36Yo5fz4QFib/YEx0yJKZOj9Wrlw5Zffu3U+d37t3r1K+fHlTH+6Zjh49qhQoUECZPHmycuXKFWXp0qWKk5OT8scff+ivmTp1quLm5qasX79eOX36tNKuXTvFz89Pefz4cZa/T1bn/Ch/CgtTlJIlpVyhdm3WlZjq9GlFqVbNUPLx8ceKEhWldlSkKIqiHDigKO3bSx1OlSosQCOLk9X3b5OTHQcHByUkJOSp8yEhIUrBggVNfbjn2rhxo1K1alXFwcFBqVixovLzzz8b3a/VapWxY8cqnp6eioODg9KsWTPl0qVLJn0PJjuUmUeP5D0AUJTy5RUlIkLtiCxHWpqifPutojg4yOtXrJiibNigdlSkpKUpysaNitKwoSEDBRSlbVv5gSeyIFl9/9YoiqKYMhJUsmRJLFiwAG3btjU6v379evTr1w+3dLvZWpCYmBi4uroiOjoaLuzySf95/Bho3hz45x/Ax0dG+f+bQaUsGDNGluUDwNtvy3J9btypsr/+kgLjc+fktr29TFl9+aVsPEZkYbL6/m1yzU7Xrl0xcOBA7NmzB2lpaUhLS8Pu3bvxxRdfZNrEj8jSpKYCXbtKouPqKr1fmOiYpm9f4KWXZKukjRuZ6JgFrVYSHWdnYPhw2cvql1+Y6JDVM3k11qRJk3Djxg00a9YMBQrIl2u1Wnz44Yf6JeJElkxRZCHK+vWyMfOGDbJhMz1bYqIkNZ06yW0fH1m1zC4PKomKktbejo6ygyogQ5U//SSNAd3c1IyOKE+ZPI2lc/nyZfz777/6zTlLWfCfvZzGovS+/hqYMEGWRa9eDbzzjtoRmb8LF2Qk7N9/gTVr+JqpKiJC+uN89x0QGytJzc2b3IiTrFJW37+z1WcHAMqXL4/y5ctn98uJzNLPP0uiA8h7Bd+0n2/xYpmySkgAihWT/jmkglu3gBkzgIULpeAMkCHJkSP5j0L5XpaSnSFDhmDSpEkoVKgQhuiGQzMxe/bsHAmMKK9t3GjY42rcOOCzz9SNx9zFx0ufucBAud2sGfD770AON1KnrPj9d6BXLyAlRW7XqweMHg20bm3YtJMoH8tSsnPq1Cmk/Pef6OTJk9Bk0jY2s/NE5u7oUemEr9XKe8bXX6sdkXk7f15qc86fl/fSCROAUaPYaDFPpd993N8fSEuTPTdGj5bMk7+PifSyXbNjTVizk79dvSrvFQ8eSJfk9esBOzu1ozJva9bIlhleXsDy5dzXKk+dOwd8840kOkuXGs5fuQKUK6deXEQqyJWl5ykpKShQoADOnj37wgESmYOICKBlS0l0atcGVq5kopMVHTrI3mDBwUx08syZMzKcVrUqEBQkx+3bhvuZ6BBlyqRkx87ODiVLlkRaWlpuxUOUZ+LjgTZtgGvXAD8/YPNmoHBhtaMyTzduSPnHnTuGc59+yt45eeL0aeDdd4Hq1WV5ICDZ5okT3K+KKItMrlwbPXo0vvrqKzx69Cg34iHKE2lpwPvvS62OhwewdSvfuDOzdSvwyiuSDOoKuCmP/PknUKOGfNRoZGTn9Gm5XbOm2tERWQyTl54vWLAAV69ehY+PD0qVKoVChQoZ3X/y5MkcC44oNyiKdMzfsMHQNLBCBbWjMj9arWz3MH68vGZ16wLz5qkdVT6QmAgULCift2gBFC8OvP46MHYsUKWKurERWSiTk5327dvnQhhEeWfuXGD+fPn899+Bhg3VjcccxcQAH34oxdqATFnNnctuyLnq/HlZBhgSIkOOGo3Mq165woaARC+Iq7HA1Vj5yZo1Uv6gKMD06cCwYWpHZH5u3JCi7UuXZJ/IH34APv5Y7ais2OXLsnZ/+XL5wQSAI0ekVw4RPVOud1A+fvw4Lly4AACoXLkyateund2HIsoTR44A3brJ+8nnnwNDh6odkXkqWhQoUEBqX9es4XturgkJASZOBJYskTlDQFp2f/21FCMTUY4xOdm5desWunbtigMHDsDtv43koqKi0KBBAwQFBeGll17K6RiJXlhIiKy8SkwE3n5bak/Yc81AN6CgmznZsAEoVIhF27nm1CnJIlNT5Xbr1jK688or6sZFZKVMXo3Vu3dvpKSk4MKFC3j06BEePXqECxcuQKvVonfv3rkRI9ELiYoCWrUC7t8HatWS9iQFsj2maX3i44H33gNmzTKcK1OGiU6O0yU2gKywqlYNePNN4PBh2auEiQ5RrjG5ZsfR0REHDx5ErVq1jM6fOHECjRs3RkJCQo4GmBdYs2O9kpOlK/Lu3TItc+QIW5OkFxoKtG8vAw0ODsD164CPj9pRWZnoaGDmTGDZMtkWXtfMKSaGhcdELyhXOigDgK+vr36frPTS0tLgw9+SZEZ0tTm7d8v7y+bNTHTSO3hQlpOfOiW7lf/1FxOdHJWQIFXwfn6yvcP161KErMNEhyjPmJzszJgxAwMGDMDx48f1544fP44vvvgCM2fOzNHgiF7EtGnAb7/JFkIrVsjMAYmlS6V1S0SEvC7HjgGNG6sdlZVISZG9NF5+GRgxAoiMBCpXlmpvTvUTqcLkaSx3d3ckJCQgNTUVBf4rfNB9/mSDQUvpssxpLOuzerU0mwWkp07//urGY04mTDDs6t6+vfQa4jYZOSQ+XgrDrlyR26VLywverRu3hCfKBbm29HzOnDkvEhdRrjt2TBriAcDAgUx0nlSkiHwcMQL43/9k5ItySKFCsqNsdDQwZgzwySfsxEhkBthUEBzZsSZhYbKiNzxcVmBt2MA/qDNy6BDg7692FFbg+HFJan74QWpzAODePUl6OFxGlOtyrUCZyFzFxUkvnfBwoGpVqQVlogNcuCC9hSIjDeeY6Lygq1eBLl2kwnv7dtlATMfTk4kOkZlhskNWIS1NyiL+/Vf2Tdy0iYtdAGDvXqBBA2DLFuDLL9WOxgpERAADBgCVKgErV0oXxu7dgUmT1I6MiJ6ByQ5ZhZEjDbuYr18PlCqldkTq+/13oHlzaarYoIGsgqYX8O23ssJqwQJpEPjWW7Juf8kS/sARmTkmO2TxFi2Snm26z199Vd141KYo0tblww9lFXSnTsCuXbLnFb2A6GggNlYKkHftkuEy9jMgsghsmk8W7e+/gU8/lc/HjQO6dlU3HrWlpsrqs59+ktvDhwNTpnDFVbZs3w64uQH168vtoUNl+qpTJ76gRBbG5GQnPj4eU6dOxa5duxAREQGtbrfe/1y/fj3HgiN6lpAQoEMHGb14913jGtH86tEjYOtWKSWZPx/o10/tiCzQ6dPAsGHAjh1AnTqyx4iNjRQdd+midnRElA0mJzu9e/fGvn370L17d3h7e0PDraNJBTExsvLqwQOZVVi8mH9sA1KcvW0bcOmSNAwkE9y9K8vIFy2SuUA7O+C112SDtYIF1Y6OiF6AycnO1q1bsXnzZjRs2DA34iF6rrQ04P33gXPnAG9vKUh2clI7KvXcvCmDEW3ayO1KleSgLEpIkC3fp02TDsgA0LmzdFwsW1bd2IgoR5j8t7C7uzs8PDxyIxaiLBk1Sjb1LFhQEp38vLnn2bOy0qpjR2DPHrWjsVAbNkjBV3y8VLcfPCibqTHRIbIaJic7kyZNwrhx45CQkJAb8RA90++/AzNmyOeLFklPt/zqwAHZvPPOHaB8eTkoi9J3WOzcWbLFoCBJdNhxkcjqmLxdRK1atXDt2jUoioLSpUvDzs7O6P6TJ0/maIB5gdtFWIYjR4AmTYCkJGD0aFlenV9t2iSLghITZWRn40aAA65ZcPOmbAr2999S2MROx0QWLdc2Am3PqkdSwe3bUnCblAS0awdMnKh2ROr5/Xfgo4+kduntt6WRb36uWcqSuDhg6lRpyJSUJMvVdu5kFTdRPsGNQMGRHXP3+LEsijl+XPa8OngQcHZWOyp17N8vo1uANA385RdZNESZ0GqBZctkNOfOHTnXtKl0Q65ZU83IiCgH5NrIjs6JEydw4cIFAECVKlVQq1at7D4UUaYUBejVSxKdIkWkljS/JjoA0KgR0KOH9LqbPZvL7Z/p8WPgjTeAw4fldpkyMrLTvr2M7BBRvmFyshMREYH33nsPe/fuhZubGwAgKioKr7/+OoKCglCsWLGcjpHysenTZffyAgWA1asBPz+1I8p7iiKdke3sJLn59Vf5yPfr53B0BEqXBs6ckf45gwaxXw5RPmXy34UDBgxAbGwszp07h0ePHuHRo0c4e/YsYmJiMHDgwNyIkfKpLVtkmTkAzJsnsw/5TVoa0Lu39BVKS5NztrZMdDKUnCwjN6GhhnOzZwOXL8tOsUx0iPItk2t2XF1dsXPnTtR9Ys3v0aNH0bx5c0RFReVkfHmCNTvm59IloF496ZT86afAjz+qHVHeS0mRupygIBnJ2btXlppTBrZtA774QhKbLl3kRSMiq5drNTtarfap5eYAYGdn99Q+WUTZERUFtG0riU6jRjKqk98kJcl79vr1Mn21fDkTnQxdvw4MHizFXIDsl9GypboxEZHZMXka64033sAXX3yBO7qVDQBu376NwYMHo1mzZjkaHOU/uq0gLl8GfH2lTsfeXu2o8lZCgiyvX78ecHAA1q2TnneUTkKC7PxaubIkOgUKAEOGyA9Oz55qR0dEZsbkZGfBggWIiYlB6dKlUbZsWZQtWxZ+fn6IiYnB/PnzcyNGykfGjJFduwsWlDd5T0+1I8pbsbFAq1bA9u3SO2fzZrlNT5gzR5otJSUBzZoB//4r+1u5uqodGRGZoWz12VEUBTt37sTFixcBAJUqVUJAQECOB5dXWLNjHlasAN57Tz5ftgzo2lXdeNRw+DDw+usymrVlC8D9dtPRag1r7ePjgebNZTSnQwdWbBPlU1l9/2ZTQTDZMQf//itbEj1+DAwbJkvO86u//gLc3YE6ddSOxEwkJABTpsgWD7t3s7kQEenlaIHyvHnz8Mknn6BgwYKY95xqUS4/J1M9eCB93h4/lj/Wp0xRO6K89egRcP8+UKGC3H7zTXXjMSsbNgADB8qeVoAMd7VurW5MRGRxsjSy4+fnh+PHj6NIkSLwe0ZXN41Gg+vXr+dogHmBIzvqSU0FWrSQP9jLlAGOHctfG1o+eAAEBAD37snScl3Ck+/duCFJzsaNctvXV+p03nmHU1ZEpJejIzshISEZfk70ooYPl0SnUCEpSM5Pic79+1Jbe+aMFGKnpqodkRlISQFmzJAt7R8/llVWQ4dK5XqhQmpHR0QWyuTJ74kTJyIhIeGp848fP8bE/LwVNZnsjz9kP0YAWLwYqFZN3Xjy0v37sm3TmTOAt7eM6lSponZUZsDGBvjzT0l0mjaVYq4pU5joENELMblA2dbWFnfv3kXx4sWNzj98+BDFixdHmq6nvQXhNFbeO3UKaNAASEwEvvoKmDxZ7YjyTvoRHV2iU7682lGpKCJCdnd1dJTbx48DFy8C3bpxyoqInimr798mj+woigJNBr+A/v33X3jkpzkIyrYHD6T0IjEReOstaZeSXzx4wERHT6sFFi4EKlY0rkqvUwf44AMmOkSUY7K8XYS7uzs0Gg00Gg3Kly9vlPCkpaUhLi4On332Wa4ESdYjNVV66dy8CZQtCyxdKhtb5hcFCsgAhrc3sGdPPk50zp6VTc8OHpTbO3ZIR+T89MNARHkmy8nOnDlzoCgKPv74Y0yYMAGu6TqV2tvbo3Tp0vD398+VIMl6jBwJ7NplKEh2d1c7orzl5ibdke/fB8qVUzsaFTx+LMXH06dL5luoEDBpEjBgABMdIso1WU52evToAUCWoTdo0CDDzUCJniUoSDr6A0BgIFC1qqrh5JmoKGkP8/77ctvNTY5859gxGdbTtado2xZYsECWlRMR5SKTdz1v0qQJ0tLSsHr1aly4cAEAULlyZbRr1w4FCpj8cJRPnD4NfPyxfD5yJPDuu+rGk1diY6Uu6fBhaR7Yv7/aEamoaFEgPBwoUUKSnPbt1Y6IiPIJk7OTc+fOoW3btggPD0eF/zqgTZs2DcWKFcPGjRtRNb/8uU5Z9uiRFCQ/fiwNBL/5Ru2I8kZ8vGziefiwTNc1bqx2RHlMUeTJ66a3/fykSWCdOgBXPRJRHjJ5NVbv3r1RpUoV3Lp1CydPnsTJkycRFhaG6tWr45NPPsmNGMmCpaXJCuLr1+W9btmy/FGakZAAtGkD/POPbMT9119AjRpqR5WHrl+XvT8aNAD27TOcf+MNJjpElOdMTnaCg4MxZcoUuKerLHV3d8fkyZNx6tSpHA3uSVOnToVGo8GgQYP05xITE9GvXz8UKVIEhQsXRseOHXHv3r1cjYOybvx4YNs2WYG0Zk3+6JCclAR07CirrZydpSC5dm21o8ojqalSmFW1KrBzJ+DgAFy9qnZURJTPmZzslC9fPsNkIiIiAi+//HKOBJWRY8eO4aeffkL16tWNzg8ePBgbN27EqlWrsG/fPty5cwcdOnTItTgo69atMzQLXLgQqFlTzWjyhlYLdO0qCZ6TkxQm16+vdlR5RLd1/dChMmf5+uvSUKhXL7UjI6J8zuRkZ8qUKRg4cCBWr16NW7du4datW1i9ejUGDRqEadOmISYmRn/klLi4OHTr1g0LFy40GlGKjo7Gr7/+itmzZ+ONN95A7dq1sWjRIhw8eBCHDx/Ose9Pprt4EfjwQ/n8iy9kKis/sLEB6tWTAY3164FGjdSOKI9Mny61OMePy7zdL79Ij4F8ub6eiMyNyQXKrVu3BgB07txZ31hQt+NEmzZt9Lc1Gk2ObR3Rr18/vP322wgICMA36apbT5w4gZSUFAQEBOjPVaxYESVLlsShQ4fw6quvZvh4SUlJSEpK0t/OycSMZAXSO+/Ix9dek30d85ORI2V0p1QptSPJQz4+MoXVsSMwf750TSQiMhMmJzt79uzJjTgyFRQUhJMnT+LYsWNP3RceHg57e3u4PdG0xNPTE+Hh4Zk+5pQpUzBhwoScDpUgC3A++khGdnx8gJUrAWtvyaQowI8/yuiVrvbW6hOduDjgyhWgVi253a2bPOl8t+SMiCxBtvrs5JWwsDB88cUX+Ouvv1CwYMEce9xRo0ZhyJAh+tsxMTHwZWOzHDFjhmxabWcnHz091Y4o902aJIXYixfL6iurbze1axfQu7dsbnb+vKyr12iY6BCR2crWr+WoqCj8+uuv+qaCVapUwccff2y0hUROOHHiBCIiIvDKK6/oz6WlpWH//v1YsGABtm/fjuTkZERFRRmN7ty7dw9eXl6ZPq6DgwMcHBxyNFaS98BRo+TzefOATGYRrcq8eZLoANIh2aoTnZgYYNgw4Oef5XbJkrLJWX7b84OILI7JBcrHjx9H2bJl8e233+LRo0d49OgRZs+ejbJly+LkyZM5GlyzZs1w5swZBAcH6486deqgW7du+s/t7Oywa9cu/ddcunQJoaGh3Kcrj4WGyk4AWq1MY336qdoR5b7Fi6X4GgAmTAAGDlQ3nly1fbssJ9clOv36yWae+WGJHRFZPI2iqy7OosaNG+Pll1/GwoUL9dtDpKamonfv3rh+/Tr279+fK4HqNG3aFDVr1sScOXMAAJ9//jm2bNmCwMBAuLi4YMCAAQCAg7rdlLMgJiYGrq6uiI6OhgsbnpksMVFmMI4fl34yf/8tfXWs2bp1suVFWhoweLC0lvmvXt+6pKUBn3wC/Pab3C5bFvj1VyAPp7OJiDKT1fdvkwfdjx8/bpToAECBAgUwfPhw1KlTJ3vRvoBvv/0WNjY26NixI5KSktCiRQt8//33eR5HfjZggCQ6RYpInY61Jzq7dwNdukge8NFHVpzoANLuOjVVnuAXX8heH4UKqR0VEZFJTE52XFxcEBoaiooVKxqdDwsLg7Ozc44Flpm9e/ca3S5YsCC+++47fPfdd7n+velpv/wih40NsHx5PliFBEnqPDxkJ4Sff7bCRCc6WtpAFy8ut+fMkdGdhg1VDYuIKLtMrtnp0qULevXqhRUrViAsLAxhYWEICgpC79690bVr19yIkczUsWNSugHIH/xvvqluPHmlRg3gyBHZ58vqCpJ37JDanI8/ljX1gBQgM9EhIgtm8q/qmTNnQqPR4MMPP0RqaioAwM7ODp9//jmmTp2a4wGSebp/X/rHJScD7dtLIz1rduuWFGE3aCC3S5ZUN54cFxsrK61++kluFywIRETkj94BRGT1TC5Q1klISMC1a9cAAGXLloWTk1OOBpaXWKBsmtRUoGVLWWpevryM8Fjzy/bwoXSCvn4d2LDBCkew9u2T4qOQELk9YAAwZQprc4jI7OVagbKOk5MTqlWrlt0vJws2ZowkOoUKAWvXWneiEx8PtG4tvfNKlJDkzmo8fgyMHi01OYoiBVeLFskGnkREVsTkmh3K39asAaZNk89/+w2oXFndeHJTSgrQuTNw+LCUrWzfbmUF2GlpslupokhH5NOnmegQkVWytvJKykUXLwI9esjnX34piYC1UhRZgLRliyyl37QJqFJF7ahyQEqKLCe3sQEKFwb++AN49Ah4+221IyMiyjUc2aEs0e1kHhcHNG0KWHst+ujRQGCg5AUrVhgKky3ahQvyRNK3afD3Z6JDRFaPyQ49V/qdzEuUAIKCrHDJdTppacDly/L5Tz8BbdqoG88L02qB+fOBV16R7o9Tp0rbayKifMKK37Iop8ycadjJfPVq61+NrBvN+esvWXVm0W7flp45O3bI7ebNpdiqYEF14yIiykMc2aFn2r3b0ENn7lzr3sn8+nVDHz1bWytIdFatAqpVk0SnYEFgwQJg2zYZniMiykeY7FCmwsJkDyitVgqTP/tM7Yhyz/nzsolpjx7SKNHiXb8OdO0KREYCdeoAp05Ju2ur29uCiOj5OI1FGUpMlA7JDx4AtWoBP/xgve+Td+4Ab70FREUBV69KzY7FK1NG9vCIjwfGjZM5SCKifIrJDmVo4EDpjOzubt07mcfEAK1ayVYQ5csDGzda6HNNSQEmTQI6dZKpK8D69/AgIsoiTmPRU379FVi4UEZyli8H/PzUjih3pKQA774L/PuvbPC9bZvsaG5xrl6VjTonTQLef1+eGBER6THZISPHjxt2Mp80CWjRQt14couuaeBff8m2F5s3W2BSpyjSDKhmTRmGc3MDxo7llBUR0RM4jUV6ERFAhw5AUhLQti0wapTaEeWe06eBpUulkfDKlVLDa1EiI6VifOVKud2kCfD774Cvr7pxERGZISY7BEB2Mn/vPVmBVb48sGSJJALWqkYNmba6cUNqdixKSIgkN2Fh0t1x4kRg+HBZL09ERE9hskMApJZ1zx7ZLmntWsDVVe2IcoeiGFaVvfGGurFkW8mSMufm4AAsWwbUrat2REREZs2K/3anrFqxApg1Sz4PDLTenczPnZMdEy5cUDuSbAgLM2zxoGvxfPIkEx0ioixgspPPnTkjuwkAwIgR0lvHGoWHy36XwcHyPC3Kn38C1avLVJWOlxfg7KxeTEREFoTJTj4WGSk7mSckAAEBwOTJakeUOxISpOD65k2gXDlg0SK1I8qix4+lCPndd6Xj4dGj3MCTiCgbmOzkU2lp0pLl2jWgVCnpp2ON9a1aLfDhh7Iy28NDlphbRC+d8+eBevVk23VAhqP+/psbeBIRZQMLlPOpsWNlNZKjI7BuHVC0qNoR5Y5Ro2QWyN5enme5cmpH9ByKIl0dBw6UkZ3ixWVJefPmakdGRGSxOLKTD61aBUyZIp//+qv0pLNGy5YB06fL57/9BjRurG48WRIRAQwdKonOm29Ke2cmOkREL4QjO/nMmTNAz57y+ZdfysbY1qplS+C114BmzYBu3dSOJos8PSUzu3IFGDbMupsdERHlEY2iKIraQagtJiYGrq6uiI6OhouLi9rh5JpHj2Sl8vXrkgBs2yY96axZcrLsnmC2O7YrCvDddzK/Zq17cxAR5ZKsvn/zz8Z8IjUV6NJFEp3SpaVNizUmOg8eSImLjr29GSc6UVGy0mrAAOCDD4D799WOiIjIKlnh2x1lZNgwYOdOwMlJCnUtYkWSiZKSZG+vv/8Gbt+WrtBm6/hxoHNn2frBzg4YM8Z6q8SJiFTGZCcfCAwE5syRz5cskX2hrI2iAJ9+KomOi4v01TFLummrL7+UOTY/PxlmYydkIqJcw2THyh06JEkAAIwbZ70dkqdNAxYvll5BK1ea6ZYXKSlSKb1qldx+5x0pRnZzUzUsIiJrx5odK3b7tkzrJCfL++r48WpHlDvWrZN+OgAwd64Z1/na2clOq3Z2MtT2559MdIiI8gBXY8E6V2MlJABNmkhpSNWqMsJTuLDaUeW8f/8FGjYE4uOBfv2ABQvUjugJiiLFRLrOxwkJshNp7drqxkVEZAW4Gisf02qBHj0k0fHwANavt85EBwAOHpREJyDAUJdkNuLj5R+iQwf5RwGkQpyJDhFRnmLNjhUaPx5YvVpmS9auBcqUUTui3PP557K3l7+/mS2lv3hRlpWfOyeNAY8ckSCJiCjPcWTHyixdCnzzjXz+88/SQdjaKIrspqDTqhXg7q5ePE9ZuVJWV507B3h5Abt3M9EhIlIRkx0rcuAA8PHH8vnIkYZtIazN9OmSO4SGqh3JE5KTgUGDpHtjXBzQtClw6pQUTxERkWqY7FiJkBBZcaVbeTV5stoR5Y6NG2Xl1b//Atu3qx3NEz76SJaDAcCIEcBff8nIDhERqYrJjhV4+BB46y3ZbeCVV2S7BGvcP/LcOeD992Ua67PPgD591I7oCUOGyEae69cDU6eaWREREVH+xd/GFu7xY6BNG+DSJcDXF9iwAShUSO2oct7Dh9IVWTc7NG+e2hFBsq7Tpw0tqWvXliE2R0d14yIiIiNW+Pd//pGWJiMdhw5Jb7pt24ASJdSOKuelpACdOskmpn5+0oDYzk7loKKjpR11vXqyxl+HiQ4RkdlhsmOhFAUYOFC6Bzs4yIiOWW6RkAPGjQP27JFeQRs2mMF+mefOSZKzdq3cvnRJ3XiIiOiZmOxYqGnTgO+/BzQa4I8/gMaN1Y4o9/TtC9SpI8+zalWVg1m5EqhfH7h8WeYN//5b9rsiIiKzxZodC/T994a9oObMkd511szXFzh8WDb5VE1qqrzoM2fK7WbNgOXLgWLFVAyKiIiygiM7Fua332QPKEDeewcOVDee3BIWJouadFRNdAAZVtIlOsOHS4EUEx0iIovAZMeCLF0K9O4tnw8ebL29dBISgPbt5Vi4UO1o/vPhh0DXrlIdPW0al5UTEVkQ/sa2EKtWyfutosh+ULNmSb2OtVEU6Z9z8qQUIr/5porBrFkjDYwcHaVx0bJlKgZDRETZxZEdC7BmjSwx12plO4gFC6wz0QFkpmjZMhk4Wb0aKF1ahSCSk6UqumNH6V6oKCoEQUREOYUjO2buu++AAQPk/bZbN9nc0xq7IwOy/cPIkfL5nDkqbSl1965UfB88KBnlyy+rEAQREeUkJjtmSquVAuTp0+X2p5/KiI7qhbq55OpV4L335Hn36iUDK3nu8GGgQwdJeFxdpUjq7bdVCISIiHKSlY4RWLakJKB7d0Oi87//AT/8YN01sevXA1FRwKuvymhWnk/T/fqrDCXdvSvdGY8dY6JDRGQlrPjt0zLduiWJzt69ktz89pvctnZffgl4e8u+Vw4OefzNHz2SXcp1W8YvXgw4O+dxEERElFuY7JgJrVbqcYYPB2Jj5b32zz9VXo2UBxTFMIrz/vsqBeHhIZ2RDx4EvvrKeouiiIjyKf5WNwNXrgCvvy5LymNjAX9/4MgR6090Nm+WRsQRESp88xMngB07DLffeAMYM4aJDhGRFeJvdpUkJ8t7bd++QPXqwP79gJMTMHeubLdUqZLaEeauy5dlJGfPHnnOeWrZMqBRI9lKnZt4EhFZPU5j5aLz54HoaODxYzkSEuT2zp3A1q1ATIzh2jffBH76CfDzUy/evBIbK6UxMTFAw4bA+PF59I3T0mRte/r9rby88uibExGRWpjs5KK2bYFr1zK/39NTrunQAWjRwnobBaanKEDPnpII+vhI40B7+zz4xpGRst3D9u1y+6uvgIkTrXctPxER6THZyUUlS0rhsZOT7Djg6Cif16oFtGsH1KuX/0pEpkyRjtD29lKAnScDKxcvSlZ55Yr8IyxaBHTpkvn1cXFSSHT/vuGIjJShqOho+RgTI8N1iYlyJCXJ3KRWKxmd7rC1BezsZGmdnZ0sNXNyAgoVMnx0cQHc3Q2Hh4dsMlq8OFCkCBMyIqIXZNbJzpQpU7BmzRpcvHgRjo6OaNCgAaZNm4YKFSror0lMTMSXX36JoKAgJCUloUWLFvj+++/h6empYuRi9261IzAv27ZJDTAgvXRefTWPvvHPP0uiU7IksG4dUKIEcOiQDLtdvw6Ehso267duyZF+flFtGo1sEubtLXG/9JLhY+nScpQsKYkUERFlyKyTnX379qFfv36oW7cuUlNT8dVXX6F58+Y4f/48ChUqBAAYPHgwNm/ejFWrVsHV1RX9+/dHhw4dcODAAZWjpyeVLAmUKycrz3S7t+caRQFu3gTOnpVkoXJlGU5q0kSKhp7H0VFGV3SHh4d0VXZxkY/OzjIyU7Cg4bCzk6E6jcYwZJeWBqSkAKmp8jEpSYq34uMNR3S0dFSMjJSPDx/KaNLDh/I8dKNLp09nHKuNjSQ/ZcrIC1yuHFC+vHx8+eU8mickIjJfGkWxnF0O79+/j+LFi2Pfvn147bXXEB0djWLFimHZsmV49913AQAXL15EpUqVcOjQIbyaydBBUlISkpKS9LdjYmLg6+uL6OhouLi45Mlzya+ioyUvyNHGgYoiIzfHjsl26cePA0ePyvRSRjQaGR15+WWgbFmgVCnA11cSBt3IiTk0FUxNBR48AO7dk87Ot2/LyNPt2zIadfMmcONG5s8TkCmwcuUk2atUCahSRZb/lS/P0SAisngxMTFwdXV97vu3WY/sPCk6OhoA4OHhAQA4ceIEUlJSEBAQoL+mYsWKKFmy5DOTnSlTpmDChAm5HzBBUaQYuUoVue3qmgMPGh8v01CHDsl+VocPSxfkJ9nYyDeuUkXe7HVv+GXKSMZl7goUkKImLy+gRo2Mr1EUSYZCQmRa7soVWdev+xgbKzVLFy8af529vbwe1atLEdkrrwA1a8rIFRGRlbGYkR2tVou2bdsiKioK//zzDwBg2bJl+Oijj4xGaQCgXr16eP311zFt2rQMH4sjO3ln9mzZiWHOHKBfv2w+SHw8cOCA7KGxb5+M2qSmGl9TsKCMYFy/Lte7ugIrVsgyt/xKUWQU6MIFyTjPnZPj9Gkpws5IuXJA7dpA3bpSQV+rlhRRExGZIasb2enXrx/Onj2rT3RehIODAxzyfAOm/GfPHtn+Ii1NFillmaLIG/L27XL884+sdErP11caA/r7S6XzhQvAJ59ITUyVKsCGDTKCk59pNIapufTtuLVamQI7fRr491/g1CmZ/gsNlRGhK1eAoCC51sYGqFoVqF9fXmt/f6BChfzRJ4GIrIZFJDv9+/fHpk2bsH//frz00kv6815eXkhOTkZUVBTc3Nz05+/duwcvNotTVViYrO5OS5ONTPv3f84XJCRIt8WNG4FNm4DwcOP7S5aUXUJ1R+nS8oar1QKjRwNTp8p1bdoAf/zB6ZhnsbGR7pV+ftIDQefBA0l8jh0zHLdvS1J0+jSwcKFc5+4uSU+jRnLUrWsZ04JElG+Z9TSWoigYMGAA1q5di71796JcuXJG9+sKlJcvX46OHTsCAC5duoSKFSs+s2bnSVkdBqOsSUwEXntN3itr1pT9NR0dM7jw0SNZCr5uHfDXX8aFtk5OktS0aCFH+fIZjyZcuyb1LPHx0h158uT817woN92+LdOGhw9LjdSxY08XRNvbS8LTuLH8mzVsCBQurEq4RJS/ZPX926yTnb59+2LZsmVYv369UW8dV1dXOP737vn5559jy5YtCAwMhIuLCwYMGAAAOHjwYJa/D5OdnPXJJzII4OEhC6OMtsB4+FCSm1WrgF27jGtvSpaU5n9t2sgS8axONa5bJzUoH3yQg8+CMpScLFNfBw/K9OLff0uBdHq2tlL307Sp9Blo1IjJDxHlCqtIdjSZ1AUsWrQIPXv2BGBoKrh8+XKjpoKmTGMx2ck5O3dKeYhGI00EmzeHTFFt2CDTS9u3Gyc41asDHTvKdEr16lmrBfnnH3lD9ffPtedBWaQoMrr299+ym+2+fbIyLL0CBaTY+Y035GjQIId7DxBRfmUVyU5eYbKTcxQF+PZbICVZixF19wC//y77QqRf/VOjhuw43qmTTE+ZYtEi4NNPpW7k+HEpVCbzEhoqSc+ePXLcuGF8v6OjzHMGBMhRvTqnHokoW5jsmIDJTg66eRMIDJSk5OZNw3k/P5lm6tZNVvOYKi1NlnbNni23O3WS7+PklBNRU24KCZGkZ9cu2UPlyeLz4sVlOLB5c/no7a1OnERkcZjsmIDJzotJfZyCKT0vYVDEV3Det0mGdwDpddO1qyzH8vfP/nLlmBh5nC1b5Pb48cC4cRwNsESKIr1+du6UY+9eKS5Pr1o1oGVLORo25JQXEWWKyY4JmOxkU1gY8PPPGP6tF2bE90NdHMVhvAqbZm8AH38MvPNOJsuwTHD9uhQsnz8vy5sXLwY6d86Z+El9ycmyymvHDjlOnDAky4A0NGzWTBKft96SlgNERP9hsmMCJjsmUBSZipg/H9i4Eau176ATVgMAVnZYjk4zX31i+dUL6tMH+OUXwMcHWL8eqFMn5x6bzM+DBzLis3WrFLM/udKrUiWgVStJfBo35ianRPkckx0TMNnJgoQEYOlSYN482UkcwAVURD3bE4hLc8KwIWmYPss2579vfDwwcCAwcaJs0En5h1Yry9y3bpXj4EHjVtzOzlLj8/bbkgCxkShRvsNkxwRMdp4hPFxGcX780bDZZqFCiOn6Kert+h8uhTjg9ddlBqJATvTjTkuTrQref59bEpCxyEhpPrlliyQ/ERHG99epA7RuLUetWqzpIsoHmOyYgMlOBi5cAGbNkqXjun2pSpcG+veH8nEvvNvbDWvWyLZLJ07IgpoXFhsrSc6mTTKSM3ZsDjwoWSWtVn7wNm+W4/hx4/u9vWW0p00bWd7OzUyJrBKTHRMw2UnnwAHZZ2rTJsM5f39g6FBp/Gdri7Aw2XvzwQPpJVevXg5835s35Y3pzBlZfbNokazAIsqK8HAZ7dm0SYYZ0/d1cnCQIuc2bWTUJ93+ekRk2ZjsmCDfJzuKIsWgU6ZIF1xAppDat5ckp0GDp74kPFy2TGrbNge+/8GDsnIrIkLqLtatk122ibIjKUl+jjdulOPJpoavvCKJT9u2Mt3F6VIii8VkxwT5NtnRaoE1a4D//U92uwYAOzugRw9g2LCnuhsrSi68LyxdKsvUk5Nl19ANG9gVmXKOokjbAl3ic+iQ8dL2EiUMic/rr3P3diILw2THBPku2UlLA1auBL75Rt4IAOlE/OmnwJAhGQ7zJybKat8+faSsJkfcvAmUKwekpMgo0h9/sLaCcldEhBQ4b9woo5npGxoWKgS0aCGJz9tvA0WLqhcnEWUJkx0T5JtkJzUVWLYMmDwZuHxZzrm6ytLuL74AihTJ9EvT72R+9apsTZUjfvsNuHJFYuLqGcpLiYmyjcXGjTKiePu24T4bG5m+bdtWjuxscUJEuY7JjgmsPtnRJTmTJkmmAkjWMngw0L8/4Ob2zC//9Vegd+8ndjLPrtu3ZdVVxYov8CBEOUxRZCp3/XpJfnTTujoVKhgSH39/wDYXekoRkcmY7JjAapOdtDRg+XJZxn3lipwrWhT48kugXz9pyvYcx44BjRpJSc033wCjR79APMePy4ouBwfgyBGgWLEXeDCiXBQaahjx2bNHplp1ihaVaa62bSXzL1xYvTiJ8jkmOyawumQnLQ1YsUKSnEuX5FyRIlJ03K9fln85378P1K4tW2C1aye1zNmeaVq9GvjwQ+DxY6BKFemNUqpUNh+MKA/FxEh9z/r18nMbFWW4T7esvW1bKXT28VEtTKL8iMmOCawm2dFqJan4+mtpCgjIdNXQoTJdlYWRHJ3UVNl7cdcuWZR19KiU95hMUaQeR9cg8K23pEOyJb/OlH+lpAD//COjPuvXy0a16dWpY1jdVaMGl7UT5TImOyaw+GRHqwXWrpUk5799q+DmJknOgAHZSizS0oAxY4AFC4DDh2UwxmSJiUCvXlIvBACDBgEzZ7LegayDosgfFRs2SOJz5IjxsnZfX0l82rSRZe0ODurFSmSlmOyYwGKTHa1WGvBNmACcPi3nXF1l+fgXX2RzKMbY3bvSeT9bhgwBvv1WNs367jtZ0kVkre7dk2muDRtkD6+EBMN9umXtbdrINhY5sr8KETHZMYHFJTtarfwlOWGC7AoNyOjNF1/ICqsXWBceFia/h3Pkj9BHj2TaasoU4I03cuABiSzE48fA7t2GZoZ37hju02ikQ7hu1KdqVU53EWUTkx0TWEyyk5oqzQD/9z/g3Dk55+ws00ODBkl9zguIiZF9rtzcpBg5W7WWZ8/KL2+dXGm7TGRBtFrg5ElD4vPksvaSJQ27tbOLM5FJmOyYwOyTnaQk6S48ZQpw7Zqcc3GRepwhQ144yQHk93HHjjIrlq2dzBVF6nFGjAC+/x747LMXjonIKt26JdNdGzfKCoDERMN9Tk6yuqt1a5nu4qalRM+U1ffvAnkYE5nq3j3gxx+BH36QzwFZQj54sCwhf04zQFNMnSqJjr098OefJiY6SUnA55/LTuWAYQsKInraSy/J1iyffip1Pbt3y27tmzZJ003dCBAgK7refluO+vVZ3E+UTRzZgZmN7CiKDKssWCANAZOT5byPjzQD/PTTHN8/ats2+SNSUYBffpEFVFl2/z7QoYMsx7WxAebMkWXunLoiMo2iAMHBMuqzefPTq7s8PKTIuVUr6QvBvbuIOI1lCrNIds6dk/4zK1ca9q0CgFdflcLjjh1lR/Icdv26tAaJjJTFUj/9ZMIXnz0rBZY3bsjKrxUr5JcxEb24+/flL5HNm6WpYfpmhhqNFNi99ZYcdepwbznKl5jsmCDPk52oKEluzpyRhGHvXkPBMSAFiu+8I0lO/fq5Gsobb0g3/Pr1gX37TFiF9eAB8PLLQHQ0ULasDMFzvyui3JGaKg2vtmyR5EfXakKnaFH5Q6NlS9nCgkvbKZ9gsmOCXEt26tWTjTc1GsOhKMDDh09fa2cnv6i6dJHuqyZ0O34R167JzFhgYDZqIadNk788V69+5o7pRJTDbt2S/3tbtwI7d8pSyvRq15bkp0ULGR22t1cnTqJcxmTHBLmW7FSoYDwlld5LLwHVqsky7Zo1ZR4+BwuOc0Viosx36boMKoq0Wi7AOnci1aSkAAcPylTXtm1PL20vXFiGcJs3l+Pll1lTR1aDyY4Jci3ZuX5dCowVxfh46SVVE5udOyVHMam85t49mVqLiwMOHMizkSciMlF4OLBjhyQ/O3bIlHN6pUsDb74pR7NmOdK6gkgtTHZMYBYFynlEV5AcHS1lNm+9lYUvCg6WqbWwMEnS/vpLHoSIzJtWK/9/t2+X4+BBGQnS0WhkyisgQI6GDdnUkCwKkx0T5JdkJz4eaNBAahvr1ZOC5Of+XvvzT+DDD6UfSPny0v+jfPk8iZeIclhcHLB/v/zBsmPH0z2xChaUhOeNN2TUp3ZtTlOTWWOyY4L8kOwoitQ+r1olCzVOnHhOQbJWC0ycKPtvATLXv2KF+dcVEVHW3bkjXZx37pQj/R5egHRqf+012cbi9delySGXuJMZYbJjgvyQ7HzzDTB2rCz62r0baNToOV8wdqx8ESBbUkybxr/wiKyZogCXLknys3u39KSIjDS+xt0daNIEaNpUjmrVmPyQqpjsmMDak53164H27eXzhQuB3r2z8EW3b8tw9vjxwEcf5WZ4RGSO0tKAf/81JD5//w3Exhpf4+4ONG4sCVCTJjLywz+KKA8x2TGBtSc7gwcbdnGYP/8ZF968CZQqZbidmMhiRSISqaky/71njxT8/fOP1ACl5+wshYGvvSZJUN26/B1CuYrJjgmsPdlRFGDNGllQleGOE4oCfPedZEXLlgGdOuV5jERkYVJTgZMnJfHRJT/R0cbX2NtLwtOokRz+/mxASjmKyY4JrDHZSUmRVaXPHVFOSpId1H/9VW6bvEEWERFk2uvMGZnu0iU/9+49fV3FijJF3qCBHOXLs+6Hso3JjgmsLdlRFODzz4GQkOcsoLpzRzYYPXxYftlMny7FyOyuSkQvSlFkP5p//jEcly49fZ27u2xp8eqrMvJTr55sLEyUBUx2TGBtyc6cOTIjpdHI1jkZdkr+5x/g3XflLy83N9lxnTuWE1FuevAAOHRImhseOAAcOya1gelpNDL6U7++4ahaNZM5eMrvmOyYwJqSnU2bpDZHUYCZM4Evv8zgomvXgEqVZK6rWjVg7VrZuZyIKC+lpMiKr8OHJQk6dEiGpJ9UsCBQq5aM+tStK8fLL3P6i5jsmMJakp3Tp2UqPC4O6NNHSm8ynZEaOlR2Tv71V6BQoTyNk4goUxERwNGjwJEjchw9+nThMyAND195RbauqV1bjrJlmQDlM0x2TGANyc69e/JHT2iodHrftu2JUd+QEMDBAfDxkdtpafJLgfU5RGTOtFrg6lWZ8jp6VD6eOvX09BcgS99r1ZLjlVeAmjVlFJtTYFaLyY4JrCHZCQiQxqfly8uIsLt7uju3bAE++ACoXFl6ZPA/PhFZstRU2dfrxAng+HE5Tp/OOAGyt5ean5o1pelhjRpA9epP/JIkS8VkxwTWkOycOSP7da5cCZQr99/JtDTZ32rSJCniqVdPinqKFVM1ViKiHJeaCly8KL1/TpyQ3d6Dg4GYmIyv9/WVpKdaNcNRoYIkR2QxmOyYwBqSHUDyGf2s1P37QPfuwPbtcvvzz4Fvv5WpLCKi/EBRgBs3ZNorOFhGf/79V85lxM5OhserVJGjalX5WLYst8EwU0x2TGCpyc60adKTq3HjJ+7Yvx/o2lX66Dg6SqVy9+6qxEhEZHaioyXxOXPG+MhsFMjOTkZ9KlWScoBKlWR5fPny8juWVMNkxwSWmOwsXCjNjh0cZOS2dOn/7tBqZVVCcLD8Z1y1Sv46ISKizCkKEBYGnDsnx9mzcly4ACQkZPw1Go388q1QQY7y5Q0fS5TgyrA8wGTHBJaW7KxYAbz/vuQ1Y8dKWY6RixeB2bPlKFxYlRiJiKyCVitJ0PnzhuPiRUmCIiMz/zpHR+kFVK6c4Xj5ZTm8vZkI5RAmOyawpGRn3TppfJyWlq6Xzo7t8h9v0CC1wyMiyh8URTpCX7ggyc/ly3JcugRcvy4F05lxdATKlJFaoDJljI/SpTk1ZgImOyawlGRnyxagfXtpOtq9O7Doh0TYjhkl+0PY2EgL9vr11Q6TiCh/S0mRIugrV4yPa9fkfFras7/eywvw85PER3eUKmU4mAzpZfX9m+XlFuLkSaBDB/k/1Lkz8NuX52Db4H0psgOAvn1lGSUREanLzs4wdfWklBTg5k1plHj9+tNHbCwQHi7HoUMZP36xYkDJksbHSy/JcnpfX0mWuHrMCF8NC1Gtmux5lZykxR81ZqFA/bFAUpL80C9aBLz9ttohEhHR89jZGWp3nqQowKNHMvoTEiLHzZtyW/cxLk5ai9y/L/2EMmJjI3VBJUoYjpdekg766Q8Xl3zTRZ/TWDDvaaz0vXNSUxSktWgFhz3b5MRbbwG//SZZPBERWTdFkaLosDBJfkJD5eOtW3Lu1i3g9u1n1wul5+Qk7x/e3obDywvw9JSPus+LFzfbZoucxrJwiiKLqU6fBgIDJeEpYKdBgc7tgJOHpE6nR498k5UTEeV7Gg3g4SFHjRoZX5OWJpsl3r5tOHRJ0J07hiM6WpbU66bPnsfNzZD46I5ixQwfixY1fCxa1Oy2JeLIDsxvZCctDfjyS2DuXLm9cVIwWo+pKTe0Whm+9PRULT4iIrJw8fFSF3T3rvFx754curqhiIisjxSl5+ICFCkiiU+RInJMniwF1jmIq7FMYE7JTmQk0Ls3sGaN3J6JLzGk9FpoLpwHChZUNTYiIspntFogKkoSoIgI+Xj/vnye/uODB4ZDq834sa5cybhW6QVwGssCrVkD9Ps8DeERtrBHEhajB96zXQ207ScV/Ex2iIgoL9nYGKbOKlV6/vVarfzV/vChHA8eGD56e+d+vJmwmmTnu+++w4wZMxAeHo4aNWpg/vz5qFevntphZdnIz6Mx7UdXALaogItYhI/gH1AYmPOvbERHRERk7mxsDNNWZsQq+lWvWLECQ4YMwfjx43Hy5EnUqFEDLVq0QEREhNqhZUpRgNgoQ2OpDnVC4YBEjMY3CK7dG/7rRwE7djDRISIiekFWUbNTv3591K1bFwsWLAAAaLVa+Pr6YsCAARg5cuRzvz43a3bCDt9GzJ04JEQm4XFUEqIjErFzh4L1515G/eLXseJWI/214QMmw6tTY9nGnKusiIiIninf1OwkJyfjxIkTGDVqlP6cjY0NAgICcCiT7pNJSUlISkrS346Jicm1+N5uGo8zSRUyvC/xji3SktNga28LAPCaPzrX4iAiIsqvLD7ZefDgAdLS0uD5xFJsT09PXLx4McOvmTJlCiZMmJAX4aGIYwKKJj+Ek20iHG2T4VQgGTVLPED7NmkI6Ften+gQERFR7rD4ZCc7Ro0ahSFDhuhvx8TEwNfXN1e+157ImhmczXikh4iIiHKexSc7RYsWha2tLe7du2d0/t69e/DKZBsFBwcHODg45EV4REREpDKLX41lb2+P2rVrY9euXfpzWq0Wu3btgr+/v4qRERERkTmw+JEdABgyZAh69OiBOnXqoF69epgzZw7i4+Px0UcfqR0aERERqcwqkp0uXbrg/v37GDduHMLDw1GzZk1s27btqaJlIiIiyn+sos/OizKnvbGIiIgoa7L6/m3xNTtEREREz8Jkh4iIiKwakx0iIiKyakx2iIiIyKox2SEiIiKrxmSHiIiIrBqTHSIiIrJqTHaIiIjIqjHZISIiIqtmFdtFvChdE+mYmBiVIyEiIqKs0r1vP28zCCY7AGJjYwEAvr6+KkdCREREpoqNjYWrq2um93NvLABarRZ37tyBs7MzNBpNth8nJiYGvr6+CAsL4x5buYyvdd7ha513+FrnHb7WeSc3X2tFURAbGwsfHx/Y2GRemcORHQA2NjZ46aWXcuzxXFxc+J8nj/C1zjt8rfMOX+u8w9c67+TWa/2sER0dFigTERGRVWOyQ0RERFaNyU4OcnBwwPjx4+Hg4KB2KFaPr3Xe4Wudd/ha5x2+1nnHHF5rFigTERGRVePIDhEREVk1JjtERERk1ZjsEBERkVVjskNERERWjcmOib777juULl0aBQsWRP369XH06NFnXr9q1SpUrFgRBQsWRLVq1bBly5Y8itTymfJaL1y4EI0bN4a7uzvc3d0REBDw3H8bMjD151onKCgIGo0G7du3z90ArYipr3VUVBT69esHb29vODg4oHz58vw9kkWmvtZz5sxBhQoV4OjoCF9fXwwePBiJiYl5FK3l2r9/P9q0aQMfHx9oNBqsW7fuuV+zd+9evPLKK3BwcMDLL7+MwMDA3A1SoSwLCgpS7O3tld9++005d+6c0qdPH8XNzU25d+9ehtcfOHBAsbW1VaZPn66cP39eGTNmjGJnZ6ecOXMmjyO3PKa+1u+//77y3XffKadOnVIuXLig9OzZU3F1dVVu3bqVx5FbHlNfa52QkBClRIkSSuPGjZV27drlTbAWztTXOikpSalTp47SqlUr5Z9//lFCQkKUvXv3KsHBwXkcueUx9bVeunSp4uDgoCxdulQJCQlRtm/frnh7eyuDBw/O48gtz5YtW5TRo0cra9asUQAoa9eufeb1169fV5ycnJQhQ4Yo58+fV+bPn6/Y2toq27Zty7UYmeyYoF69ekq/fv30t9PS0hQfHx9lypQpGV7fuXNn5e233zY6V79+feXTTz/N1Titgamv9ZNSU1MVZ2dnZfHixbkVotXIzmudmpqqNGjQQPnll1+UHj16MNnJIlNf6x9++EEpU6aMkpycnFchWg1TX+t+/fopb7zxhtG5IUOGKA0bNszVOK1NVpKd4cOHK1WqVDE616VLF6VFixa5FhensbIoOTkZJ06cQEBAgP6cjY0NAgICcOjQoQy/5tChQ0bXA0CLFi0yvZ5Edl7rJyUkJCAlJQUeHh65FaZVyO5rPXHiRBQvXhy9evXKizCtQnZe6w0bNsDf3x/9+vWDp6cnqlativ/9739IS0vLq7AtUnZe6wYNGuDEiRP6qa7r169jy5YtaNWqVZ7EnJ+o8d7IjUCz6MGDB0hLS4Onp6fReU9PT1y8eDHDrwkPD8/w+vDw8FyL0xpk57V+0ogRI+Dj4/PUfygylp3X+p9//sGvv/6K4ODgPIjQemTntb5+/Tp2796Nbt26YcuWLbh69Sr69u2LlJQUjB8/Pi/CtkjZea3ff/99PHjwAI0aNYKiKEhNTcVnn32Gr776Ki9Czlcye2+MiYnB48eP4ejomOPfkyM7ZHWmTp2KoKAgrF27FgULFlQ7HKsSGxuL7t27Y+HChShatKja4Vg9rVaL4sWL4+eff0bt2rXRpUsXjB49Gj/++KPaoVmdvXv34n//+x++//57nDx5EmvWrMHmzZsxadIktUOjHMCRnSwqWrQobG1tce/ePaPz9+7dg5eXV4Zf4+XlZdL1JLLzWuvMnDkTU6dOxc6dO1G9evXcDNMqmPpaX7t2DTdu3ECbNm3057RaLQCgQIECuHTpEsqWLZu7QVuo7Pxce3t7w87ODra2tvpzlSpVQnh4OJKTk2Fvb5+rMVuq7LzWY8eORffu3dG7d28AQLVq1RAfH49PPvkEo0ePho0NxwZySmbvjS4uLrkyqgNwZCfL7O3tUbt2bezatUt/TqvVYteuXfD398/wa/z9/Y2uB4C//vor0+tJZOe1BoDp06dj0qRJ2LZtG+rUqZMXoVo8U1/rihUr4syZMwgODtYfbdu2xeuvv47g4GD4+vrmZfgWJTs/1w0bNsTVq1f1CSUAXL58Gd7e3kx0niE7r3VCQsJTCY0uyVS4hWSOUuW9MddKn61QUFCQ4uDgoAQGBirnz59XPvnkE8XNzU0JDw9XFEVRunfvrowcOVJ//YEDB5QCBQooM2fOVC5cuKCMHz+eS8+zyNTXeurUqYq9vb2yevVq5e7du/ojNjZWradgMUx9rZ/E1VhZZ+prHRoaqjg7Oyv9+/dXLl26pGzatEkpXry48s0336j1FCyGqa/1+PHjFWdnZ2X58uXK9evXlR07dihly5ZVOnfurNZTsBixsbHKqVOnlFOnTikAlNmzZyunTp1Sbt68qSiKoowcOVLp3r27/nrd0vNhw4YpFy5cUL777jsuPTc38+fPV0qWLKnY29sr9erVUw4fPqy/r0mTJkqPHj2Mrl+5cqVSvnx5xd7eXqlSpYqyefPmPI7YcpnyWpcqVUoB8NQxfvz4vA/cApn6c50ekx3TmPpaHzx4UKlfv77i4OCglClTRpk8ebKSmpqax1FbJlNe65SUFOXrr79WypYtqxQsWFDx9fVV+vbtq0RGRuZ94BZmz549Gf7+1b2+PXr0UJo0afLU19SsWVOxt7dXypQpoyxatChXY9QoCsfniIiIyHqxZoeIiIisGpMdIiIismpMdoiIiMiqMdkhIiIiq8Zkh4iIiKwakx0iIiKyakx2iIiIyKox2SEiIiKrxmSHiCxGz5490b59e7XDICILww7KRGQxoqOjoSgK3Nzc1A6FiCwIkx0iIiKyapzGIiKzs3r1alSrVg2Ojo4oUqQIAgICEB8f/9Q0VmxsLLp164ZChQrB29sb3377LZo2bYpBgwbpryldujS++eYbfPjhhyhcuDBKlSqFDRs24P79+2jXrh0KFy6M6tWr4/jx4/qvefjwIbp27YoSJUrAyckJ1apVw/Lly/PwFSCinMRkh4jMyt27d9G1a1d8/PHHuHDhAvbu3YsOHTogo0HoIUOG4MCBA9iwYQP++usv/P333zh58uRT13377bdo2LAhTp06hbfffhvdu3fHhx9+iA8++AAnT55E2bJl8eGHH+q/R2JiImrXro3Nmzfj7Nmz+OSTT9C9e3ccPXo0158/EeU8TmMRkVk5efIkateujRs3bqBUqVJG9/Xs2RNRUVFYt24dYmNjUaRIESxbtgzvvvsuAKnp8fHxQZ8+fTBnzhwAMrLTuHFj/P777wCA8PBweHt7Y+zYsZg4cSIA4PDhw/D398fdu3fh5eWVYVytW7dGxYoVMXPmzFx65kSUWziyQ0RmpUaNGmjWrBmqVauGTp06YeHChYiMjHzquuvXryMlJQX16tXTn3N1dUWFChWeurZ69er6zz09PQEA1apVe+pcREQEACAtLQ2TJk1CtWrV4OHhgcKFC2P79u0IDQ3NmSdJRHmKyQ4RmRVbW1v89ddf2Lp1KypXroz58+ejQoUKCAkJyfZj2tnZ6T/XaDSZntNqtQCAGTNmYO7cuRgxYgT27NmD4OBgtGjRAsnJydmOgYjUw2SHiMyORqNBw4YNMWHCBJw6dQr29vZYu3at0TVlypSBnZ0djh07pj8XHR2Ny5cvv/D3P3DgANq1a4cPPvgANWrUQJkyZXLkcYlIHQXUDoCIKL0jR45g165daN68OYoXL44jR47g/v37qFSpEk6fPq2/ztnZGT169MCwYcPg4eGB4sWLY/z48bCxsdGP1GRXuXLlsHr1ahw8eBDu7u6YPXs27t27h8qVK7/o0yMiFXBkh4jMiouLC/bv349WrVqhfPnyGDNmDGbNmoW33nrrqWtnz54Nf39/tG7dGgEBAWjYsCEqVaqEggULvlAMY8aMwSuvvIIWLVqgadOm8PLyYudmIgvG1VhEZDXi4+NRokQJzJo1C7169VI7HCIyE5zGIiKLderUKVy8eBH16tVDdHS0fil5u3btVI6MiMwJkx0ismgzZ87EpUuXYG9vj9q1a+Pvv/9G0aJF1Q6LiMwIp7GIiIjIqrFAmYiIiKwakx0iIiKyakx2iIiIyKox2SEiIiKrxmSHiIiIrBqTHSIiIrJqTHaIiIjIqjHZISIiIqv2f/KS13U3yCEmAAAAAElFTkSuQmCC" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 47 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:43:07.827513Z", + "start_time": "2025-03-02T12:43:07.185505Z" + } + }, + "cell_type": "code", + "source": [ + "sigma = 0.2\n", + "rates = np.linspace(0, 0.05, 100)\n", + "asian_call = []\n", + "european_call = []\n", + "asian_put = []\n", + "european_put = []\n", + "for r in rates:\n", + " asian_call.append(geometric_mkhize(r=r)[0])\n", + " european_call.append(european_option(r=r)[0])\n", + " asian_put.append(geometric_mkhize(r=r)[1])\n", + " european_put.append(european_option(r=r)[1])\n", + "\n", + "plt.plot(rates, asian_call, label='asian call', color='red')\n", + "plt.plot(rates, asian_put, label='asian put', color='red', linestyle='--')\n", + "plt.plot(rates, european_call, label='european call', color='blue')\n", + "plt.plot(rates, european_put, label='european put', color='blue', linestyle='--')\n", + "plt.legend()\n", + "plt.xlabel('risk free rate')\n", + "plt.ylabel('option price')\n", + "plt.show()" + ], + "id": "c787d4bb7b36beed", + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "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" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 48 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:43:21.392975Z", + "start_time": "2025-03-02T12:43:20.691255Z" + } + }, + "cell_type": "code", + "source": [ + "sigma = 0.2\n", + "rate = 0.008\n", + "s_ts = np.linspace(0, 200, 100)\n", + "asian_call = []\n", + "european_call = []\n", + "asian_put = []\n", + "european_put = []\n", + "asian_call2 = []\n", + "european_call2 = []\n", + "for s_t in s_ts:\n", + " asian_call.append(geometric_mkhize(s_t=s_t)[0])\n", + " european_call.append(european_option(s_t=s_t)[0])\n", + " asian_put.append(geometric_mkhize(s_t=s_t)[1])\n", + " european_put.append(european_option(s_t=s_t)[1])\n", + " asian_call2.append(geometric_mkhize_general(s_t=s_t, K=150)[0])\n", + " european_call2.append(european_option(s_t=s_t, K=150)[0])\n", + "\n", + "\n", + "plt.plot(s_ts, asian_call, label='asian call', color='red')\n", + "# plt.plot(s_ts, asian_put, label='asian put', color='red', linestyle='--')\n", + "plt.plot(s_ts, european_call, label='european call', color='blue')\n", + "# plt.plot(s_ts, european_put, label='european put', color='blue', linestyle='--')\n", + "plt.plot(s_ts, asian_call2, label='asian call K=150', color='green')\n", + "plt.plot(s_ts, european_call2, label='european call K=150', color='black')\n", + "plt.legend()\n", + "plt.xlabel('stock price')\n", + "plt.ylabel('option price')\n", + "plt.show()" + ], + "id": "50947cd51ecdfbc0", + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\Pawel\\AppData\\Local\\Temp\\ipykernel_11504\\4118472630.py:2: RuntimeWarning: divide by zero encountered in log\n", + " d_1 = (np.log(s_t/K) + 0.5*(r - (sigma**2)/6)*(T-T_0))/(sigma*np.sqrt(T/3))\n", + "C:\\Users\\Pawel\\AppData\\Local\\Temp\\ipykernel_11504\\2838495742.py:3: RuntimeWarning: divide by zero encountered in log\n", + " d1 = (T* np.log(s_wave_t/K) + 0.5 * (r - 0.5 * sigma**2) * (T-t)**2 + (sigma**2 * (T-t)**3)/(3*T))/(sigma * np.sqrt(((T-t)**3)/3))\n", + "C:\\Users\\Pawel\\AppData\\Local\\Temp\\ipykernel_11504\\2838495742.py:4: RuntimeWarning: divide by zero encountered in log\n", + " d2 = (T * np.log(s_wave_t/K) + 0.5 * (r - 0.5 * sigma**2) * (T-t)**2)/(sigma * np.sqrt(((T-t)**3)/3))\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "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hBAvFhysVKVKSoFSmTMrdfSo0RG9mpCQEPXuu+8qQGXIkEH5+fkZHdIL37//SUZ20qArV64QERFBrX81VomJiaFs2bJJulbevHnJmjWr+fjChQvkzp07wchEsWLFcHNz48KFC1T461eWPHnykDNnTvNzKleujMlk4tKlSzg7O3P16lU6dOhAp06dzM+Ji4vD1dXVfLx06VKmTp3K1atXCQsLIy4uDhcXlwTx5cuXD2dnZ/Oxh4fHC9ecnDx5kubNmz/38cuXLzN06FAOHTrEw4cPMZlMgJ66K1GixHM/77/Url2brVu3MmbMGCZNmvTU4//8WiWHwoULU7hwYfNxlSpVuHr1KpMmTeKXX35J1nsJIZ4WHKybeB45Au7uept5Ev/7tSj379+nbt26nDhxAhcXF9atW8e7qWi/vCQ7SeTk5ERYWJhh906MJ/GtX7/+qTfRJ9sBra2tUUoleOyf62GeyJgx48uEmqj4Zs+eTaVKlRI89qRR3IEDB2jdujXDhw+nTp06uLq64uvry/fff5/g+XZ2dgmOrayszAnKszg6Or4wtoYNG5I3b15mz56Np6cnJpOJEiVKvPLi7Jo1a9KjRw8aN26MyWRiypQpCR5PqWmsf6pYsSJ79+4F4I033sDGxibBWiuAe/fuWUS1UyFSs8BAnegcOwZZsuht5qVLGx3Vy/P396dWrVr88ccfZM2alU2bNvH2228bHVaSSLKTRFZWVimSACSnYsWK4eDggL+//3PX52TNmpXHjx8THh5ufj1Pase8SNGiRbl58yY3b940j+6cP3+e4OBgihUrZn6ev78/d+7cwdPTE4CDBw9ibW1N4cKFyZ49O56enly7do3WrVs/8z779+8nb968fPXVV+ZzN27cSNTrf5FSpUqxbds2hg8f/tRjjx494tKlS8yePZv//VX44klykBxq167NunXraNSoEUoppk6dan5szpw5REZGPvdz/53UvYyTJ0/i4eEBgL29PeXKlWPbtm3mresmk4lt27bRvXv3V76XEOnVo0e6W/mJE/DGGzrRKVXK6Khe3sWLF6lVqxa3bt0iT548bNmyhUKFChkdVpJJspMGOTs7079/f/r06YPJZKJatWqEhISwb98+XFxcaNOmDZUqVcLJyYkvv/ySnj17cujQIebPn/+f1/by8qJkyZK0bt2ayZMnExcXR9euXale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" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 49 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:43:22.997214Z", + "start_time": "2025-03-02T12:43:22.980932Z" + } + }, + "cell_type": "code", + "source": [ + "# get difference between asian and european option at s=100\n", + "asian_call = geometric_mkhize()[0]\n", + "european_call = european_option()[0]\n", + "print(asian_call - european_call)" + ], + "id": "336e64f6c14c1500", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-29.052899716661855\n" + ] + } + ], + "execution_count": 50 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:43:23.982109Z", + "start_time": "2025-03-02T12:43:23.965423Z" + } + }, + "cell_type": "code", + "source": [ + "# get difference between asian and european option at s=150 and k=150\n", + "asian_call = geometric_mkhize(K=150)[0]\n", + "european_call = european_option(K=150)[0]" + ], + "id": "f669df2ce648a8b7", + "outputs": [], + "execution_count": 51 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:43:25.433079Z", + "start_time": "2025-03-02T12:43:25.408893Z" + } + }, + "cell_type": "code", + "source": "print(asian_call - european_call)", + "id": "c7d6ae1bca8e2ec3", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "-27.708175937889294\n" + ] + } + ], + "execution_count": 52 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:43:26.001453Z", + "start_time": "2025-03-02T12:43:25.983429Z" + } + }, + "cell_type": "code", + "source": "from PyMPDATA_examples.utils.financial_formulae.asian_option import geometric_asian_average_price_c", + "id": "7d10fa61a8a7f567", + "outputs": [], + "execution_count": 53 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T12:43:27.433903Z", + "start_time": "2025-03-02T12:43:27.083052Z" + } + }, + "cell_type": "code", + "source": [ + "St_s = np.linspace(80, 120, 100)\n", + "C_kemna = []\n", + "C_geometric = []\n", + "C_mcdonald = []\n", + "\n", + "for St in St_s:\n", + " C_kemna.append(kemna_vorst(s_t=St, K=100, r=0.008, sigma=0.2, T=30))\n", + " C_geometric.append(geometric_mkhize(s_t=St, K=100, r=0.008, sigma=0.2, T=30)[0])\n", + " C_mcdonald.append(geometric_asian_average_price_c(S=St, K=100, r=0.008, sgma=0.2, T=30, dividend_yield=0))\n", + " \n", + "plt.plot(St_s, C_kemna, label='kemna vorst', color='red')\n", + "plt.plot(St_s, C_geometric, label='geometric', color='blue')\n", + "plt.plot(St_s, C_mcdonald, label='mcdonald', color='green')\n", + "plt.legend()\n", + "plt.xlabel('stock price')\n", + "plt.ylabel('option price')\n", + "plt.show()\n", + "# r = 0.008\n", + "# sigma = 0.2\n", + "# s_t = 100\n", + "# T = 30\n", + "# K = 100\n", + "# T_0 = 0\n", + "# t = 0" + ], + "id": "37e689daff4353bc", + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "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" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 54 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T13:03:07.201660Z", + "start_time": "2025-03-02T13:03:07.183673Z" + } + }, + "cell_type": "code", + "source": [ + "s = [1.9, 2, 2.1]\n", + "for s_t in s:\n", + " print(geometric_mkhize(s_t=s_t, K=2, r=0.05, sigma=0.5, T=1)[0])" + ], + "id": "e6348028e1a935bf", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "0.17020801789553563\n", + "0.2205333942809955\n", + "0.27743350494092955\n" + ] + } + ], + "execution_count": 55 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-02T13:04:13.637232Z", + "start_time": "2025-03-02T13:04:13.627847Z" + } + }, + "cell_type": "code", + "source": [ + "s = [95, 100, 105]\n", + "for s_t in s:\n", + " print(geometric_mkhize(s_t=s_t, K=100, r=0.1, sigma=0.4, T=1)[0])" + ], + "id": "c6e1dddd4b01178c", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "7.562863900456641\n", + "10.212987422434402\n", + "13.255170582207228\n" + ] + } + ], + "execution_count": 56 + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": "", + "id": "a4e37a09b2086dd1" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/asian_option.py b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/asian_option.py new file mode 100644 index 00000000..c4ada1ef --- /dev/null +++ b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/asian_option.py @@ -0,0 +1,446 @@ +# import os +# os.environ["NUMBA_DISABLE_JIT"] = "1" + +from functools import cached_property, lru_cache +from types import SimpleNamespace + +import numba +import numpy as np +import PyMPDATA_examples.utils.financial_formulae.asian_option as asian_analytic +from ipywidgets import IntProgress +from matplotlib import colors, pyplot + +# from PyMPDATA_examples.utils.quick_look import quick_look +from monte_carlo import ( + BSModel, + FixedStrikeArithmeticAsianOption, + FixedStrikeGeometricAsianOption, +) +from open_atmos_jupyter_utils import show_anim, show_plot +from PyMPDATA_examples.utils.discretisation import discretised_analytical_solution +from PyMPDATA_examples.utils.financial_formulae import ( + Bjerksund_and_Stensland_1993, + Black_Scholes_1973, +) +from pystrict import strict +from tqdm import tqdm + +from PyMPDATA import Options, ScalarField, Solver, Stepper, VectorField +from PyMPDATA.boundary_conditions import Constant, Extrapolated +from PyMPDATA.impl.enumerations import ( + ARG_FOCUS, + INNER, + META_AND_DATA_DATA, + META_AND_DATA_META, + OUTER, + SIGN_RIGHT, +) +from PyMPDATA.impl.traversals_common import make_fill_halos_loop + +OPTIONS = { + "n_iters": 3, + "infinite_gauge": False, + "nonoscillatory": True, + "divergent_flow": False, + "third_order_terms": False, + "non_zero_mu_coeff": True, +} + + +class Settings: + params = SimpleNamespace( + T=1, + sgma=0.1, + r=0.1, + K=100, + ) + + S_min = 50 + S_max = 200 + + def __init__(self, T, sgma, r, K, S_min, S_max): + self.params.T = T + self.params.sgma = sgma + self.params.r = r + self.params.K = K + self.S_min = S_min + self.S_max = S_max + + def payoff(self, A: np.ndarray, da: np.float32 = 0, variant="call"): + def call(x): + return np.maximum(0, x - self.params.K) + + def put(x): + return np.maximum(0, self.params.K - x) + + if variant == "call": + payoff_func = call + else: + payoff_func = put + + self.rh = np.linspace(A[0] - da / 2, A[-1] + da / 2, len(A) + 1) + output = discretised_analytical_solution(self.rh, payoff_func) + return output + + +_t = np.nan + + +@lru_cache() +# pylint: disable=too-many-arguments +def _make_scalar_custom( + dim, eps, ats, set_value, halo, dtype, jit_flags, data, inner_or_outer +): + @numba.njit(**jit_flags) + def impl(focus_psi, span, sign): + focus = focus_psi[0] + i = min(max(0, focus[inner_or_outer] - halo), span - 1) + if sign == SIGN_RIGHT: + # TODO: reuse the code from Extrapolated (here copy & paste!) + edg = span + halo - 1 - focus_psi[ARG_FOCUS][dim] + den = ats(*focus_psi, edg - 1) - ats(*focus_psi, edg - 2) + nom = ats(*focus_psi, edg) - ats(*focus_psi, edg - 1) + cnst = nom / den if abs(den) > eps else 0 + return max( + ats(*focus_psi, -1) + + (ats(*focus_psi, -1) - ats(*focus_psi, -2)) * cnst, + 0, + ) + return data[i] + + if dtype == complex: + + @numba.njit(**jit_flags) + def fill_halos_scalar(psi, span, sign): + return complex( + impl( + (psi[META_AND_DATA_META], psi[META_AND_DATA_DATA].real), span, sign + ), + impl( + (psi[META_AND_DATA_META], psi[META_AND_DATA_DATA].imag), span, sign + ), + ) + + else: + + @numba.njit(**jit_flags) + def fill_halos_scalar(psi, span, sign): + return impl(psi, span, sign) + + return make_fill_halos_loop(jit_flags, set_value, fill_halos_scalar) + + +class KemnaVorstBoundaryCondition(Extrapolated): + """eq. (12) in [Kemna & Vorst (1990)](TODO) but without discounting + which is embedded in the advectee definition (and applied to the initial condition) + """ + + def __init__(self, *, data_left, dim): + super().__init__(dim=dim) + self.data = tuple(data_left) + self.inner_or_outer = (INNER, OUTER)[dim] + + def make_scalar(self, indexers, halo, dtype, jit_flags, dimension_index): + return _make_scalar_custom( + self.dim, + self.eps, + indexers.ats[dimension_index], + indexers.set, + halo, + dtype, + jit_flags, + self.data, + self.inner_or_outer, + ) + + +class Simulation: + def __init__(self, settings, *, nx, ny, nt, variant="call"): + self.nx = nx + self.nt = nt + self.settings = settings + + self.ny = ny + self.dt = settings.params.T / self.nt + log_s_min = np.log(settings.S_min) + log_s_max = np.log(settings.S_max) + self.S = np.exp(np.linspace(log_s_min, log_s_max, self.nx)) + self.A, self.dy = np.linspace( + 0, settings.S_max, self.ny, retstep=True, endpoint=True + ) + self.dx = (log_s_max - log_s_min) / self.nx + # self.dy = + + self.settings = settings + self.step_number = 0 + + sigma_squared = pow(settings.params.sgma, 2) + courant_number_x = ( + -(0.5 * sigma_squared - settings.params.r) * (-self.dt) / self.dx + ) + + self.l2 = self.dx * self.dx / sigma_squared / self.dt + + self.mu_coeff = (0.5 / self.l2, 0) + + print(f"{self.l2=}") + + assert ( + self.l2 > 2 + ), f"Lambda squared should be more than 2 for stability {self.l2}" + + # print(f"dx: {self.dx}, dy: {self.dy}, dt: {self.dt}") + + self.payoff = settings.payoff(A=self.A, da=self.dy, variant=variant) + + options = Options(**OPTIONS) + stepper = Stepper(options=options, n_dims=2) + + x_dim_advector = np.full( + (self.nx + 1, self.ny), + courant_number_x, + dtype=options.dtype, + ) + print( + f"CFL {np.max(np.abs(self.a_dim_advector)) + np.max(np.abs(x_dim_advector))}" + ) + assert ( + np.max(np.abs(self.a_dim_advector)) + np.max(np.abs(x_dim_advector)) < 1 + ), f"CFL condition not met {np.max(np.abs(self.a_dim_advector)) + np.max(np.abs(x_dim_advector))}" + + courant_x = np.max(np.abs(x_dim_advector)) + courant_y = np.max(np.abs(self.a_dim_advector)) + print(f"{courant_x=}, {courant_y=}") + + print(f"{x_dim_advector.shape=}, {self.a_dim_advector.shape=}") + + self.solver = Solver( + stepper=stepper, + advectee=ScalarField( + self.payoff_2d.astype(dtype=options.dtype) + * np.exp(-self.settings.params.r * self.settings.params.T), + halo=options.n_halo, + boundary_conditions=self.boundary_conditions, + ), + advector=VectorField( + (x_dim_advector, self.a_dim_advector), + halo=options.n_halo, + boundary_conditions=self.boundary_conditions, + ), + ) + self.rhs = np.zeros((self.nx, self.ny)) + + @property + def a_dim_advector(self): + raise NotImplementedError() + + def add_half_rhs(self): + raise NotImplementedError() + + def free_boundary(self, t): + raise NotImplementedError() + + def step(self): + global _t + _t = self.settings.params.T - (self.step_number + 0.5) * self.dt + + self.add_half_rhs() + self.free_boundary(t=_t) + + self.solver.advance(1, self.mu_coeff) + + self.add_half_rhs() + self.free_boundary(t=_t) + + self.step_number += 1 + + +class _Asian(Simulation): + @cached_property + def payoff_2d(self): + return np.repeat([self.payoff], self.nx, axis=0) + + def free_boundary(self, t): + pass + + @cached_property + def boundary_conditions(self): + return ( + # KemnaVorstBoundaryCondition( + # data_left=self.payoff_2d[0, :] + # * np.exp(-self.settings.params.r * self.settings.params.T), + # dim=OUTER, + # ), + Extrapolated(OUTER), + Extrapolated(INNER), + ) + + +class AsianArithmetic(_Asian): + @property + def a_dim_advector(self): + a_dim_advector = np.zeros((self.nx, self.ny + 1)) + # y_edg = np.log(self.S[0]) + np.arange(self.ny + 1) * self.dy + # A_edg = np.exp(y_edg - self.dy / 2) + for i in range(self.ny + 1): + a_dim_advector[:, i] = -self.dt / self.dy * self.S / self.settings.params.T + return a_dim_advector + + def add_half_rhs(self): + pass + # psi = self.solver.advectee.get() + # self.rhs[:] = -psi / self.settings.params.T # todo male t + # psi[:] = np.maximum(0, psi + -self.dt * self.rhs / 2) + + +class AsianGeometric(_Asian): + @property + def a_dim_advector(self): + a_dim_advector = np.zeros((self.nx, self.ny + 1)) + # y_edg = np.log(self.S[0]) + np.arange(self.ny + 1) * self.dy + # A_edg = np.exp(y_edg - self.dy / 2) + A_edg = np.arange(self.ny + 1) * self.dy + for i in range(self.ny + 1): + a_dim_advector[:, i] = ( + -self.dt + / self.dy + * np.log(self.S) + * (A_edg[i] - self.dy / 2) + / self.settings.params.T + ) + return a_dim_advector + + def add_half_rhs(self): + pass + # psi = self.solver.advectee.get() + # self.rhs[:] = psi / self.settings.params.T * np.log(self.S) + # psi[:] = np.maximum(0, psi + -self.dt * self.rhs / 2) + + +class European(Simulation): + @cached_property + def a_dim_advector(self): + return np.zeros((self.nx, self.ny + 1)) + + def add_half_rhs(self): + pass + + @cached_property + def payoff_2d(self): + return np.repeat(self.payoff.reshape(self.nx, 1), self.ny, axis=1) + + def free_boundary(self, t): + pass + + @cached_property + def boundary_conditions(self): + return ( + Extrapolated(OUTER), + Extrapolated(INNER), + ) + + +class American(European): + def free_boundary(self, t): + psi = self.solver.advectee.get() + psi[:] = np.maximum(psi, self.payoff_2d / np.exp(self.settings.params.r * t)) + + +def plot_solution( + settings, + frame_index, + ax, + history, + S_linspace, + arithmetic_by_mc, + option_type: str, + variant, + A_space, +): + params = { + k: v for k, v in settings.params.__dict__.items() if not k.startswith("K") + } + if variant == "call": + BS_price_func = Black_Scholes_1973.c_euro + Amer_price_func = Bjerksund_and_Stensland_1993.c_amer + geometric_price_func = asian_analytic.geometric_asian_average_price_c + else: + BS_price_func = Black_Scholes_1973.p_euro + Amer_price_func = Bjerksund_and_Stensland_1993.p_amer + geometric_price_func = asian_analytic.geometric_asian_average_price_p + + ax.plot( + S_linspace, + ( + BS_price_func( + S=S_linspace, K=settings.params.K, **params, b=settings.params.r + ) + ), + label="European analytic (Black-Scholes '73)", + linestyle="--", + alpha=0.5, + ) + # ax.plot( + # S_linspace, + # ( + # Amer_price_func( + # S=S_linspace, K=settings.params.K, **params, b=settings.params.r + # ) + # ), + # label="American analytic (Bjerksund & Stensland '93)", linestyle='--' + # ) + ax.plot( + S_linspace, + ( + geometric_price_func( + S=S_linspace, K=settings.params.K, **params, dividend_yield=0 + ) + ), + label="Asian analytic (geometric, Kemna & Vorst 1990)", + alpha=0.5, + linestyle="--", + ) + ax.plot( + S_linspace, + arithmetic_by_mc, + label="Asian arithmetic by Monte-Carlo", + linestyle=":", + ) + ax.plot( + S_linspace, + history[frame_index][:, 0], + label=f"MPDATA solution ({option_type})", + marker=".", + ) + ax.plot( + A_space, + history[0][0, :], + label=f"Terminal condition (discounted payoff)", + marker=".", + ) + ax.legend(loc="upper right") + ax.grid() + minmax = (np.amin(history[0]), np.amax(history[0])) + span = minmax[1] - minmax[0] + ax.set_ylim(minmax[0] - 0.05 * span, minmax[1] + 0.25 * span) + ax.set_title(f"instrument parameters: {settings.params.__dict__}") + # ax.set_xlabel("underlying S(t=0)=A(t=0) (and A(T) for terminal condition)") + ax.set_xlabel("average at t=T for payoff, spot at t=0 for other datasets") + ax.set_ylabel("value") + + +def plot_difference_arithmetic( + settings, frame_index, ax, history, S_linspace, arithmetic_by_mc, option_type: str +): + ax.plot( + S_linspace, + abs(arithmetic_by_mc - history[frame_index][:, 0]) / arithmetic_by_mc, + label="Difference in price of Asian arithmetic option MPDATA vs MC", + ) + ax.legend(loc="upper right") + ax.grid() + ax.set_title(f"instrument parameters: {settings.params.__dict__}") + ax.set_xlabel("underlying S(t=0)=A(t=0) (and A(T) for terminal condition)") + ax.set_ylabel("option price error") + ax.set_yscale("log") + ax.set_ylim(0, 100) diff --git a/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/fig_1.ipynb b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/fig_1.ipynb new file mode 100644 index 00000000..4721059b --- /dev/null +++ b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/fig_1.ipynb @@ -0,0 +1,1049 @@ +{ + "cells": [ + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "[![preview notebook](https://img.shields.io/static/v1?label=render%20on&logo=github&color=87ce3e&message=GitHub)](https://github.com/open-atmos/PyMPDATA/blob/main/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/fig_1.ipynb)\n", + "[![launch on mybinder.org](https://mybinder.org/badge_logo.svg)](https://mybinder.org/v2/gh/open-atmos/PyMPDATA.git/main?urlpath=lab/tree/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/fig_1.ipynb)\n", + "[![launch on Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/open-atmos/PyMPDATA/blob/main/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/fig_1.ipynb)" + ] + }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "Asian-option pricing using 2D advection-diffusion solver \n", + "MSc project by Paweł Magnuszewski (pmagnus@student.agh.edu.pl)\n", + "\n", + "TODO:\n", + "- zero-strike option test\n", + "- Monte-Carlo\n", + "- rhs: the maximum call should best not be needed\n", + "- case with nx != ny" + ] + }, + { + "cell_type": "code", + "execution_count": 1, + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-05T13:04:33.679605400Z", + "start_time": "2025-02-28T11:43:14.353684Z" + } + }, + "outputs": [], + "source": [ + "import sys\n", + "if 'google.colab' in sys.modules:\n", + " !pip --quiet install open-atmos-jupyter-utils\n", + " from open_atmos_jupyter_utils import pip_install_on_colab\n", + " pip_install_on_colab('PyMPDATA-examples')" + ] + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-23T12:15:56.873366Z", + "start_time": "2025-04-23T12:15:56.864363Z" + } + }, + "source": [ + "import os\n", + "os.environ[\"NUMBA_DISABLE_JIT\"] = \"1\"" + ], + "outputs": [], + "execution_count": 1 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-23T12:16:03.078651Z", + "start_time": "2025-04-23T12:15:56.878789Z" + } + }, + "source": [ + "from types import SimpleNamespace\n", + "from functools import lru_cache, cached_property\n", + "\n", + "import numpy as np\n", + "import numba\n", + "from matplotlib import pyplot, colors\n", + "from pystrict import strict\n", + "from ipywidgets import IntProgress\n", + "from tqdm import tqdm\n", + "\n", + "from open_atmos_jupyter_utils import show_plot, show_anim\n", + "from PyMPDATA.impl.traversals_common import make_fill_halos_loop\n", + "from PyMPDATA import Options, ScalarField, Solver, Stepper, VectorField\n", + "from PyMPDATA.boundary_conditions import Extrapolated, Constant\n", + "from PyMPDATA.impl.enumerations import SIGN_RIGHT, ARG_FOCUS, META_AND_DATA_META, META_AND_DATA_DATA, OUTER, INNER\n", + "import PyMPDATA_examples.utils.financial_formulae.asian_option as asian_analytic\n", + "from PyMPDATA_examples.utils.financial_formulae import Black_Scholes_1973, Bjerksund_and_Stensland_1993\n", + "from PyMPDATA_examples.utils.quick_look import quick_look\n", + "from monte_carlo import BSModel, FixedStrikeGeometricAsianOption, FixedStrikeArithmeticAsianOption\n", + "from PyMPDATA_examples.utils.discretisation import discretised_analytical_solution" + ], + "outputs": [], + "execution_count": 2 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T19:52:35.894856Z", + "start_time": "2025-03-19T19:52:35.893161Z" + } + }, + "source": [ + "OPTIONS = {\n", + " \"n_iters\": 3,\n", + " \"infinite_gauge\": False,\n", + " \"nonoscillatory\": True,\n", + " \"divergent_flow\": False,\n", + " \"third_order_terms\": False,\n", + " \"non_zero_mu_coeff\": True,\n", + "}" + ], + "outputs": [], + "execution_count": 4 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T19:52:41.538648Z", + "start_time": "2025-03-19T19:52:41.536118Z" + } + }, + "source": [ + "@strict\n", + "class Settings:\n", + " params = SimpleNamespace(\n", + " T=1,\n", + " sgma=0.1,\n", + " r=.1,\n", + " K1=80,\n", + " K2=100,\n", + " )\n", + "\n", + " S_min = 50\n", + " S_max = 200\n", + " \n", + " def payoff(self, A: np.ndarray, da: np.float32 = 0):\n", + " def call(x):\n", + " return np.maximum(0, x - self.params.K2)\n", + " rh = np.linspace(A[0] - da/2 , A[-1] + da/2, len(A) + 1)\n", + " output = discretised_analytical_solution(rh, call)\n", + " return output" + ], + "outputs": [], + "execution_count": 5 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T19:52:43.319418Z", + "start_time": "2025-03-19T19:52:43.315172Z" + } + }, + "source": [ + "_t = np.nan\n", + "\n", + "@lru_cache()\n", + "# pylint: disable=too-many-arguments\n", + "def _make_scalar_custom(dim, eps, ats, set_value, halo, dtype, jit_flags, data, inner_or_outer, S_max, dx, T):\n", + " @numba.njit(**jit_flags)\n", + " def impl(focus_psi, span, sign):\n", + " focus = focus_psi[0]\n", + " i = min(max(0, focus[inner_or_outer] - halo), span - 1)\n", + " if sign == SIGN_RIGHT:\n", + " edg = span + halo - 1 - focus_psi[ARG_FOCUS][dim]\n", + " den = ats(*focus_psi, edg - 1) - ats(*focus_psi, edg - 2)\n", + " nom = ats(*focus_psi, edg) - ats(*focus_psi, edg - 1)\n", + " cnst = nom / den if abs(den) > eps else 0\n", + " return max(\n", + " ats(*focus_psi, -1) + (ats(*focus_psi, -1) - ats(*focus_psi, -2)) * cnst, 0\n", + " )\n", + " return data[i]\n", + " \n", + " if dtype == complex:\n", + " @numba.njit(**jit_flags)\n", + " def fill_halos_scalar(psi, span, sign):\n", + " return complex(\n", + " impl(\n", + " (psi[META_AND_DATA_META], psi[META_AND_DATA_DATA].real), span, sign\n", + " ),\n", + " impl(\n", + " (psi[META_AND_DATA_META], psi[META_AND_DATA_DATA].imag), span, sign\n", + " ),\n", + " )\n", + " else:\n", + " @numba.njit(**jit_flags)\n", + " def fill_halos_scalar(psi, span, sign):\n", + " return impl(psi, span, sign)\n", + "\n", + " return make_fill_halos_loop(jit_flags, set_value, fill_halos_scalar)\n", + "\n", + "\n", + "class KemnaVorstBoundaryCondition(Extrapolated):\n", + " def __init__(self, *, data_left, T, dx, S_max, dim):\n", + " super().__init__(dim=dim)\n", + " self.data = tuple(data_left)\n", + " self.inner_or_outer = (INNER, OUTER)[dim]\n", + " self.S_max = S_max\n", + " self.dx = dx\n", + " self.T = T\n", + "\n", + " def make_scalar(self, indexers, halo, dtype, jit_flags, dimension_index):\n", + " return _make_scalar_custom(\n", + " self.dim,\n", + " self.eps,\n", + " indexers.ats[dimension_index],\n", + " indexers.set,\n", + " halo,\n", + " dtype,\n", + " jit_flags,\n", + " self.data,\n", + " self.inner_or_outer,\n", + " S_max=self.S_max,\n", + " dx=self.dx,\n", + " T=self.T,\n", + " )" + ], + "outputs": [], + "execution_count": 6 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T19:52:56.656912Z", + "start_time": "2025-03-19T19:52:56.648821Z" + } + }, + "source": [ + "class Simulation:\n", + " def __init__(self, settings, *, nx, ny, nt):\n", + " self.nx = nx\n", + " self.nt = nt\n", + " \n", + " self.ny = ny\n", + " self.dt = settings.params.T / self.nt\n", + " log_s_min = np.log(settings.S_min)\n", + " log_s_max = np.log(settings.S_max)\n", + " self.S = np.exp(np.linspace(log_s_min, log_s_max, self.nx))\n", + " self.A, self.dy = np.linspace(0, settings.S_max, self.ny, retstep=True, endpoint=True)\n", + " self.dx = (log_s_max - log_s_min) / self.nx\n", + " # self.dy =\n", + "\n", + " self.settings = settings\n", + " self.step_number = 0\n", + " \n", + " sigma_squared = pow(settings.params.sgma, 2)\n", + " courant_number_x = -(0.5 * sigma_squared - settings.params.r) * (-self.dt) / self.dx\n", + " \n", + " self.l2 = self.dx * self.dx / sigma_squared / self.dt\n", + " \n", + " self.mu_coeff = (0.5 / self.l2, 0)\n", + " \n", + " print(f\"{self.l2=}\")\n", + " \n", + " assert self.l2 > 2, f\"Lambda squared should be more than 2 for stability {self.l2}\"\n", + " \n", + " print(f\"dx: {self.dx}, dy: {self.dy}, dt: {self.dt}, l2: {self.l2}\")\n", + "\n", + " self.payoff = settings.payoff(A=self.A, da=self.dy)\n", + " \n", + " options = Options(**OPTIONS)\n", + " stepper = Stepper(options=options, n_dims=2)\n", + "\n", + " x_dim_advector = np.full(\n", + " (self.nx + 1, self.ny),\n", + " courant_number_x,\n", + " dtype=options.dtype,\n", + " )\n", + " print(f\"CFL {np.max(np.abs(self.a_dim_advector)) + np.max(np.abs(x_dim_advector))}\")\n", + " assert np.max(np.abs(self.a_dim_advector)) + np.max(np.abs(x_dim_advector)) < 1, f\"CFL condition not met {np.max(np.abs(self.a_dim_advector)) + np.max(np.abs(x_dim_advector))}\"\n", + " \n", + " courant_x = np.max(np.abs(x_dim_advector))\n", + " courant_y = np.max(np.abs(self.a_dim_advector))\n", + " print(f\"{courant_x=}, {courant_y=}\")\n", + " \n", + " print(f\"{x_dim_advector.shape=}, {self.a_dim_advector.shape=}\")\n", + "\n", + " self.solver = Solver(\n", + " stepper=stepper,\n", + " advectee=ScalarField(\n", + " self.payoff_2d.astype(dtype=options.dtype) * np.exp(-self.settings.params.r * self.settings.params.T),\n", + " halo=options.n_halo,\n", + " boundary_conditions=self.boundary_conditions,\n", + " ),\n", + " advector=VectorField(\n", + " (x_dim_advector, self.a_dim_advector),\n", + " halo=options.n_halo,\n", + " boundary_conditions=self.boundary_conditions,\n", + " ),\n", + " )\n", + " self.rhs = np.zeros((self.nx, self.ny))\n", + " \n", + " @property\n", + " def a_dim_advector(self):\n", + " raise NotImplementedError()\n", + "\n", + " def add_half_rhs(self):\n", + " raise NotImplementedError()\n", + "\n", + " def free_boundary(self, t):\n", + " raise NotImplementedError()\n", + "\n", + " def step(self):\n", + " global _t\n", + " _t = settings.params.T - (self.step_number + 0.5) * self.dt\n", + " \n", + " self.add_half_rhs()\n", + " self.free_boundary(t=_t)\n", + "\n", + " self.solver.advance(1, self.mu_coeff)\n", + "\n", + " self.add_half_rhs()\n", + " self.free_boundary(t=_t)\n", + "\n", + " self.step_number += 1\n", + "\n", + "class _Asian(Simulation):\n", + " @cached_property\n", + " def payoff_2d(self):\n", + " return np.repeat([self.payoff], self.nx, axis=0)\n", + " def free_boundary(self, t):\n", + " pass\n", + " @cached_property\n", + " def boundary_conditions(self):\n", + " return (\n", + " KemnaVorstBoundaryCondition(\n", + " data_left=self.payoff_2d[0,:] * np.exp(-self.settings.params.r * self.settings.params.T),\n", + " dim=OUTER,\n", + " dx=self.dx,\n", + " S_max=self.settings.S_max,\n", + " T=self.settings.params.T,\n", + " ),\n", + " Extrapolated(INNER),\n", + " )\n", + "\n", + "class AsianArithmetic(_Asian):\n", + " @property\n", + " def a_dim_advector(self):\n", + " a_dim_advector = np.zeros((self.nx, self.ny + 1))\n", + " # y_edg = np.log(self.S[0]) + np.arange(self.ny + 1) * self.dy\n", + " # A_edg = np.exp(y_edg - self.dy / 2)\n", + " for i in range(self.ny + 1):\n", + " a_dim_advector[:, i] = -self.dt / self.dy * self.S / self.settings.params.T\n", + " return a_dim_advector\n", + " def add_half_rhs(self):\n", + " pass\n", + " # psi = self.solver.advectee.get()\n", + " # self.rhs[:] = -psi / self.settings.params.T # todo male t\n", + " # psi[:] = np.maximum(0, psi + -self.dt * self.rhs / 2) \n", + " \n", + "class AsianGeometric(_Asian):\n", + " @property\n", + " def a_dim_advector(self):\n", + " a_dim_advector = np.zeros((self.nx, self.ny + 1))\n", + " # y_edg = np.log(self.S[0]) + np.arange(self.ny + 1) * self.dy\n", + " # A_edg = np.exp(y_edg - self.dy / 2)\n", + " A_edg = np.arange(self.ny + 1) * self.dy\n", + " for i in range(self.ny + 1):\n", + " a_dim_advector[:, i] = -self.dt / self.dy * np.log(self.S) * (A_edg[i] - self.dy/2) / self.settings.params.T \n", + " return a_dim_advector\n", + " def add_half_rhs(self):\n", + " pass\n", + " # psi = self.solver.advectee.get()\n", + " # self.rhs[:] = psi / self.settings.params.T * np.log(self.S)\n", + " # psi[:] = np.maximum(0, psi + -self.dt * self.rhs / 2) \n", + "\n", + "class European(Simulation):\n", + " @cached_property\n", + " def a_dim_advector(self):\n", + " return np.zeros((self.nx, self.ny + 1))\n", + " def add_half_rhs(self):\n", + " pass\n", + " @cached_property\n", + " def payoff_2d(self):\n", + " return np.repeat(self.payoff.reshape(self.nx, 1), self.ny, axis=1)\n", + " def free_boundary(self, t):\n", + " pass\n", + " @cached_property\n", + " def boundary_conditions(self):\n", + " return (\n", + " Extrapolated(OUTER),\n", + " Extrapolated(INNER),\n", + " )\n", + "class American(European):\n", + " def free_boundary(self, t):\n", + " psi = self.solver.advectee.get()\n", + " psi[:] = np.maximum(psi, self.payoff_2d / np.exp(settings.params.r * t)) " + ], + "outputs": [], + "execution_count": 7 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T20:13:25.802637Z", + "start_time": "2025-03-19T20:13:25.796140Z" + } + }, + "source": [ + "settings = Settings()\n", + "simulations = {\n", + " # 'European': European(settings, nx=30, nt=120),\n", + " # 'American': American(settings, nx=30, nt=120),\n", + " 'Asian arithmetic': AsianArithmetic(settings, nx=61, ny=130, nt=300),\n", + " # 'Asian geometric': AsianGeometric(settings, nx=31, ny=41, nt=300),\n", + "}" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(15.494319180377357)\n", + "dx: 0.022726137067539186, dy: 1.550387596899225, dt: 0.0033333333333333335, l2: 15.494319180377357\n", + "CFL 0.4439340296032524\n", + "courant_x=np.float64(0.013934029603252575), courant_y=np.float64(0.4299999999999998)\n", + "x_dim_advector.shape=(62, 130), self.a_dim_advector.shape=(61, 131)\n" + ] + } + ], + "execution_count": 63 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T20:13:26.115357Z", + "start_time": "2025-03-19T20:13:26.113366Z" + } + }, + "source": [ + "def plot_advectee(advectee_array, fig, ax, normargs, t=settings.params.T, colorbar_shrink=.91):\n", + " fig.colorbar(ax.imshow(\n", + " advectee_array,\n", + " extent=(np.log(settings.S_min), np.log(settings.S_max), np.log(settings.S_min), np.log(settings.S_max)),\n", + " origin=\"lower\",\n", + " norm=colors.Normalize(**normargs)\n", + " ), shrink=colorbar_shrink)" + ], + "outputs": [], + "execution_count": 64 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T20:13:27.003094Z", + "start_time": "2025-03-19T20:13:26.775977Z" + } + }, + "source": [ + "fig, axs = pyplot.subplot_mosaic([simulations.keys()], figsize=(6 * len(simulations), 6))\n", + "for key, simulation in simulations.items():\n", + " psi = simulation.solver.advectee.get()\n", + " plot_advectee(psi, fig, axs[key], normargs={'vmin':np.amin(psi), 'vmax':np.amax(psi)}, colorbar_shrink=.5)\n", + " axs[key].set_title(key)\n", + " axs[key].set_xlabel(\"y\")\n", + " axs[key].set_ylabel(\"x\")\n", + "show_plot('terminal_condition.pdf', inline_format='png')" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAfkAAAHJCAYAAACGzEBJAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjEsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvc2/+5QAAAAlwSFlzAAAPYQAAD2EBqD+naQAAOsJJREFUeJzt3X1cVHXe//H3mQHBFAgNwRtS89JwQypvlsWbrKTMNa8ob4ooy2zdEndR11Yt78tQu7Nb77a0dnHZaqttN7N1LeoyLc2b69Jf5U1KkAmulYK5gsyc3x/I5AjMDQozHF7Px+M8HL7zPed8vlrz5nvOmXMM0zRNAQAAy7EFugAAAFA/CHkAACyKkAcAwKIIeQAALIqQBwDAogh5AAAsipAHAMCiCHkAACyKkAcAwKIIecCDvLw8GYahvLy8QJdSJ1dffbWuvvpqn/smJibWb0HnSX5+vgzD0KpVqwJdChDUCHlY1gsvvCDDMJScnBzoUoLGt99+qzlz5mjHjh2BLsUnq1ev1uLFiwNdBtBoGdy7HlbVr18/ffvtt8rPz9fevXv1X//1X35vw+l0qry8XM2aNZPN1vh+Jy4vL5ckNWvWTJL02WefqU+fPlq5cqXuvvtut75XX321jhw5ol27djV0mbW68cYbtWvXLuXn57u1m6apsrIyhYaGym63B6Y4oBFofJ9agA8OHDigjRs36sknn1RMTIxycnLqtB2bzabw8PBGF/AnTpyQVBnuVQFvJYZhKDw8nIAHvGhcn1yAj3JychQdHa2hQ4dqxIgRtYZ8bm6uevXqpYiICEVGRqpHjx56+umnXe/XdE7+f/7nfzRy5EhdfPHFCgsLU3x8vCZNmqT//Oc/btu+++671bJlSx08eFBpaWlq2bKlYmJiNGXKFDkcDq9j+Nvf/qahQ4eqXbt2CgsLU5cuXfTwww9XW7fqXPrWrVt11VVX6YILLtCDDz7oeq/qnHxeXp769OkjSRozZowMw6jxvPbnn3+ua665RhdccIHat2+vRYsWub1f9Xfy6quvau7cuWrfvr0iIiI0YsQIHTt2TGVlZZo4caLatGmjli1basyYMSorK6s2vj/96U/q1auXmjdvrlatWum2225TYWGh27jeeecdff31165aO3XqJKn2c/JffvmlRo0apZiYGDVv3lyXXnqpHnroIa9/14BVhQS6AKA+5OTk6JZbblGzZs2Unp6uJUuWaMuWLa6Qk6R169YpPT1dgwYN0sKFCyVJX3zxhT7++GNlZWXVuu3XXntNJ06c0P3336/WrVtr8+bNevbZZ/XNN9/otddec+vrcDg0ePBgJScn6/HHH9e//vUvPfHEE+rSpYvuv/9+j2NYtWqVWrZsqcmTJ6tly5Z6//33NWvWLJWUlOixxx5z6/vdd99pyJAhuu2223THHXcoNja22va6d++uefPmadasWRo3bpwGDBggSerbt6+rzw8//KAbbrhBt9xyi0aNGqXXX39dU6dOVY8ePTRkyBC37WVnZ6t58+aaNm2a9u3bp2effVahoaGy2Wz64YcfNGfOHH3yySdatWqVOnfurFmzZrnWnT9/vmbOnKlRo0bp3nvv1b///W89++yzuuqqq7R9+3ZdeOGFeuihh3Ts2DF98803euqppyRJLVu2rPXv6//+7/80YMAAhYaGaty4cerUqZO++uor/f3vf9f8+fM9/l0DlmUCFvPZZ5+Zksx169aZpmmaTqfT7NChg5mVleXWLysry4yMjDQrKipq3dYHH3xgSjI/+OADV9uJEyeq9cvOzjYNwzC//vprV9tdd91lSjLnzZvn1vfKK680e/Xq5XUcNe3n17/+tXnBBReYJ0+edLUNHDjQlGQuXbq0Wv+BAweaAwcOdP28ZcsWU5K5cuXKGvtKMl955RVXW1lZmRkXF2cOHz7c1Vb1d5KYmGiWl5e72tPT003DMMwhQ4a4bTclJcXs2LGj6+f8/HzTbreb8+fPd+u3c+dOMyQkxK196NChbutWOXDgQLVxXHXVVWZERITbv4FpVv77A00Vh+thOTk5OYqNjdU111wjqfL87a233qrc3Fy3Q90XXnihfvzxR61bt86v7Tdv3tz1+scff9SRI0fUt29fmaap7du3V+t/3333uf08YMAA7d+/36/9lJaW6siRIxowYIBOnDihL7/80q1vWFiYxowZ49c4atKyZUvdcccdrp+bNWumn//85zXWO3r0aIWGhrp+Tk5Olmmauueee9z6JScnq7CwUBUVFZKkN954Q06nU6NGjdKRI0dcS1xcnLp27aoPPvjA77r//e9/66OPPtI999yjiy++2O09wzD83h5gFYQ8LMXhcCg3N1fXXHONDhw4oH379mnfvn1KTk5WcXGx1q9f7+o7fvx4devWTUOGDFGHDh10zz33aO3atV73UVBQoLvvvlutWrVynWcfOHCgJOnYsWNufcPDwxUTE+PWFh0drR9++MHrfv7f//t/uvnmmxUVFaXIyEjFxMS4Avjs/bRv3/68XGDXoUOHaqFYW71nh2lUVJQkKT4+vlq70+l01bx3716ZpqmuXbsqJibGbfniiy90+PBhv+uu+iWksXzPH2gonJOHpbz//vs6dOiQcnNzlZubW+39nJwcXX/99ZKkNm3aaMeOHXrvvff07rvv6t1339XKlSs1evRovfzyyzVu3+Fw6LrrrtP333+vqVOnKiEhQS1atNDBgwd19913y+l0uvWv69XfR48e1cCBAxUZGal58+apS5cuCg8P17Zt2zR16tRq+zlz1n8uaqvXrOGbtrX19bYNp9MpwzD07rvv1tjX03l3AP4h5GEpOTk5atOmjZ5//vlq773xxht68803tXTpUlcoNmvWTMOGDdOwYcPkdDo1fvx4LVu2TDNnzqzxe/U7d+7Unj179PLLL2v06NGudn8P+XuTl5en7777Tm+88YauuuoqV/uBAwfOabvBcOi6S5cuMk1TnTt3Vrdu3Tz29bXeSy65RJKC6jv+QDDgcD0s4z//+Y/eeOMN3XjjjRoxYkS1ZcKECSotLdXbb78tqfKK9DPZbDYlJSVJUo1f+ZJ+mqWeObM1TdPta3fnQ037KS8v1wsvvHBO223RooWkyiMFgXLLLbfIbrdr7ty51Y4QmKbp9u/SokWLaqcmahITE6OrrrpKL730kgoKCqptE2iqmMnDMt5++22Vlpbqv//7v2t8/xe/+IXrxji33nqr7r33Xn3//fe69tpr1aFDB3399dd69tlndcUVV6h79+41biMhIUFdunTRlClTdPDgQUVGRuqvf/2rT+fY/dG3b19FR0frrrvu0m9/+1sZhqE//vGP5xxYXbp00YUXXqilS5cqIiJCLVq0UHJysjp37nyeKvethkceeUTTp09Xfn6+0tLSFBERoQMHDujNN9/UuHHjNGXKFElSr1699Je//EWTJ09Wnz591LJlSw0bNqzG7T7zzDPq37+/evbsqXHjxqlz587Kz8/XO++802hu4wucb4Q8LCMnJ0fh4eG67rrranzfZrNp6NChysnJ0Xfffac77rhDy5cv1wsvvKCjR48qLi5Ot956q+bMmVPrHe5CQ0P197//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" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./terminal_condition.pdf
…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "abc504835c394e8a879ddae90ab9fcc5" + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 65 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T20:13:28.034540Z", + "start_time": "2025-03-19T20:13:28.032878Z" + } + }, + "cell_type": "code", + "source": "# quick_look(simulations['Asian geometric'].solver.advector)", + "outputs": [], + "execution_count": 66 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T20:13:28.309240Z", + "start_time": "2025-03-19T20:13:28.306796Z" + } + }, + "source": [ + "# fig, axs = pyplot.subplot_mosaic([simulations.keys()], figsize=(6 * len(simulations), 6))\n", + "# for key, simulation in simulations.items():\n", + "# X = simulation.solver.advector.get_component(0)\n", + "# Y = simulation.solver.advector.get_component(1)\n", + "# grid = (X.shape[1], Y.shape[0])\n", + "# scale = max(np.amax(np.abs(X)), np.amax(np.abs(Y)))\n", + "# print(f\"{grid=}, {scale=}\")\n", + "# axs[key].quiver(*np.mgrid[\n", + "# 1 / 2 : grid[1] : 1,\n", + "# 0: grid[0]+1 : 1,\n", + "# ], 0, X.T.flatten()/scale, pivot='mid', color='green', width=.005,\n", + "# label='price advector values at cell walls', scale=1, scale_units='inches'\n", + "# )\n", + "# axs[key].quiver(*np.mgrid[\n", + "# 0: grid[1]+1 : 1,\n", + "# 1 / 2 : grid[0] : 1,\n", + "# ], Y.T.flatten()/scale, 0, pivot='mid', color='blue', width=.005,\n", + "# label='averaging advector values at cell walls', scale=1, scale_units='inches'\n", + "# )\n", + "# axs[key].scatter(*np.mgrid[\n", + "# 1/2: grid[1] : 1,\n", + "# 1/2: grid[0] : 1\n", + "# ], color='red', label='cell centers', s=2\n", + "# )\n", + "# \n", + "# axs[key].axis('equal')\n", + "# axs[key].set_title(key)\n", + "# axs[key].set_xlabel('y/Δy')\n", + "# axs[key].set_ylabel('x/Δx')\n", + "# # axs[key].legend(bbox_to_anchor=(.1, -.1), loc='upper left', ncol=1)\n", + "# for i, xy in enumerate(('x', 'y')):\n", + "# getattr(axs[key], f\"set_{xy}ticks\")(np.arange(0, grid[i] + 1))\n", + "# axs[key].grid()\n", + "# show_plot('advector.pdf')" + ], + "outputs": [], + "execution_count": 67 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T20:16:36.078154Z", + "start_time": "2025-03-19T20:13:29.533962Z" + } + }, + "source": [ + "history = {}\n", + "for key, simulation in simulations.items():\n", + " history[key] = []\n", + " print(f\"{key}: {simulation.nt} time steps will be taken\")\n", + " progbar = IntProgress(max = simulation.nt)\n", + " display(progbar)\n", + " \n", + " for progbar.value in range(simulation.nt + 1):\n", + " if progbar.value != 0:\n", + " res = simulation.step()\n", + " history[key].append(simulation.solver.advectee.get().copy())" + ], + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Asian arithmetic: 300 time steps will be taken\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=300)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "378fa6e8fe8b414db9233d754fefab3e" + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 68 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T20:24:32.470401Z", + "start_time": "2025-03-19T20:22:33.641443Z" + } + }, + "cell_type": "code", + "source": [ + "arithmetic_by_mc = np.zeros_like(simulation.S)\n", + "arithmetic_option = FixedStrikeArithmeticAsianOption(settings.params.T, settings.params.K2, 'call')\n", + "for idx, spot in tqdm(enumerate(simulation.S)):\n", + " model = BSModel(spot, settings.params.r, settings.params.sgma, settings.params.T, 1000)\n", + " arithmetic_by_mc[idx] = arithmetic_option.price_by_mc(model, 100000)" + ], + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "61it [01:58, 1.95s/it]\n" + ] + } + ], + "execution_count": 72 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T20:25:15.951344Z", + "start_time": "2025-03-19T20:25:15.948127Z" + } + }, + "source": [ + "def plot_solution(frame_index, ax, history, option_type: str):\n", + " params = {k:v for k,v in settings.params.__dict__.items() if not k.startswith(\"K\")}\n", + "\n", + " ax.plot(\n", + " simulation.S,\n", + " (\n", + " Black_Scholes_1973.c_euro(S=simulation.S, K=settings.params.K2, **params, b=settings.params.r)\n", + " # -\n", + " # Black_Scholes_1973.c_euro(S=simulation.S, K=settings.params.K2, **params, b=settings.params.r)\n", + " ),\n", + " label=\"European analytic (Black-Scholes '73)\", linestyle=':'\n", + " )\n", + " # ax.plot(\n", + " # simulation.S,\n", + " # (\n", + " # Bjerksund_and_Stensland_1993.c_amer(S=simulation.S, K=settings.params.K2, **params, b=settings.params.r)\n", + " # # -\n", + " # # Bjerksund_and_Stensland_1993.c_amer(S=simulation.S, K=settings.params.K2, **params, b=settings.params.r)\n", + " # ),\n", + " # label=\"American analytic (Bjerksund & Stensland '93)\", linestyle='--'\n", + " # )\n", + " ax.plot(\n", + " simulation.S,\n", + " (\n", + " asian_analytic.geometric_asian_average_price_c(\n", + " S=simulation.S,\n", + " K=settings.params.K2,\n", + " **params,\n", + " dividend_yield=0\n", + " )\n", + " ),\n", + " label=\"Asian analytic (geometric, Kemna & Vorst 1990)\", alpha=0.5, linestyle=\"--\"\n", + " )\n", + " \n", + " ax.plot(\n", + " simulation.S,\n", + " arithmetic_by_mc,\n", + " label=\"Asian arithmetic by Monte-Carlo\"\n", + " )\n", + " ax.plot(simulation.S, history[frame_index][:,0], label=f\"MPDATA solution ({option_type})\", marker='.')\n", + " # ax.plot(simulation.S, history[0].diagonal(), label=\"discretised terminal condition (discounted payoff)\", marker='.', alpha=0.5)\n", + " ax.legend(loc='upper right')\n", + " ax.grid()\n", + " minmax = (np.amin(history[0]), np.amax(history[0]))\n", + " span = minmax[1] - minmax[0]\n", + " ax.set_ylim(minmax[0] - .05 * span, minmax[1] + .25 * span)\n", + " ax.set_title(f\"instrument parameters: {settings.params.__dict__}\")\n", + " ax.set_xlabel(\"underlying S(t=0)=A(t=0) (and A(T) for terminal condition)\")\n", + " ax.set_ylabel(\"option price\")\n", + " # ax.set_yscale('log')\n", + " # ax.set_xscale('log')\n", + " # ax.set_ylim(10e-1, 100)\n", + " # ax.set_xlim(95, 105)" + ], + "outputs": [], + "execution_count": 73 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T20:25:16.325382Z", + "start_time": "2025-03-19T20:25:16.323126Z" + } + }, + "cell_type": "code", + "source": [ + "def plot_difference_arithmetic(frame_index, ax, history, option_type: str):\n", + " params = {k:v for k,v in settings.params.__dict__.items() if not k.startswith(\"K\")}\n", + "\n", + " \n", + " ax.plot(\n", + " simulation.S,\n", + " abs(arithmetic_by_mc-history[frame_index][:,0])/arithmetic_by_mc,\n", + " label=\"Difference in price of Asian arithmetic option MPDATA vs MC\"\n", + " )\n", + " ax.legend(loc='upper right')\n", + " ax.grid()\n", + " ax.set_title(f\"instrument parameters: {settings.params.__dict__}\")\n", + " ax.set_xlabel(\"underlying S(t=0)=A(t=0) (and A(T) for terminal condition)\")\n", + " ax.set_ylabel(\"option price\")\n", + " ax.set_yscale('log')\n", + " ax.set_ylim(0, 100)" + ], + "outputs": [], + "execution_count": 74 + }, + { + "cell_type": "code", + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-19T20:25:16.939472Z", + "start_time": "2025-03-19T20:25:16.729418Z" + } + }, + "source": [ + "fig, axs = pyplot.subplot_mosaic([simulations.keys()], figsize=(9 * len(simulations), 5))\n", + "for key, simulation in simulations.items():\n", + " plot_solution(-1, axs[key], history[key], option_type=key)\n", + "show_plot('numeric_vs_analytic.pdf')" + ], + "outputs": [ + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-19T21:25:16.913308\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-19T21:25:33.444699\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "text/html": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HTML(value=\".\\\\tmpqu48160_.gif
\")" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "fd45f627043947a1a4d248b723e460ec" + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 28 + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# import os\n", + "# os.environ[\"NUMBA_DISABLE_JIT\"] = \"1\"\n", + "\n", + "from asian_option import AsianArithmetic, Settings, plot_solution, plot_difference_arithmetic\n", + "\n", + "import numpy as np\n", + "from matplotlib import pyplot\n", + "from ipywidgets import IntProgress\n", + "from tqdm import tqdm\n", + "\n", + "from open_atmos_jupyter_utils import show_plot, show_anim\n", + "from monte_carlo import BSModel, FixedStrikeGeometricAsianOption, FixedStrikeArithmeticAsianOption\n", + "import time" + ] + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": [ + "def run_numeric_and_mc(params, nx=31, ny=41, nt=300, variant='call'):\n", + " s_max = params.get('S_max', params['spot']*2)\n", + " s_min = params.get('S_min', params['spot']/2)\n", + " settings = Settings(T=params['T'], K=params['K'], r=params['r'], sgma=params['sgma'], S_max=s_max, S_min=s_min)\n", + " simulation = AsianArithmetic(settings, nx=nx, ny=ny, nt=nt, variant=variant)\n", + " \n", + " \n", + " history = []\n", + " progbar = IntProgress(max = simulation.nt)\n", + " display(progbar)\n", + " start = time.time()\n", + " for progbar.value in range(simulation.nt + 1):\n", + " if progbar.value != 0:\n", + " res = simulation.step()\n", + " history.append(simulation.solver.advectee.get().copy())\n", + " end = time.time()\n", + " print(f\"MPDATA elapsed time: {end - start}\")\n", + " print(f\"Numeric price: {np.interp(params['spot'], simulation.S, history[-1][:,0])}\")\n", + " start = time.time()\n", + " arithmetic_by_mc = np.zeros_like(simulation.S)\n", + " for idx, spot in tqdm(enumerate(simulation.S)):\n", + " model = BSModel(spot, settings.params.r, settings.params.sgma, settings.params.T, 1000)\n", + " arithmetic_option = FixedStrikeArithmeticAsianOption(settings.params.T, settings.params.K, variant, model, 100000)\n", + " arithmetic_by_mc[idx] = arithmetic_option.price_by_mc()\n", + " end = time.time()\n", + " print(f\"MC elapsed time: {end - start}\")\n", + " _, ax = pyplot.subplots(1, 1, figsize=(10, 5))\n", + " plot_solution(settings=settings,\n", + " frame_index=-1,\n", + " ax=ax,\n", + " history=history,\n", + " arithmetic_by_mc=arithmetic_by_mc,\n", + " S_linspace=simulation.S,\n", + " option_type=f'arithmetic {variant}',\n", + " variant=variant)\n", + " show_plot('numeric_vs_analytic.pdf')\n", + " # _, ax = pyplot.subplots(1, 1, figsize=(10, 5))\n", + " # plot_difference_arithmetic(settings=settings,\n", + " # frame_index=-1,\n", + " # ax=ax,\n", + " # history=history,\n", + " # arithmetic_by_mc=arithmetic_by_mc,\n", + " # S_linspace=simulation.S,\n", + " # option_type=f'arithmetic {variant}')\n", + " # show_plot('numeric_vs_analytic_error.pdf')\n", + " \n", + " print(f\"True price: {params['true_price']}\")\n", + " print(f\"Numeric price: {np.interp(params['spot'], simulation.S, history[-1][:,0])}\")\n", + " print(f\"MC price: {np.interp(params['spot'], simulation.S, arithmetic_by_mc)}\")" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3 (ipykernel)", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 3 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython3", + "version": "3.9.2" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/monte_carlo.ipynb b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/monte_carlo.ipynb new file mode 100644 index 00000000..48446fc3 --- /dev/null +++ b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/monte_carlo.ipynb @@ -0,0 +1,189 @@ +{ + "cells": [ + { + "cell_type": "code", + "id": "initial_id", + "metadata": { + "collapsed": true, + "ExecuteTime": { + "end_time": "2025-03-26T13:12:05.473882Z", + "start_time": "2025-03-26T13:12:04.746729Z" + } + }, + "source": "from monte_carlo import BSModel, FixedStrikeGeometricAsianOption, FixedStrikeArithmeticAsianOption", + "outputs": [], + "execution_count": 1 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T13:12:05.514726Z", + "start_time": "2025-03-26T13:12:05.482165Z" + } + }, + "cell_type": "code", + "source": [ + "s0 = 100\n", + "r = 0.1\n", + "sigma = 0.1\n", + "T = 2\n", + "K = 100\n", + "true_price = 3.028\n", + "arithm_bp = 3.100\n", + "\n", + "M = 1000\n", + "N = 100000\n", + "model = BSModel(s0, r, sigma, T, M)\n", + "arithmetic_option = FixedStrikeArithmeticAsianOption(T, K, 'call', model, N)\n", + "# geometric_option = FixedStrikeGeometricAsianOption(T, K, 'call', model, N)" + ], + "id": "1844a74546da6e65", + "outputs": [], + "execution_count": 2 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T13:12:27.147208Z", + "start_time": "2025-03-26T13:12:16.886139Z" + } + }, + "cell_type": "code", + "source": [ + "arithm_price = arithmetic_option.price_by_mc()\n", + "# geo_price = geometric_option.price_by_mc(model, N)" + ], + "id": "95d1d5556a41a618", + "outputs": [], + "execution_count": 4 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-13T17:26:10.868058Z", + "start_time": "2025-03-13T17:26:02.004283Z" + } + }, + "cell_type": "code", + "source": [ + "print(arithmetic_option.price_by_mc(model, 1000))\n", + "print(arithmetic_option.price_by_mc(model, 10000))\n", + "print(arithmetic_option.price_by_mc(model, 100000))" + ], + "id": "86d4256a676cab2f", + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Pricing by MC: 100%|█████████████████████████████████████████| 1000/1000 [00:00<00:00, 11911.30it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "8.710956126536196\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Pricing by MC: 100%|███████████████████████████████████████| 10000/10000 [00:00<00:00, 11906.89it/s]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "9.101791585524897\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "Pricing by MC: 100%|█████████████████████████████████████| 100000/100000 [00:07<00:00, 12646.48it/s]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "9.140055184423701\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + } + ], + "execution_count": 4 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-13T17:18:26.296216400Z", + "start_time": "2025-03-13T15:21:26.958391Z" + } + }, + "cell_type": "code", + "source": [ + "geom_error = abs(geo_price - true_price)/true_price\n", + "arithm_error = abs(arithm_price - arithm_bp)/arithm_bp\n", + "\n", + "print(f'Geometric Asian Call Price: {geo_price}')\n", + "print(f'Geometric Asian Call Error: {geom_error}')\n", + "print(f'Arithmetic Asian Call Price: {arithm_price}')\n", + "print(f'Arithmetic Asian Call Error: {arithm_error}')" + ], + "id": "eb00ae1e3835d3e4", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Geometric Asian Call Price: 8.858897106549337\n", + "Geometric Asian Call Error: 1.9256595464165576\n", + "Arithmetic Asian Call Price: 9.176177239116097\n", + "Arithmetic Asian Call Error: 1.9600571739084183\n" + ] + } + ], + "execution_count": 35 + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": "", + "id": "b59f537babe46f99" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/monte_carlo.py b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/monte_carlo.py new file mode 100644 index 00000000..adda08d9 --- /dev/null +++ b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/monte_carlo.py @@ -0,0 +1,120 @@ +import os +from abc import abstractmethod +from typing import Callable + +import numpy as np +from tqdm import tqdm + +os.environ["NUMBA_OPT"] = "3" + +from functools import cached_property, lru_cache, partial + +import numba + +jit = partial(numba.jit, fastmath=True, error_model="numpy", cache=True, nogil=True) + + +class BSModel: + def __init__(self, S0, r, sigma, T, M): + self.S0 = S0 + self.r = r + self.sigma = sigma + self.sigma2 = sigma * sigma + self.b = r - 0.5 * self.sigma2 + self.T = T + self.M = M + self.t = np.linspace(0, T, M) + self.bt = self.b * self.t + self.sqrt_tm = np.sqrt(T / M) + + @cached_property + def generate_path(self): + M = self.M + S0 = self.S0 + bt = self.bt + sigma = self.sigma + sqrt_tm = self.sqrt_tm + + @jit + def body(path): + path[:] = S0 * np.exp( + bt + sigma * np.cumsum(np.random.standard_normal(M)) * sqrt_tm + ) + + return body + + +class PathDependentOption: + def __init__(self, T, model, N): + self.T = T + self.model = model + self.N = N + self.payoff: Callable[[np.ndarray], float] = lambda path: 0.0 + self.std = 0 + + @cached_property + def price_by_mc(self): + T = self.T + model_generate_path = self.model.generate_path + model_r = self.model.r + payoff = self.payoff + M = self.model.M + N = self.N + + @jit + def body(): + sum_ct = 0.0 + sum_sq = 0.0 + path = np.empty(M) + for _ in range(N): + model_generate_path(path) + partial_payoff = payoff(path) + sum_ct += partial_payoff + sum_sq += partial_payoff**2 + return np.exp(-model_r * T) * (sum_ct / N), np.exp(-model_r * T) * np.sqrt( + (sum_sq / N) - (sum_ct / N) ** 2 + ) + + return body + + +@lru_cache +def make_payoff(K: float, option_type: str, average_type: str = "arithmetic"): + assert average_type in ["arithmetic", "geometric"] + if average_type != "arithmetic": + raise NotImplementedError("Only arithmetic average is supported") + if option_type == "call": + + @jit + def payoff(path): + return max(np.mean(path) - K, 0) + + elif option_type == "put": + + @jit + def payoff(path): + return max(K - np.mean(path), 0) + + else: + raise ValueError("Invalid option") + return payoff + + +class FixedStrikeArithmeticAsianOption(PathDependentOption): + def __init__(self, T, K, type, model, N): + super().__init__(T, model, N) + self.K = K + self.payoff = make_payoff(K, type) + + +class FixedStrikeGeometricAsianOption(PathDependentOption): + def __init__(self, T, K, type, model, N): + super().__init__(T, model, N) + self.K = K + + if type == "call": + self.payoff = lambda path: max(np.exp(np.mean(np.log(path))) - K, 0) + elif type == "put": + self.payoff = lambda path: max(K - np.exp(np.mean(np.log(path))), 0) + else: + raise ValueError("Invalid option type") diff --git a/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/table_1.ipynb b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/table_1.ipynb new file mode 100644 index 00000000..efe4be25 --- /dev/null +++ b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/table_1.ipynb @@ -0,0 +1,8712 @@ +{ + "cells": [ + { + "cell_type": "code", + "id": "initial_id", + "metadata": { + "collapsed": true, + "ExecuteTime": { + "end_time": "2025-03-26T14:55:44.872588Z", + "start_time": "2025-03-26T14:55:44.870570Z" + } + }, + "source": [ + "# import sys\n", + "# \n", + "# from tests.smoke_tests.olesik_et_al_2022.test_simulation import settings\n", + "# \n", + "# if 'google.colab' in sys.modules:\n", + "# !pip --quiet install open-atmos-jupyter-utils\n", + "# from open_atmos_jupyter_utils import pip_install_on_colab\n", + "# pip_install_on_colab('PyMPDATA-examples')" + ], + "outputs": [], + "execution_count": 2 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-23T11:27:43.681229Z", + "start_time": "2025-04-23T11:27:36.846194Z" + } + }, + "cell_type": "code", + "source": [ + "import matplotlib.pyplot as plt\n", + "\n", + "# import os\n", + "# os.environ[\"NUMBA_DISABLE_JIT\"] = \"1\"\n", + "\n", + "from asian_option import AsianArithmetic, Settings, plot_solution, plot_difference_arithmetic\n", + "\n", + "import numpy as np\n", + "from matplotlib import pyplot\n", + "from ipywidgets import IntProgress\n", + "from tqdm import tqdm\n", + "\n", + "from open_atmos_jupyter_utils import show_plot, show_anim\n", + "from monte_carlo import BSModel, FixedStrikeGeometricAsianOption, FixedStrikeArithmeticAsianOption\n", + "import time\n", + "from PyMPDATA_examples.utils.financial_formulae import (\n", + " Bjerksund_and_Stensland_1993,\n", + " Black_Scholes_1973,\n", + ")\n", + "import PyMPDATA_examples.utils.financial_formulae.asian_option as asian_analytic" + ], + "id": "bd8f8eaef8662792", + "outputs": [], + "execution_count": 1 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-23T11:27:44.840384Z", + "start_time": "2025-04-23T11:27:44.831393Z" + } + }, + "cell_type": "code", + "source": [ + "def plot_solution(\n", + " settings,\n", + " frame_index,\n", + " ax,\n", + " history,\n", + " S_linspace,\n", + " arithmetic_by_mc,\n", + " option_type: str,\n", + " variant,\n", + " A_space,\n", + " S_space\n", + "):\n", + " params = {\n", + " k: v for k, v in settings.params.__dict__.items() if not k.startswith(\"K\")\n", + " }\n", + " if variant == \"call\":\n", + " BS_price_func = Black_Scholes_1973.c_euro\n", + " Amer_price_func = Bjerksund_and_Stensland_1993.c_amer\n", + " geometric_price_func = asian_analytic.geometric_asian_average_price_c\n", + " else:\n", + " BS_price_func = Black_Scholes_1973.p_euro\n", + " Amer_price_func = Bjerksund_and_Stensland_1993.p_amer\n", + " geometric_price_func = asian_analytic.geometric_asian_average_price_p\n", + "\n", + " ax.plot(\n", + " S_linspace,\n", + " (\n", + " BS_price_func(\n", + " S=S_linspace, K=settings.params.K, **params, b=settings.params.r\n", + " )\n", + " ),\n", + " label=\"European analytic (Black-Scholes '73)\",\n", + " linestyle=\"--\",\n", + " alpha=0.5,\n", + " )\n", + " # ax.plot(\n", + " # S_linspace,\n", + " # (\n", + " # Amer_price_func(\n", + " # S=S_linspace, K=settings.params.K, **params, b=settings.params.r\n", + " # )\n", + " # ),\n", + " # label=\"American analytic (Bjerksund & Stensland '93)\", linestyle='--'\n", + " # )\n", + " ax.plot(\n", + " S_linspace,\n", + " (\n", + " geometric_price_func(\n", + " S=S_linspace, K=settings.params.K, **params, dividend_yield=0\n", + " )\n", + " ),\n", + " label=\"Asian analytic (geometric, Kemna & Vorst 1990)\",\n", + " alpha=0.5,\n", + " linestyle=\"--\",\n", + " )\n", + " ax.plot(\n", + " S_linspace,\n", + " arithmetic_by_mc,\n", + " label=\"Asian arithmetic by Monte-Carlo\",\n", + " linestyle=\":\",\n", + " )\n", + " ax.bar(\n", + " settings.rh[:-1],\n", + " history[frame_index][:, 0],\n", + " width=settings.rh[1:] - settings.rh[:-1],\n", + " label=f\"MPDATA solution ({option_type})\",\n", + " marker=\".\",\n", + " )\n", + " ax.plot(\n", + " A_space,\n", + " history[0][0, :],\n", + " label=f\"Terminal condition (discounted payoff)\",\n", + " marker=\".\",\n", + " )\n", + " ax.legend(loc=\"upper right\")\n", + " ax.grid()\n", + " minmax = (np.amin(history[0]), np.amax(history[0]))\n", + " span = minmax[1] - minmax[0]\n", + " ax.set_ylim(minmax[0] - 0.05 * span, minmax[1] + 0.25 * span)\n", + " ax.set_title(f\"instrument parameters: {settings.params.__dict__}\")\n", + " # ax.set_xlabel(\"underlying S(t=0)=A(t=0) (and A(T) for terminal condition)\")\n", + " ax.set_xlabel(\"average at t=T for payoff, spot at t=0 for other datasets\")\n", + " ax.set_ylabel(\"value\")" + ], + "id": "12cea6ef353ffc5b", + "outputs": [], + "execution_count": 2 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-25T12:36:58.592860Z", + "start_time": "2025-04-25T12:36:58.574858Z" + } + }, + "cell_type": "code", + "source": [ + "def run_numeric_and_mc(params, nx=31, ny=41, nt=300, variant='call'):\n", + " s_max = params.get('S_max', params['spot']*2)\n", + " s_min = params.get('S_min', params['spot']/2)\n", + " settings = Settings(T=params['T'], K=params['K'], r=params['r'], sgma=params['sgma'], S_max=s_max, S_min=s_min)\n", + " simulation = AsianArithmetic(settings, nx=nx, ny=ny, nt=nt, variant=variant)\n", + " \n", + " \n", + " history = []\n", + " progbar = IntProgress(max = simulation.nt)\n", + " display(progbar)\n", + " start = time.time()\n", + " for progbar.value in range(simulation.nt + 1):\n", + " if progbar.value != 0:\n", + " res = simulation.step()\n", + " history.append(simulation.solver.advectee.get().copy())\n", + " end = time.time()\n", + " print(f\"MPDATA elapsed time: {end - start}\")\n", + " print(f\"Numeric price: {np.interp(params['spot'], simulation.S, history[-1][:,0])}\")\n", + " # start = time.time()\n", + " arithmetic_by_mc = np.zeros_like(simulation.S)\n", + " arithmetic_by_mc_std = np.zeros_like(simulation.S)\n", + " # for idx, spot in tqdm(enumerate(simulation.S)):\n", + " # model = BSModel(spot, settings.params.r, settings.params.sgma, settings.params.T, 1000)\n", + " # arithmetic_option = FixedStrikeArithmeticAsianOption(settings.params.T, settings.params.K, variant, model, 100000)\n", + " # arithmetic_by_mc[idx], arithmetic_by_mc_std[idx] = arithmetic_option.price_by_mc()\n", + " # end = time.time()\n", + " # print(f\"MC elapsed time: {end - start}\")\n", + " S_space = np.exp(np.linspace(np.log(simulation.S[0])-simulation.dx/2, np.log(simulation.S[-1])+simulation.dx/2, nx+1))\n", + " _, ax = pyplot.subplots(1, 1, figsize=(8, 4))\n", + " plot_solution(settings=settings,\n", + " frame_index=-1,\n", + " ax=ax,\n", + " history=history,\n", + " arithmetic_by_mc=history[-1][:,0],\n", + " # arithmetic_by_mc=arithmetic_by_mc,\n", + " arithmetic_by_mc_std=arithmetic_by_mc_std,\n", + " S_linspace=simulation.S,\n", + " option_type=f'arithmetic {variant}',\n", + " variant=variant,\n", + " A_space=simulation.A,\n", + " S_space=S_space)\n", + " show_plot('numeric_vs_analytic.pdf')\n", + " \n", + " print(f\"True price: {params['true_price']}\")\n", + " print(f\"Numeric price: {np.interp(params['spot'], simulation.S, history[-1][:,0])}\")\n", + " # print(f\"MC price: {np.interp(params['spot'], simulation.S, arithmetic_by_mc)}\")" + ], + "id": "546e4f22be847ea4", + "outputs": [], + "execution_count": 73 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "## sigma = 0.1", + "id": "e9af660af0a54cf3" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### T = 0.25", + "id": "e4fcfc900d2a1edf" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T22:20:52.171109Z", + "start_time": "2025-03-26T22:15:29.762750Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 6.132,\n", + " 'S_max': 120,\n", + " 'S_min': 80\n", + " }\n", + "run_numeric_and_mc(params, nx=121, ny=500, nt=1500)" + ], + "id": "52ab1c5adb568508", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(6.737324795840403)\n", + "CFL 0.33739169305000277\n", + "courant_x=np.float64(0.004725026383336177), courant_y=np.float64(0.3326666666666666)\n", + "x_dim_advector.shape=(122, 500), self.a_dim_advector.shape=(121, 501)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "c99e620e361f49b38765f2f3435d6c7f" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 58.98099613189697\n", + "Numeric price: 6.117620067942513\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "121it [04:22, 2.17s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 262.8348124027252\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T23:20:51.759679\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T23:20:52.124050\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "1dad65ed46a24a1c9fdc7e4839c311c8" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 6.132\n", + "Numeric price: 6.117620067942513\n", + "MC price: 6.1208107318861265\n" + ] + } + ], + "execution_count": 5 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T09:57:49.009940Z", + "start_time": "2025-04-03T09:51:05.198423Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 6.132,\n", + " 'S_max': 120,\n", + " 'S_min': 80\n", + " }\n", + "run_numeric_and_mc(params, nx=121, ny=500, nt=1500)" + ], + "id": "6d52948ed3e0220e", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=6.737324795840403\n", + "CFL 0.33739169305000277\n", + "courant_x=0.004725026383336177, courant_y=0.3326666666666666\n", + "x_dim_advector.shape=(122, 500), self.a_dim_advector.shape=(121, 501)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "5b3a1f63118141c7976aaec26e96e7aa" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 17.602856159210205\n", + "Numeric price: 6.117620067954955\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "121it [06:24, 3.17s/it]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 384.0525276660919\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T11:57:47.602570\n image/svg+xml\n \n \n Matplotlib v3.7.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\".\\\\numeric_vs_analytic.pdf…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "b5889062003140cc8698ef1b531513b1" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "C:\\Users\\Pawel\\PycharmProjects\\PyMPDATA\\examples\\PyMPDATA_examples\\Magnuszewski_et_al_2025\\asian_option.py:404: RuntimeWarning: divide by zero encountered in divide\n", + " abs(arithmetic_by_mc - history[frame_index][:, 0]) / arithmetic_by_mc,\n", + "C:\\Users\\Pawel\\PycharmProjects\\PyMPDATA\\examples\\PyMPDATA_examples\\Magnuszewski_et_al_2025\\asian_option.py:413: UserWarning: Attempt to set non-positive ylim on a log-scaled axis will be ignored.\n", + " ax.set_ylim(0, 100)\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T11:57:48.856745\n image/svg+xml\n \n \n Matplotlib v3.7.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\".\\\\numeric_vs_analytic_e…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "8dee6463cbb242e5ac389f6c3699c20a" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 6.132\n", + "Numeric price: 6.117620067954955\n", + "MC price: 6.121811548784314\n" + ] + } + ], + "execution_count": 4 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T19:02:49.237508Z", + "start_time": "2025-03-26T18:58:17.717189Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 1.869,\n", + " 'S_max': 120,\n", + " 'S_min': 80\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=500, nt=1500)" + ], + "id": "84c0ad9139d9de66", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(9.66975515497494)\n", + "CFL 0.3366106969535836\n", + "courant_x=np.float64(0.003944030286916974), courant_y=np.float64(0.3326666666666666)\n", + "x_dim_advector.shape=(102, 500), self.a_dim_advector.shape=(101, 501)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "30ed5211d57b4d6494dabe6b8a75e963" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 65.01133799552917\n", + "Numeric price: 1.873875070498296\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:25, 2.04s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 205.91771578788757\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T20:02:48.819748\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T20:02:49.190279\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "9141633a0439410d9ee5ba8ec69ded72" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 1.869\n", + "Numeric price: 1.873875070498296\n", + "MC price: 1.8510434244370215\n" + ] + } + ], + "execution_count": 37 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T19:23:47.999042Z", + "start_time": "2025-03-26T19:20:19.037675Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 0.151,\n", + " 'S_max': 120,\n", + " 'S_min': 80\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=500, nt=1500)" + ], + "id": "e5a56cc7ac5597a4", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(9.66975515497494)\n", + "CFL 0.3366106969535836\n", + "courant_x=np.float64(0.003944030286916974), courant_y=np.float64(0.3326666666666666)\n", + "x_dim_advector.shape=(102, 500), self.a_dim_advector.shape=(101, 501)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "f54554274e904caf9d86297d0ac0eea1" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 6.592661142349243\n", + "Numeric price: 0.17248245918828978\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:21, 2.00s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 201.8002269268036\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T20:23:47.613394\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T20:23:47.955971\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "89308baa54354d21a8d6e1ac31f6ac5d" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 0.151\n", + "Numeric price: 0.17248245918828978\n", + "MC price: 0.14671374756013328\n" + ] + } + ], + "execution_count": 45 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### T = 0.5", + "id": "af4752d0b73ee586" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T19:29:52.739595Z", + "start_time": "2025-03-26T19:25:03.546675Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 7.248,\n", + " 'S_max': 120,\n", + " 'S_min': 80\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=500, nt=1500)" + ], + "id": "c64b78f762ddf19f", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.83487757748747)\n", + "CFL 0.34055472724050057\n", + "courant_x=np.float64(0.007888060573833948), courant_y=np.float64(0.3326666666666666)\n", + "x_dim_advector.shape=(102, 500), self.a_dim_advector.shape=(101, 501)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "80024e3a9f6040e38356eb4b38418443" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 36.11634802818298\n", + "Numeric price: 7.23805467438877\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [04:12, 2.50s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 252.5069715976715\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T20:29:52.342751\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T20:29:52.694325\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "e6f3f40981e84c1c81988991e271898b" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 7.248\n", + "Numeric price: 7.23805467438877\n", + "MC price: 7.223247309952393\n" + ] + } + ], + "execution_count": 46 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T19:41:49.456276Z", + "start_time": "2025-03-26T19:38:21.885164Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 3.1,\n", + " 'S_max': 120,\n", + " 'S_min': 80\n", + " }\n", + "run_numeric_and_mc(params, nx=71, ny=400, nt=1500)" + ], + "id": "b1ed79f5552414df", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(9.783889340993785)\n", + "CFL 0.2715450722845763\n", + "courant_x=np.float64(0.0055450722845763415), courant_y=np.float64(0.26599999999999996)\n", + "x_dim_advector.shape=(72, 400), self.a_dim_advector.shape=(71, 401)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "4d39fdf6febc431193f505d919da5904" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 35.576953411102295\n", + "Numeric price: 3.1170989026076468\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "71it [02:51, 2.41s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 171.40877079963684\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T20:41:49.032086\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T20:41:49.405525\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "fe54f35d5a894df9957d246dce6e7442" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 3.1\n", + "Numeric price: 3.1170989026076468\n", + "MC price: 3.0771666777085724\n" + ] + } + ], + "execution_count": 50 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T22:26:13.158318Z", + "start_time": "2025-03-26T22:21:56.077726Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 0.727,\n", + " 'S_max': 120,\n", + " 'S_min': 80\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=400, nt=2000)" + ], + "id": "53cc4f28921057da", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(6.44650343664996)\n", + "CFL 0.20541604543037542\n", + "courant_x=np.float64(0.005916045430375462), courant_y=np.float64(0.19949999999999996)\n", + "x_dim_advector.shape=(102, 400), self.a_dim_advector.shape=(101, 401)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "3f4a6dc78dd84a0ca17d50b485ea036d" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 51.17937707901001\n", + "Numeric price: 0.755516576533361\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:25, 2.03s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 205.32445168495178\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T23:26:12.769907\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T23:26:13.116103\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "48e00511a1504c4fb5b85617aedc936c" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 0.727\n", + "Numeric price: 0.755516576533361\n", + "MC price: 0.7181102171339728\n" + ] + } + ], + "execution_count": 7 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### T = 1", + "id": "83acf7f6080c679b" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T20:40:05.327928Z", + "start_time": "2025-03-26T20:36:02.518334Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 9.313,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=500, nt=2500)" + ], + "id": "a28d9267aa384cea", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(47.0986191469661)\n", + "CFL 0.20236853178346584\n", + "courant_x=np.float64(0.0027685317834659213), courant_y=np.float64(0.19959999999999992)\n", + "x_dim_advector.shape=(102, 500), self.a_dim_advector.shape=(101, 501)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "b731e9aff03544b1923af9645a40231b" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 40.146838903427124\n", + "Numeric price: 9.32109221064491\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:22, 2.00s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 202.10721015930176\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T21:40:04.938329\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T21:40:05.284665\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "f83a7840c0c94d78ab4b4bcb03d84bfc" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 9.313\n", + "Numeric price: 9.32109221064491\n", + "MC price: 9.280451262059675\n" + ] + } + ], + "execution_count": 63 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T20:44:10.516005Z", + "start_time": "2025-03-26T20:40:06.747350Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 5.279,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=500, nt=2500)" + ], + "id": "b50d733dbb6218d1", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(47.0986191469661)\n", + "CFL 0.20236853178346584\n", + "courant_x=np.float64(0.0027685317834659213), courant_y=np.float64(0.19959999999999992)\n", + "x_dim_advector.shape=(102, 500), self.a_dim_advector.shape=(101, 501)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "ea2ca49a3e60478892c351004d20bca0" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 40.21532130241394\n", + "Numeric price: 5.291606873926925\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:22, 2.01s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 202.9929702281952\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T21:44:10.123563\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T21:44:10.472461\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "5e6b25b793a94ef7ac4fc59511b1093c" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 5.279\n", + "Numeric price: 5.291606873926925\n", + "MC price: 5.279868482000612\n" + ] + } + ], + "execution_count": 64 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T21:42:40.604854Z", + "start_time": "2025-03-26T21:34:49.303045Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 2.313,\n", + " }\n", + "run_numeric_and_mc(params, nx=171, ny=600, nt=3000)" + ], + "id": "5083a5cdf1246ac5", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(19.716959635506356)\n", + "CFL 0.20357276348987344\n", + "courant_x=np.float64(0.0039060968232068694), courant_y=np.float64(0.19966666666666658)\n", + "x_dim_advector.shape=(172, 600), self.a_dim_advector.shape=(171, 601)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=3000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "df44d98f23104a248311e42c571c37af" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 42.432754039764404\n", + "Numeric price: 2.329833876655385\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "171it [07:08, 2.50s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 428.2790036201477\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T22:42:40.207541\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T22:42:40.556946\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "e72a1833d45a4e60a91858e265e3a4c7" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 2.313\n", + "Numeric price: 2.329833876655385\n", + "MC price: 2.294358605447854\n" + ] + } + ], + "execution_count": 73 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "## sigma = 0.2", + "id": "5c0f0bd614b81421" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### T = 0.25", + "id": "16e7eb01844a5e34" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T21:49:55.777029Z", + "start_time": "2025-03-26T21:44:56.161727Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 6.5,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=500, nt=3000)" + ], + "id": "9c811c46489fc2d9", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(56.51834297635932)\n", + "CFL 0.16681904066376588\n", + "courant_x=np.float64(0.0004857073304326177), courant_y=np.float64(0.16633333333333325)\n", + "x_dim_advector.shape=(102, 500), self.a_dim_advector.shape=(101, 501)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=3000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "b31f11a3f3424fa18ae1e74a2650c4c4" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 44.36493515968323\n", + "Numeric price: 6.479734092585453\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [04:14, 2.52s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 254.65015649795532\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T22:49:55.346537\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T22:49:55.729144\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "b99a4aef036e4c25aaf4a7796746c3cf" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 6.5\n", + "Numeric price: 6.479734092585453\n", + "MC price: 6.480534273237569\n" + ] + } + ], + "execution_count": 76 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T21:54:00.430976Z", + "start_time": "2025-03-26T21:49:55.842009Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 2.960,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=500, nt=3000)" + ], + "id": "c6bbee17c503c283", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(56.51834297635932)\n", + "CFL 0.16681904066376588\n", + "courant_x=np.float64(0.0004857073304326177), courant_y=np.float64(0.16633333333333325)\n", + "x_dim_advector.shape=(102, 500), self.a_dim_advector.shape=(101, 501)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=3000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "4724ddc367734dff8e6faa5dbb1fb2cd" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 41.78067398071289\n", + "Numeric price: 2.9615616957809614\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:22, 2.00s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 202.21847438812256\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T22:54:00.008197\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-26T22:54:00.384156\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "dd1af9fdf62a4202b3b2f5966f670b50" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 2.96\n", + "Numeric price: 2.9615616957809614\n", + "MC price: 2.9230179830439713\n" + ] + } + ], + "execution_count": 77 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T23:15:12.971944Z", + "start_time": "2025-03-26T23:08:55.787748Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 0.966,\n", + " }\n", + "run_numeric_and_mc(params, nx=151, ny=800, nt=3000)" + ], + "id": "d97abdef936a1c4f", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(25.285891702199095)\n", + "CFL 0.2670594898372473\n", + "courant_x=np.float64(0.0007261565039141117), courant_y=np.float64(0.2663333333333332)\n", + "x_dim_advector.shape=(152, 800), self.a_dim_advector.shape=(151, 801)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=3000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "d4025a691fa94149bc63764b06b0a652" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 67.22992396354675\n", + "Numeric price: 0.9735837467209867\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "151it [05:08, 2.04s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 308.73529076576233\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T00:15:11.935489\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T00:15:12.927001\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "15353b29c9d4497bac3b425ca7394072" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 0.966\n", + "Numeric price: 0.9735837467209867\n", + "MC price: 0.9479796324019648\n" + ] + } + ], + "execution_count": 23 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### T = 0.5", + "id": "4754e22b497010b3" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T23:20:23.188199Z", + "start_time": "2025-03-26T23:16:10.621619Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 7.793,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=300, nt=3000)" + ], + "id": "5938ee3678f411f5", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(28.25917148817966)\n", + "CFL 0.10063808132753185\n", + "courant_x=np.float64(0.0009714146608652355), courant_y=np.float64(0.09966666666666661)\n", + "x_dim_advector.shape=(102, 300), self.a_dim_advector.shape=(101, 301)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=3000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "b1bc3d256ae64f93a016da9eec436ef5" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 43.361796855926514\n", + "Numeric price: 7.907266869619778\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:28, 2.07s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 208.6245617866516\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T00:20:22.779700\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T00:20:23.139711\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "f93db76f974b46508e5f18212bd21098" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 7.793\n", + "Numeric price: 7.907266869619778\n", + "MC price: 7.901410364533869\n" + ] + } + ], + "execution_count": 25 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-26T23:41:27.169752Z", + "start_time": "2025-03-26T23:36:53.715189Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 4.548,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=300, nt=3000)" + ], + "id": "e52bb3aa743f783c", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(28.25917148817966)\n", + "CFL 0.10063808132753185\n", + "courant_x=np.float64(0.0009714146608652355), courant_y=np.float64(0.09966666666666661)\n", + "x_dim_advector.shape=(102, 300), self.a_dim_advector.shape=(101, 301)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=3000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "d1978b6a1b5c47f2aa5cf425665dbf18" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 64.4211094379425\n", + "Numeric price: 4.548534262410401\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:28, 2.06s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 208.44248747825623\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T00:41:26.745432\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T00:41:27.120446\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "823f43d625da432a9dee69bdfc068eff" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 4.548\n", + "Numeric price: 4.548534262410401\n", + "MC price: 4.498795084403486\n" + ] + } + ], + "execution_count": 26 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T00:23:52.800014Z", + "start_time": "2025-03-27T00:20:09.537454Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 2.241,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=400, nt=3000)" + ], + "id": "ba1e4bbea2fea16", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(28.25917148817966)\n", + "CFL 0.13397141466086518\n", + "courant_x=np.float64(0.0009714146608652355), courant_y=np.float64(0.13299999999999995)\n", + "x_dim_advector.shape=(102, 400), self.a_dim_advector.shape=(101, 401)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=3000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "f5054e525de440a989c0c98b9fa53cae" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 19.9363956451416\n", + "Numeric price: 2.262972517589888\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:22, 2.01s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 202.7743284702301\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T01:23:52.416614\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T01:23:52.755248\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "00bbe89849494de7aef06fd92e5c3add" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 2.241\n", + "Numeric price: 2.262972517589888\n", + "MC price: 2.2065165941301417\n" + ] + } + ], + "execution_count": 30 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### T = 1", + "id": "e356c6c319851f57" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T09:30:57.882717Z", + "start_time": "2025-03-27T09:27:23.901363Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 10.336,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=300, nt=3000)" + ], + "id": "75135a4b98ce14d5", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(14.12958574408983)\n", + "CFL 0.10160949598839708\n", + "courant_x=np.float64(0.001942829321730471), courant_y=np.float64(0.09966666666666661)\n", + "x_dim_advector.shape=(102, 300), self.a_dim_advector.shape=(101, 301)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=3000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "59a6c1a512af43d59ccfd320bc0dbf10" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 11.284118890762329\n", + "Numeric price: 10.35798495255406\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:22, 2.00s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 202.11466360092163\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T10:30:57.462343\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T10:30:57.833604\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "1213f9f159734ce6a9078fa42aafd6c4" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 10.336\n", + "Numeric price: 10.35798495255406\n", + "MC price: 10.284173062381173\n" + ] + } + ], + "execution_count": 34 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T12:03:41.978011Z", + "start_time": "2025-03-27T11:58:31.483452Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 7.079,\n", + " }\n", + "run_numeric_and_mc(params, nx=121, ny=200, nt=4000)" + ], + "id": "ba886b925684c508", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(13.12623492707332)\n", + "CFL 0.051495660999475626\n", + "courant_x=np.float64(0.0017456609994756461), courant_y=np.float64(0.04974999999999998)\n", + "x_dim_advector.shape=(122, 200), self.a_dim_advector.shape=(121, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=4000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "b31e7b3a49d84aa295704474d9f129ef" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 60.90426731109619\n", + "Numeric price: 7.096975058351778\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "121it [04:08, 2.06s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 248.98864316940308\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T13:03:41.547165\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T13:03:41.918409\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "babadea8eb7546378c4a091ad808648f" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 7.079\n", + "Numeric price: 7.096975058351778\n", + "MC price: 7.051676711641259\n" + ] + } + ], + "execution_count": 45 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T13:53:55.865097Z", + "start_time": "2025-03-27T13:49:10.643448Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 4.539,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=250, nt=5000)" + ], + "id": "f4d7c251193d373b", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(23.54930957348305)\n", + "CFL 0.05096569759303827\n", + "courant_x=np.float64(0.0011656975930382828), courant_y=np.float64(0.04979999999999998)\n", + "x_dim_advector.shape=(102, 250), self.a_dim_advector.shape=(101, 251)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=5000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "d412737345714a2790cde643d23ba0a4" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 76.43629837036133\n", + "Numeric price: 4.590857118265698\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:28, 2.06s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 208.16607403755188\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T14:53:55.409547\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T14:53:55.813593\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "0c54c7459fd74417a9826bff7937314e" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 4.539\n", + "Numeric price: 4.590857118265698\n", + "MC price: 4.503736080266976\n" + ] + } + ], + "execution_count": 7 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "## sigma = 0.4", + "id": "f2b29dbd0d3b08a8" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### T = 0.25", + "id": "3c9a001ab9ecf395" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T14:15:20.036740Z", + "start_time": "2025-03-27T14:09:58.210271Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 8.151,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=300, nt=3000)" + ], + "id": "660798133ebf93e2", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(14.12958574408983)\n", + "CFL 0.09978809349927477\n", + "courant_x=np.float64(0.00012142683260815438), courant_y=np.float64(0.09966666666666661)\n", + "x_dim_advector.shape=(102, 300), self.a_dim_advector.shape=(101, 301)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=3000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "eb35b5d2e39746bcb9b079fa6c648370" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 54.102399826049805\n", + "Numeric price: 8.148219143453625\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [04:27, 2.65s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 267.14795303344727\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T15:15:19.632170\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T15:15:19.990056\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "d45c0b2ea36d4f2a9ed1097453bacd35" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 8.151\n", + "Numeric price: 8.148219143453625\n", + "MC price: 8.140743252725361\n" + ] + } + ], + "execution_count": 8 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T14:42:47.041469Z", + "start_time": "2025-03-27T14:38:03.442371Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 5.218,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=200, nt=3000)" + ], + "id": "fbcc028a8096c4f9", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(14.12958574408983)\n", + "CFL 0.06645476016594147\n", + "courant_x=np.float64(0.00012142683260815438), courant_y=np.float64(0.06633333333333331)\n", + "x_dim_advector.shape=(102, 200), self.a_dim_advector.shape=(101, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=3000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "39e7e84db1d742c6942d041d2d8797a5" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 73.67468810081482\n", + "Numeric price: 5.232699634724515\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:28, 2.07s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 208.96177792549133\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T15:42:46.244656\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T15:42:46.991156\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "e0724ab71cd247acb728ce245f27f022" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 5.218\n", + "Numeric price: 5.232699634724515\n", + "MC price: 5.161130694728721\n" + ] + } + ], + "execution_count": 10 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T16:42:50.181364Z", + "start_time": "2025-03-27T16:37:56.952017Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 3.106,\n", + " }\n", + "run_numeric_and_mc(params, nx=81, ny=200, nt=5000)" + ], + "id": "484904a6c838f0dd", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(36.61431290338371)\n", + "CFL 0.039858429149155994\n", + "courant_x=np.float64(5.8429149156003e-05), courant_y=np.float64(0.03979999999999999)\n", + "x_dim_advector.shape=(82, 200), self.a_dim_advector.shape=(81, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=5000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "ff0f688caef049d3a9ccae0a87f7309d" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 88.09815859794617\n", + "Numeric price: 3.156410250692144\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "81it [03:24, 2.52s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 204.52555775642395\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T17:42:49.737970\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T17:42:50.130851\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "a95e1b5c78e34c19ac16c897577594cc" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 3.106\n", + "Numeric price: 3.156410250692144\n", + "MC price: 3.0561261961139525\n" + ] + } + ], + "execution_count": 19 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### T = 0.5", + "id": "d74195468d0156a7" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T17:56:25.637274Z", + "start_time": "2025-03-27T17:50:44.027003Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 10.425,\n", + " }\n", + "run_numeric_and_mc(params, nx=81, ny=200, nt=5000)" + ], + "id": "cbcdaa281b101c44", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(18.307156451691856)\n", + "CFL 0.03991685829831199\n", + "courant_x=np.float64(0.000116858298312006), courant_y=np.float64(0.03979999999999999)\n", + "x_dim_advector.shape=(82, 200), self.a_dim_advector.shape=(81, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=5000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "4923dffe253544768d5f2ff0ae8ea5ca" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 124.03241348266602\n", + "Numeric price: 10.446123536926867\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "81it [03:36, 2.68s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 216.9741814136505\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T18:56:25.197686\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T18:56:25.585083\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "e494bbdd89054bf1b5a47d5e41a1602d" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 10.425\n", + "Numeric price: 10.446123536926867\n", + "MC price: 10.313906034050241\n" + ] + } + ], + "execution_count": 23 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T18:05:24.792839Z", + "start_time": "2025-03-27T18:00:23.247430Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 7.650,\n", + " }\n", + "run_numeric_and_mc(params, nx=81, ny=200, nt=5000)" + ], + "id": "83cb6b2aef167c6f", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(18.307156451691856)\n", + "CFL 0.03991685829831199\n", + "courant_x=np.float64(0.000116858298312006), courant_y=np.float64(0.03979999999999999)\n", + "x_dim_advector.shape=(82, 200), self.a_dim_advector.shape=(81, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=5000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "6ca8392ef8e04569818e4f6c454d8447" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 131.24387907981873\n", + "Numeric price: 7.68451177587822\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "81it [02:49, 2.10s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 169.76302123069763\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T19:05:24.420090\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T19:05:24.750412\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "ff0b84562736493383840f47365e4f7e" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 7.65\n", + "Numeric price: 7.68451177587822\n", + "MC price: 7.509663741280927\n" + ] + } + ], + "execution_count": 25 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T18:20:16.030486Z", + "start_time": "2025-03-27T18:15:17.676829Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 5.444,\n", + " }\n", + "run_numeric_and_mc(params, nx=81, ny=150, nt=5000)" + ], + "id": "618aa5856e76f4e5", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(18.307156451691856)\n", + "CFL 0.02991685829831199\n", + "courant_x=np.float64(0.000116858298312006), courant_y=np.float64(0.029799999999999986)\n", + "x_dim_advector.shape=(82, 150), self.a_dim_advector.shape=(81, 151)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=5000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "a8df6e85942b4dc4ad7e5ca3a86d665e" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 124.118656873703\n", + "Numeric price: 5.49905668963933\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "81it [02:53, 2.14s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 173.67766666412354\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T19:20:15.637416\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-27T19:20:15.986744\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "46fed5f456924318804be74c1cee52bf" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 5.444\n", + "Numeric price: 5.49905668963933\n", + "MC price: 5.33228621554954\n" + ] + } + ], + "execution_count": 27 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### T = 1", + "id": "ece94a1114edc4f1" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T23:18:11.529092Z", + "start_time": "2025-03-27T23:14:31.838909Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 13.825,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=102, nt=4000)" + ], + "id": "f4e77b5c91a1b848", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.70986191469661)\n", + "CFL 0.025614280497824455\n", + "courant_x=np.float64(0.00036428049782446316), courant_y=np.float64(0.02524999999999999)\n", + "x_dim_advector.shape=(102, 102), self.a_dim_advector.shape=(101, 103)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=4000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "33b7ffef128b429295b9db77ea359f34" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 13.946833848953247\n", + "Numeric price: 13.855097055660202\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:25, 2.03s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 205.22511911392212\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-28T00:18:11.171144\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-28T00:18:11.488218\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "91c5f0387ee444c69b17abf8e05c4262" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 13.825\n", + "Numeric price: 13.855097055660202\n", + "MC price: 13.741926903990185\n" + ] + } + ], + "execution_count": 58 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T23:31:16.203398Z", + "start_time": "2025-03-27T23:27:35.109870Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 11.213,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=102, nt=4000)" + ], + "id": "6d0154d9d4b75069", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.70986191469661)\n", + "CFL 0.025614280497824455\n", + "courant_x=np.float64(0.00036428049782446316), courant_y=np.float64(0.02524999999999999)\n", + "x_dim_advector.shape=(102, 102), self.a_dim_advector.shape=(101, 103)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=4000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "1cfa6e5be38f40d2b07bed785ac726fd" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 14.22810673713684\n", + "Numeric price: 11.271253489580493\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:25, 2.03s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 205.29935455322266\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-28T00:31:14.793368\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-28T00:31:16.159022\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "66d0385b072d4dae9708032d2af242ae" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 11.213\n", + "Numeric price: 11.271253489580493\n", + "MC price: 11.105145084505846\n" + ] + } + ], + "execution_count": 63 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-03-27T23:25:25.123618Z", + "start_time": "2025-03-27T23:21:16.584332Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 8.989,\n", + " }\n", + "run_numeric_and_mc(params, nx=101, ny=102, nt=4000)" + ], + "id": "70c80819bda8d7fd", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.70986191469661)\n", + "CFL 0.025614280497824455\n", + "courant_x=np.float64(0.00036428049782446316), courant_y=np.float64(0.02524999999999999)\n", + "x_dim_advector.shape=(102, 102), self.a_dim_advector.shape=(101, 103)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=4000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "f195e833262e43ef89b430a936450169" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 43.496519804000854\n", + "Numeric price: 9.069009024996241\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "101it [03:24, 2.03s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 204.53332710266113\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-28T00:25:24.768892\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-03-28T00:25:25.083821\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "ebd813580475469f8d161bb3a9241867" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 8.989\n", + "Numeric price: 9.069009024996241\n", + "MC price: 8.870991019686969\n" + ] + } + ], + "execution_count": 61 + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "# Put", + "id": "e7c702571468505d" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "## sigma = 0.1", + "id": "765ab07eb7f0609f" + }, + { + "metadata": {}, + "cell_type": "markdown", + "source": "### T = 0.25", + "id": "6133f7a8558a940f" + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T17:30:03.070793Z", + "start_time": "2025-04-03T17:21:35.900702Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 0.013,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=400, nt=1500, variant='put')" + ], + "id": "a6879f539e3f08fa", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(28.827180835092065)\n", + "CFL 0.2682842671480741\n", + "courant_x=np.float64(0.0022842671480741926), courant_y=np.float64(0.2659999999999999)\n", + "x_dim_advector.shape=(201, 400), self.a_dim_advector.shape=(200, 401)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "69835be2bb784a3baac7c0516026ab52" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 6.664181470870972\n", + "Numeric price: 0.012777092496087496\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [08:19, 2.50s/it]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 499.4820206165314\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T19:30:02.601670\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T19:30:03.024545\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "82041a72dc074de8b44f5f3e3541739e" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 0.013\n", + "Numeric price: 0.012777092496087496\n", + "MC price: 0.01365262309322565\n" + ] + } + ], + "execution_count": 4 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T17:50:41.456100Z", + "start_time": "2025-04-03T17:43:46.583823Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 0.624,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=400, nt=1500, variant='put')" + ], + "id": "8f1825eb35850b1e", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(28.827180835092065)\n", + "CFL 0.2682842671480741\n", + "courant_x=np.float64(0.0022842671480741926), courant_y=np.float64(0.2659999999999999)\n", + "x_dim_advector.shape=(201, 400), self.a_dim_advector.shape=(200, 401)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "2c21c03b8d104b459e9e7ce6045e60ee" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 6.321263790130615\n", + "Numeric price: 0.6334633046164623\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:47, 2.04s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 407.8348774909973\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T19:50:40.999673\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T19:50:41.405323\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "b11f85feee734f7586b489a724555175" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 0.624\n", + "Numeric price: 0.6334633046164623\n", + "MC price: 0.6323299958269782\n" + ] + } + ], + "execution_count": 7 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T17:43:46.507598Z", + "start_time": "2025-04-03T17:36:54.416152Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 3.785,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=400, nt=1500, variant='put')" + ], + "id": "b047bb5b906d33da", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(28.827180835092065)\n", + "CFL 0.2682842671480741\n", + "courant_x=np.float64(0.0022842671480741926), courant_y=np.float64(0.2659999999999999)\n", + "x_dim_advector.shape=(201, 400), self.a_dim_advector.shape=(200, 401)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "f0d8a2fac6da49099e4318e53ce92cc7" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 7.746179103851318\n", + "Numeric price: 3.7982460605446993\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:43, 2.02s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 403.66155552864075\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T19:43:46.074273\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T19:43:46.458584\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "dfae81fb287f496d8ed7d4d78daafd4c" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 3.785\n", + "Numeric price: 3.7982460605446993\n", + "MC price: 3.7986762148465387\n" + ] + } + ], + "execution_count": 6 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T18:23:15.060348Z", + "start_time": "2025-04-03T18:14:44.635090Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 0.046,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "24b70a81d53bc15c", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(9.609060278364021)\n", + "CFL 0.2058528014442225\n", + "courant_x=np.float64(0.006852801444222578), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "57db5f4b0f7b4fd19273409a286b3c69" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 3.602018356323242\n", + "Numeric price: 0.04714652063297036\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [08:26, 2.53s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 506.1392478942871\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T20:23:14.629466\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T20:23:15.010907\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "76f38e96d8fa4f1fb1e07b131d07faeb" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 0.046\n", + "Numeric price: 0.04714652063297036\n", + "MC price: 0.045951004279038324\n" + ] + } + ], + "execution_count": 16 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T18:30:00.562636Z", + "start_time": "2025-04-03T18:23:15.077769Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 0.655,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "3137c1eae983f9d9", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(9.609060278364021)\n", + "CFL 0.2058528014442225\n", + "courant_x=np.float64(0.006852801444222578), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "454ae4f2e4a344c2b18169bec626956c" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 3.191105604171753\n", + "Numeric price: 0.6755355343517594\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:41, 2.01s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 401.8144726753235\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T20:30:00.331889\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T20:30:00.534310\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "a9d5bedb33784ae7b70ae9900e48a904" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 0.655\n", + "Numeric price: 0.6755355343517594\n", + "MC price: 0.6604116374657183\n" + ] + } + ], + "execution_count": 17 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T18:36:45.731523Z", + "start_time": "2025-04-03T18:30:00.605466Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 3.039,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "6201d6146d87ca30", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(9.609060278364021)\n", + "CFL 0.2058528014442225\n", + "courant_x=np.float64(0.006852801444222578), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "6a7c00aed054410b84ea5f971f30e9cf" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 2.9280269145965576\n", + "Numeric price: 3.0719973370261897\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:41, 2.01s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 401.4987404346466\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T20:36:45.291639\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T20:36:45.683577\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "9bf12df695ba467b94a4a6e4686f4511" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 3.039\n", + "Numeric price: 3.0719973370261897\n", + "MC price: 3.0577108775345474\n" + ] + } + ], + "execution_count": 18 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T19:24:31.602532Z", + "start_time": "2025-04-03T19:17:40.596199Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 0.084,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "d761be92374c7c9e", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.8045301391820106)\n", + "CFL 0.2127056028884451\n", + "courant_x=np.float64(0.013705602888445157), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "4f1444e9c9b8482e9901ed3da144d5ed" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 4.371012449264526\n", + "Numeric price: 0.08053257256841188\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:45, 2.03s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 405.68738079071045\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:24:31.180578\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:24:31.555351\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "3b9831deee3e4396872b13e64910446e" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 0.084\n", + "Numeric price: 0.08053257256841188\n", + "MC price: 0.08365062591258933\n" + ] + } + ], + "execution_count": 19 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T19:31:24.833276Z", + "start_time": "2025-04-03T19:24:31.621082Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 0.57,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "aeb07c1985a6fb5c", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.8045301391820106)\n", + "CFL 0.2127056028884451\n", + "courant_x=np.float64(0.013705602888445157), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "8b392daa4c024172be242770f3890025" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 3.9839422702789307\n", + "Numeric price: 0.5750143496096317\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:48, 2.04s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 408.5220260620117\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:31:24.406079\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:31:24.784863\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "57d129cb75384b55a810c2559d862b31" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 0.57\n", + "Numeric price: 0.5750143496096317\n", + "MC price: 0.5753349569020421\n" + ] + } + ], + "execution_count": 20 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T19:38:19.067126Z", + "start_time": "2025-04-03T19:31:24.909912Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 2.137,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "9fe9039928c0126", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.8045301391820106)\n", + "CFL 0.2127056028884451\n", + "courant_x=np.float64(0.013705602888445157), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "b7e513ec931c4604b40cbde99d684137" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 4.279627084732056\n", + "Numeric price: 2.1450968025220645\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:49, 2.05s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 409.1793339252472\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:38:18.630121\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:38:19.018103\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "0ae39c92b2e3433c86757ed93a728cab" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 2.137\n", + "Numeric price: 2.1450968025220645\n", + "MC price: 2.1386287843157326\n" + ] + } + ], + "execution_count": 21 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T19:45:42.086062Z", + "start_time": "2025-04-03T19:38:49.464195Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 0.379,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "5d9b500b2fbb4548", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.8045301391820106)\n", + "CFL 0.20188539008177786\n", + "courant_x=np.float64(0.0028853900817779276), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "7e286a314f7444499247a0e4f4c73a86" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 4.27038311958313\n", + "Numeric price: 0.3740327567428815\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:47, 2.04s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 407.6851451396942\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:45:41.682205\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:45:42.039424\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "a051cb5fe85144bbac7d26e953c791bd" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 0.379\n", + "Numeric price: 0.3740327567428815\n", + "MC price: 0.3733092120408695\n" + ] + } + ], + "execution_count": 22 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T19:52:34.902447Z", + "start_time": "2025-04-03T19:45:42.104287Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 1.716,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "8d29256e05b3294a", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.8045301391820106)\n", + "CFL 0.20188539008177786\n", + "courant_x=np.float64(0.0028853900817779276), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "ddeb9bc41dca4c189d54575524d630d6" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 3.062779664993286\n", + "Numeric price: 1.7168248614894328\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:48, 2.04s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 408.72767972946167\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:52:34.174815\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:52:34.851640\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "f64f9ddc842a4171bb1cf436322bd1c7" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 1.716\n", + "Numeric price: 1.7168248614894328\n", + "MC price: 1.7003910478009128\n" + ] + } + ], + "execution_count": 23 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T19:59:30.398262Z", + "start_time": "2025-04-03T19:52:34.919737Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 4.598,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "dce48286dcee4438", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.8045301391820106)\n", + "CFL 0.20188539008177786\n", + "courant_x=np.float64(0.0028853900817779276), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "a10d2e1af2244cd7b40c135bce3361e8" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 3.274336814880371\n", + "Numeric price: 4.6072760593822935\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:51, 2.06s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 411.5004634857178\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:59:29.973757\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T21:59:30.349623\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "f1b6a54cd68f40e7865911435dad5c2a" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 4.598\n", + "Numeric price: 4.6072760593822935\n", + "MC price: 4.591024402240118\n" + ] + } + ], + "execution_count": 24 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T20:06:47.650821Z", + "start_time": "2025-04-03T19:59:48.776411Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 0.731,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "c7e21c29dd1e3035", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(2.4022650695910053)\n", + "CFL 0.2047707801635558\n", + "courant_x=np.float64(0.005770780163555855), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "9e9137afd7c14984843a5ace498d9298" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 5.372064113616943\n", + "Numeric price: 0.7168363286287819\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:52, 2.06s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 412.8026759624481\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T22:06:47.211536\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T22:06:47.601112\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "198953da5fc448688fc267d8870e2216" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 0.731\n", + "Numeric price: 0.7168363286287819\n", + "MC price: 0.7197278961738409\n" + ] + } + ], + "execution_count": 25 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T20:13:46.011353Z", + "start_time": "2025-04-03T20:06:47.730938Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 2.102,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "195ef5b8625531d0", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(2.4022650695910053)\n", + "CFL 0.2047707801635558\n", + "courant_x=np.float64(0.005770780163555855), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "b679fbe6f2ef4bcaa1cc46b86a581764" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 3.4919865131378174\n", + "Numeric price: 2.089890853749037\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:54, 2.07s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 414.0727949142456\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T22:13:45.554306\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T22:13:45.963469\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "b9a075a7f322477387b2a3a078407da9" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 2.102\n", + "Numeric price: 2.089890853749037\n", + "MC price: 2.101859714787861\n" + ] + } + ], + "execution_count": 26 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T20:20:48.039519Z", + "start_time": "2025-04-03T20:13:46.028191Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 4.552,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=1000, variant='put')" + ], + "id": "2beb64a8761c2ffb", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(2.4022650695910053)\n", + "CFL 0.2047707801635558\n", + "courant_x=np.float64(0.005770780163555855), courant_y=np.float64(0.19899999999999993)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=1000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "7ef3c6d4c2c5477fa6ddb8b791b6c06a" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 5.2422919273376465\n", + "Numeric price: 4.549458487332414\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:55, 2.08s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 415.7400801181793\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T22:20:47.604232\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T22:20:47.989492\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "2bc1e26d3fb740899648f66fa831281a" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 4.552\n", + "Numeric price: 4.549458487332414\n", + "MC price: 4.543542058806283\n" + ] + } + ], + "execution_count": 27 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T20:40:20.144690Z", + "start_time": "2025-04-03T20:33:16.575791Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 1.099,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=4000, variant='put')" + ], + "id": "1ab5d24bed57fbbc", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.8045301391820106)\n", + "CFL 0.05263539008177791\n", + "courant_x=np.float64(0.0028853900817779276), courant_y=np.float64(0.04974999999999998)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=4000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "11c0b003f82b463fa1d6f572d931e650" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 13.12001085281372\n", + "Numeric price: 1.091816171172086\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:49, 2.05s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 409.79074001312256\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T22:40:19.756288\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T22:40:20.100887\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "47669b56f9ce46009c11bb8b900d82d6" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 1.099\n", + "Numeric price: 1.091816171172086\n", + "MC price: 1.0952014916721646\n" + ] + } + ], + "execution_count": 30 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T20:47:23.975288Z", + "start_time": "2025-04-03T20:40:20.161997Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 2.369,\n", + " }\n", + "run_numeric_and_mc(params, nx=200, ny=200, nt=4000, variant='put')" + ], + "id": "1ecbf52413dce2f9", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.8045301391820106)\n", + "CFL 0.05263539008177791\n", + "courant_x=np.float64(0.0028853900817779276), courant_y=np.float64(0.04974999999999998)\n", + "x_dim_advector.shape=(201, 200), self.a_dim_advector.shape=(200, 201)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=4000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "394dfea203244d19828c9b505c75d5dd" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 11.763642311096191\n", + "Numeric price: 2.3687731171065307\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "200it [06:51, 2.06s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 411.293240070343\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T22:47:23.495072\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T22:47:23.922467\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "04625866221a48ff996bc9b950e329dd" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 2.369\n", + "Numeric price: 2.3687731171065307\n", + "MC price: 2.3843194242655525\n" + ] + } + ], + "execution_count": 31 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T21:00:19.456738Z", + "start_time": "2025-04-03T20:55:45.087384Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.2,\n", + " 'spot': 100,\n", + " 'true_price': 4.356,\n", + " }\n", + "run_numeric_and_mc(params, nx=100, ny=100, nt=2000, variant='put')" + ], + "id": "e6641557f07a5ac6", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(9.609060278364021)\n", + "CFL 0.05238539008177791\n", + "courant_x=np.float64(0.0028853900817779276), courant_y=np.float64(0.04949999999999998)\n", + "x_dim_advector.shape=(101, 100), self.a_dim_advector.shape=(100, 101)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "a4acc4cbed3841d48b4c88874e53031a" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 7.309493780136108\n", + "Numeric price: 4.384219700518613\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100it [04:26, 2.66s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 266.4030833244324\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:00:19.060374\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:00:19.412679\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "b0350a03d9934fec93a4693a03f10ac3" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 4.356\n", + "Numeric price: 4.384219700518613\n", + "MC price: 4.3771623201897985\n" + ] + } + ], + "execution_count": 36 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T21:05:13.690864Z", + "start_time": "2025-04-03T21:00:45.683713Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 2.025,\n", + " }\n", + "run_numeric_and_mc(params, nx=100, ny=100, nt=2000, variant='put')" + ], + "id": "8b815d7e7cc4b43", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(9.609060278364021)\n", + "CFL 0.0496803368801111\n", + "courant_x=np.float64(0.0001803368801111204), courant_y=np.float64(0.04949999999999998)\n", + "x_dim_advector.shape=(101, 100), self.a_dim_advector.shape=(100, 101)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "109df02928f54799962d243bf5fdc55b" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 7.278459310531616\n", + "Numeric price: 2.0304778925736913\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100it [04:20, 2.60s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 260.01831245422363\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:05:13.265425\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:05:13.643310\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "cbc6fb1c07824d89bbb2db300c66c6d8" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 2.025\n", + "Numeric price: 2.0304778925736913\n", + "MC price: 2.0108483926750895\n" + ] + } + ], + "execution_count": 37 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T21:08:50.305252Z", + "start_time": "2025-04-03T21:05:13.826439Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 3.970,\n", + " }\n", + "run_numeric_and_mc(params, nx=100, ny=100, nt=2000, variant='put')" + ], + "id": "922b9299a258ef4c", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(9.609060278364021)\n", + "CFL 0.0496803368801111\n", + "courant_x=np.float64(0.0001803368801111204), courant_y=np.float64(0.04949999999999998)\n", + "x_dim_advector.shape=(101, 100), self.a_dim_advector.shape=(100, 101)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "a0a8d1475db54490a7426307e652bf46" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 7.520007610321045\n", + "Numeric price: 3.986590613609267\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100it [03:28, 2.08s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 208.2283284664154\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:08:49.867076\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:08:50.255599\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "f4f71064ce43463d99cc9fdc25ee6fb6" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 3.97\n", + "Numeric price: 3.986590613609267\n", + "MC price: 3.9496294886658645\n" + ] + } + ], + "execution_count": 38 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T21:34:32.720890Z", + "start_time": "2025-04-03T21:30:57.479300Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 6.735,\n", + " }\n", + "run_numeric_and_mc(params, nx=100, ny=100, nt=2000, variant='put')" + ], + "id": "8482fda398e49686", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(9.609060278364021)\n", + "CFL 0.0496803368801111\n", + "courant_x=np.float64(0.0001803368801111204), courant_y=np.float64(0.04949999999999998)\n", + "x_dim_advector.shape=(101, 100), self.a_dim_advector.shape=(100, 101)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "0c34513700404245977600537148a179" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 8.734480857849121\n", + "Numeric price: 6.759513851662983\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100it [03:25, 2.06s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 205.83200311660767\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:34:32.334604\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:34:32.677217\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "cfb782d702ad4636b568df68e4b98f01" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 6.735\n", + "Numeric price: 6.759513851662983\n", + "MC price: 6.734118515613793\n" + ] + } + ], + "execution_count": 39 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T21:38:56.990540Z", + "start_time": "2025-04-03T21:34:32.735726Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 3.215,\n", + " }\n", + "run_numeric_and_mc(params, nx=100, ny=100, nt=2000, variant='put')" + ], + "id": "4c9f007125cf6329", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.8045301391820106)\n", + "CFL 0.04986067376022222\n", + "courant_x=np.float64(0.0003606737602222408), courant_y=np.float64(0.04949999999999998)\n", + "x_dim_advector.shape=(101, 100), self.a_dim_advector.shape=(100, 101)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "4e18ac41128a44c49d8aa7a00ea9b6f8" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 5.330230474472046\n", + "Numeric price: 3.2105192313337465\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100it [04:18, 2.58s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 258.2690587043762\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:38:56.597322\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:38:56.945482\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "af7d1fb8ce1a4312ae2e5815f43864d0" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 3.215\n", + "Numeric price: 3.2105192313337465\n", + "MC price: 3.1851930496141225\n" + ] + } + ], + "execution_count": 40 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T21:42:28.471241Z", + "start_time": "2025-04-03T21:38:57.005728Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 5.197,\n", + " }\n", + "\n", + "run_numeric_and_mc(params, nx=100, ny=100, nt=2000, variant='put')" + ], + "id": "ce46b8e72261dc36", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.8045301391820106)\n", + "CFL 0.04986067376022222\n", + "courant_x=np.float64(0.0003606737602222408), courant_y=np.float64(0.04949999999999998)\n", + "x_dim_advector.shape=(101, 100), self.a_dim_advector.shape=(100, 101)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "1b441cf4c4f14a06970093aa965354cc" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 5.508124113082886\n", + "Numeric price: 5.1993683015073335\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100it [03:25, 2.05s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 205.24198007583618\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:42:28.048846\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:42:28.423806\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "c5059096dfb04bd4a6e1edba08ef2a0c" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 5.197\n", + "Numeric price: 5.1993683015073335\n", + "MC price: 5.183080870225042\n" + ] + } + ], + "execution_count": 41 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T21:46:01.989889Z", + "start_time": "2025-04-03T21:42:28.485698Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 0.5,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 7.748,\n", + " }\n", + "run_numeric_and_mc(params, nx=100, ny=100, nt=2000, variant='put')" + ], + "id": "3699a52955b4163b", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(4.8045301391820106)\n", + "CFL 0.04986067376022222\n", + "courant_x=np.float64(0.0003606737602222408), courant_y=np.float64(0.04949999999999998)\n", + "x_dim_advector.shape=(101, 100), self.a_dim_advector.shape=(100, 101)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2000)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "c9f85b73dceb4c2eaf034e883d8016ec" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 5.683553457260132\n", + "Numeric price: 7.757526964435898\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100it [03:27, 2.07s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 207.13279509544373\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:46:01.592350\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-03T23:46:01.945501\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "a346bde549f74910bb627e9c031a8811" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 7.748\n", + "Numeric price: 7.757526964435898\n", + "MC price: 7.71713657467501\n" + ] + } + ], + "execution_count": 42 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T22:25:54.095253Z", + "start_time": "2025-04-03T22:22:20.054547Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 4.550,\n", + " }\n", + "run_numeric_and_mc(params, nx=100, ny=100, nt=2420, variant='put')" + ], + "id": "91c6579d9e6109f5", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(2.906740734205117)\n", + "CFL 0.04150524588466484\n", + "courant_x=np.float64(0.0005961549755739516), courant_y=np.float64(0.04090909090909089)\n", + "x_dim_advector.shape=(101, 100), self.a_dim_advector.shape=(100, 101)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2420)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "2b28eb827b964714a72ce2b5b2ebd814" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 7.470585584640503\n", + "Numeric price: 4.5385899957267295\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100it [03:25, 2.06s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 205.91660904884338\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-04T00:25:53.709844\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-04T00:25:54.050718\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "9312eaf2ecfe47e38b2b4e055abcbd54" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 4.55\n", + "Numeric price: 4.5385899957267295\n", + "MC price: 4.510373825622241\n" + ] + } + ], + "execution_count": 53 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T22:30:54.792029Z", + "start_time": "2025-04-03T22:27:19.932605Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 100,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 6.465,\n", + " }\n", + "run_numeric_and_mc(params, nx=100, ny=100, nt=2300, variant='put')" + ], + "id": "7687628eff927aa3", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(2.762604830029656)\n", + "CFL 0.04367073697429953\n", + "courant_x=np.float64(0.0006272587134299839), courant_y=np.float64(0.043043478260869544)\n", + "x_dim_advector.shape=(101, 100), self.a_dim_advector.shape=(100, 101)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2300)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "536dba7cbe7547508b2698f0c67813ae" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 6.921475172042847\n", + "Numeric price: 6.64812954364324\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100it [03:27, 2.07s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 207.30976152420044\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-04T00:30:54.428063\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-04T00:30:54.749798\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "1058846cfa3541418aef6bcb1bb6e32e" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 6.465\n", + "Numeric price: 6.64812954364324\n", + "MC price: 6.462341731633215\n" + ] + } + ], + "execution_count": 55 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-03T22:34:54.728754Z", + "start_time": "2025-04-03T22:31:20.100281Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 105,\n", + " 'r': 0.1,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 8.767,\n", + " }\n", + "run_numeric_and_mc(params, nx=100, ny=100, nt=2600, variant='put')" + ], + "id": "a90878e280b5b003", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=np.float64(3.122944590468307)\n", + "CFL 0.03863180578495727\n", + "courant_x=np.float64(0.0005548827080342166), courant_y=np.float64(0.03807692307692306)\n", + "x_dim_advector.shape=(101, 100), self.a_dim_advector.shape=(100, 101)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=2600)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "bb0fc37ae848453d8c84514de10d1180" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 8.134722471237183\n", + "Numeric price: 8.812782369694158\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "100it [03:25, 2.06s/it]" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 205.79937505722046\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-04T00:34:54.333908\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic.pdf" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-04T00:34:54.684843\n image/svg+xml\n \n \n Matplotlib v3.10.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\"./numeric_vs_analytic_err…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "3f1c927e568940b9ac49af72f77c0a97" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 8.767\n", + "Numeric price: 8.812782369694158\n", + "MC price: 8.73132536932032\n" + ] + } + ], + "execution_count": 57 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-25T12:36:15.615904Z", + "start_time": "2025-04-25T12:36:15.599913Z" + } + }, + "cell_type": "code", + "source": [ + "def plot_solution(\n", + " settings,\n", + " frame_index,\n", + " ax,\n", + " history,\n", + " S_linspace,\n", + " arithmetic_by_mc,\n", + " arithmetic_by_mc_std,\n", + " option_type: str,\n", + " variant,\n", + " A_space,\n", + " S_space\n", + "):\n", + " params = {\n", + " k: v for k, v in settings.params.__dict__.items() if not k.startswith(\"K\")\n", + " }\n", + " if variant == \"call\":\n", + " BS_price_func = Black_Scholes_1973.c_euro\n", + " Amer_price_func = Bjerksund_and_Stensland_1993.c_amer\n", + " geometric_price_func = asian_analytic.geometric_asian_average_price_c\n", + " else:\n", + " BS_price_func = Black_Scholes_1973.p_euro\n", + " Amer_price_func = Bjerksund_and_Stensland_1993.p_amer\n", + " geometric_price_func = asian_analytic.geometric_asian_average_price_p\n", + " range_lower, range_upper = 80, 120\n", + " s_indexes_within_range = [i for i, v in enumerate(S_linspace) if range_lower<=v<=range_upper]\n", + " # s_indexes_within_range = [i for i, v in enumerate(S_linspace)]\n", + " ax.plot(\n", + " S_linspace[s_indexes_within_range],\n", + " (\n", + " BS_price_func(\n", + " S=S_linspace[s_indexes_within_range], K=settings.params.K, **params, b=settings.params.r\n", + " )\n", + " ),\n", + " label=\"European analytic (Black-Scholes '73)\",\n", + " linestyle=\"--\",\n", + " alpha=0.5,\n", + " c=\"black\"\n", + " )\n", + " # ax.plot(\n", + " # S_linspace,\n", + " # (\n", + " # Amer_price_func(\n", + " # S=S_linspace, K=settings.params.K, **params, b=settings.params.r\n", + " # )\n", + " # ),\n", + " # label=\"American analytic (Bjerksund & Stensland '93)\", linestyle='--'\n", + " # )\n", + " \n", + " # print(settings.rh[:-1].shape)\n", + " # print(history[frame_index][0,:].shape)\n", + " ax.bar(\n", + " S_space[:-1][s_indexes_within_range],\n", + " history[frame_index][:, 0][s_indexes_within_range],\n", + " width=S_space[1:][s_indexes_within_range] - S_space[:-1][s_indexes_within_range],\n", + " # label=f\"MPDATA solution ({option_type})\",\n", + " alpha=0.3,\n", + " align=\"edge\",\n", + " color=\"orange\"\n", + " )\n", + " # ax.bar(\n", + " # settings.rh[:-1],\n", + " # history[0][0,:],\n", + " # width=settings.rh[1:] - settings.rh[:-1],\n", + " # label=f\"Terminal condition (discounted payoff)\",\n", + " # alpha=0.5,\n", + " # align=\"edge\"\n", + " # )\n", + " ax.plot(\n", + " S_linspace[s_indexes_within_range],\n", + " history[frame_index][:, 0][s_indexes_within_range],\n", + " label=f\"Asian arithmetic MPDATA solution\",\n", + " marker=\".\",\n", + " # alpha=0.7,\n", + " c=\"orange\"\n", + " )\n", + " \n", + " ax.plot(\n", + " S_linspace[s_indexes_within_range],\n", + " arithmetic_by_mc[s_indexes_within_range],\n", + " # arithmetic_by_mc_std[s_indexes_within_range],\n", + " label=\"Asian arithmetic by Monte-Carlo\",\n", + " # linestyle=\":\",\n", + " marker=\"+\",\n", + " # alpha=0.5,\n", + " c=\"blue\"\n", + " )\n", + " ax.plot(\n", + " S_linspace[s_indexes_within_range],\n", + " (\n", + " geometric_price_func(\n", + " S=S_linspace[s_indexes_within_range], K=settings.params.K, **params, dividend_yield=0\n", + " )\n", + " ),\n", + " label=\"Asian geometric analytic (Kemna & Vorst 1990)\",\n", + " # alpha=0.5,\n", + " linestyle=\"--\",\n", + " c=\"green\"\n", + " )\n", + " # ax.plot(\n", + " # A_space,\n", + " # history[0][0, :],\n", + " # label=f\"Terminal condition (discounted payoff)\",\n", + " # marker=\".\",\n", + " # alpha=0.5,\n", + " # )\n", + " ax2 = ax.twinx()\n", + " # on ax2 plot discretized ticks x/Δx\n", + " ax2.set_xticks(np.arange(0, len(settings.rh), 5))\n", + " ax.legend(loc=\"upper left\")\n", + " ax.grid()\n", + " minmax = (np.amin(history[0]), np.amax(history[0]))\n", + " span = minmax[1] - minmax[0]\n", + " # ax.set_ylim(minmax[0] - 0.05 * span, minmax[1] + 0.25 * span)\n", + " # ax.set_title(f\"Asian option valuation for: {settings.params.__dict__}\")\n", + " # ax.set_xlabel(\"underlying S(t=0)=A(t=0) (and A(T) for terminal condition)\")\n", + " # ax.set_xlabel(\"average at t=T for payoff, spot at t=0 for other datasets\")\n", + " ax.set_xlabel(\"spot price at t=0 ($)\")\n", + " ax.set_ylabel(\"instrument value ($)\")" + ], + "id": "595d954c5ec0007b", + "outputs": [], + "execution_count": 71 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-25T12:37:15.261Z", + "start_time": "2025-04-25T12:37:08.333461Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 100,\n", + " 'r': 0.08,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 8.767,\n", + " }\n", + "run_numeric_and_mc(params, nx=21, ny=31, nt=500, variant='call')" + ], + "id": "e911818f257299a2", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=13.618282707432003\n", + "CFL 0.05999999999999997\n", + "courant_x=4.20449728625708e-19, courant_y=0.05999999999999997\n", + "x_dim_advector.shape=(22, 31), self.a_dim_advector.shape=(21, 32)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "a23d7e8dffe041a8bc07b1b4a392dbe2" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 6.000473976135254\n", + "Numeric price: 11.590865261368332\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-25T14:37:15.193000\n image/svg+xml\n \n \n Matplotlib v3.7.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\".\\\\numeric_vs_analytic.pdf…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "f759f0679a8f4f3c86405c8eb4278112" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 8.767\n", + "Numeric price: 11.590865261368332\n" + ] + } + ], + "execution_count": 74 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-23T10:19:03.562252Z", + "start_time": "2025-04-23T10:17:59.248158Z" + } + }, + "cell_type": "code", + "source": [ + "params = {\n", + " 'T': 1,\n", + " 'K': 100,\n", + " 'r': 0.08,\n", + " 'sgma': 0.4,\n", + " 'spot': 100,\n", + " 'true_price': 8.767,\n", + " }\n", + "run_numeric_and_mc(params, nx=21, ny=31, nt=500, variant='call')" + ], + "id": "b7f313c735acdc50", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=13.618282707432003\n", + "CFL 0.05999999999999997\n", + "courant_x=4.20449728625708e-19, courant_y=0.05999999999999997\n", + "x_dim_advector.shape=(22, 31), self.a_dim_advector.shape=(21, 32)\n" + ] + }, + { + "data": { + "text/plain": [ + "IntProgress(value=0, max=500)" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "00e7ddd6919d4d6d9cfde8ae1a94e65a" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MPDATA elapsed time: 5.8242504596710205\n", + "Numeric price: 11.590816454795288\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "21it [00:57, 2.75s/it]\n" + ] + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "MC elapsed time: 57.6473867893219\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-23T12:19:03.488250\n image/svg+xml\n \n \n Matplotlib v3.7.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\".\\\\numeric_vs_analytic.pdf…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "5a1bb6506e2f4602870eeeba161b189a" + } + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "name": "stdout", + "output_type": "stream", + "text": [ + "True price: 8.767\n", + "Numeric price: 11.590816454795288\n" + ] + } + ], + "execution_count": 40 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-25T12:32:24.101217Z", + "start_time": "2025-04-25T12:32:22.762320Z" + } + }, + "cell_type": "code", + "source": [ + "settings = Settings(T=params['T'], K=params['K'], r=params['r'], sgma=params['sgma'], S_max=200, S_min=50)\n", + "simulation = AsianArithmetic(settings, nx=21, ny=31, nt=1000, variant=\"call\")\n", + "\n", + "fig, ax = pyplot.subplots(1, 1, figsize=(10,6))\n", + "X = simulation.solver.advector.get_component(0)[:-1,:]\n", + "Y = simulation.solver.advector.get_component(1)[:,:-1]\n", + "grid = (X.shape[1], Y.shape[0])\n", + "scale_x, scale_y = np.amax(np.abs(X)), np.amax(np.abs(Y))\n", + "ax.quiver(*np.mgrid[\n", + " 1/2 : grid[0] : 1,\n", + " 1/2: grid[1] : 1,\n", + " ], Y.T.flatten()/0.8/scale_y, X.T.flatten()/scale_x, pivot='mid', color='green', width=.003,\n", + " label='price advector values at cell centers', scale=6, scale_units='inches'\n", + ")\n", + "\n", + "ax.axis('equal')\n", + "# ax.set_title(\"resulting advector values at cell centers fo Asian arithmetic call option\")\n", + "ax.set_xlabel('y/Δy')\n", + "ax.set_ylabel('x/Δx')\n", + "# ax.legend(bbox_to_anchor=(.1, -.1), loc='upper left', ncol=1)\n", + "for i, xy in enumerate(('x', 'y')):\n", + " getattr(ax, f\"set_{xy}ticks\")(np.arange(0, grid[i] + 1))\n", + "ax.grid()\n", + "show_plot('asian_arithmetic_advector.pdf')" + ], + "id": "7dd88e88ff7e474", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=27.236565414864007\n", + "CFL 0.029999999999999985\n", + "courant_x=2.10224864312854e-19, courant_y=0.029999999999999985\n", + "x_dim_advector.shape=(22, 31), self.a_dim_advector.shape=(21, 32)\n" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-25T14:32:23.969881\n image/svg+xml\n \n \n Matplotlib v3.7.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + }, + { + "data": { + "text/plain": [ + "HBox(children=(HTML(value=\".\\\\asian_arithmetic_adve…" + ], + "application/vnd.jupyter.widget-view+json": { + "version_major": 2, + "version_minor": 0, + "model_id": "a37fbc2af18343ea90119ef57cdfc0f9" + } + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 69 + }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-04-25T12:27:25.762144Z", + "start_time": "2025-04-25T12:27:14.108853Z" + } + }, + "cell_type": "code", + "source": [ + "settings = Settings(T=params['T'], K=params['K'], r=params['r'], sgma=params['sgma'], S_max=200, S_min=50)\n", + "simulation = AsianArithmetic(settings, nx=21, ny=31, nt=500, variant=\"call\")\n", + "\n", + "history = [simulation.solver.advectee.get().copy()]\n", + "for i in range(500):\n", + " res = simulation.step()\n", + "history.append(simulation.solver.advectee.get().copy())\n", + "for i in range(500):\n", + " res = simulation.step()\n", + "history.append(simulation.solver.advectee.get().copy())\n", + "\n", + "fig, ax = pyplot.subplots(3, 1, figsize=(10,8))\n", + "\n", + "ax[0].imshow(history[0], cmap='hot', interpolation='nearest', origin='lower', extent=(0, 31, 0, 21))\n", + "ax[0].set_title(\"terminal condition (t=T)\")\n", + "ax[1].imshow(history[1], cmap='hot', interpolation='nearest', origin='lower', extent=(0, 31, 0, 21))\n", + "ax[1].set_title(\"at t=T/2\")\n", + "ax[2].imshow(history[2], cmap='hot', interpolation='nearest', origin='lower', extent=(0, 31, 0, 21))\n", + "ax[2].set_title(\"at t=0\")\n", + "\n", + "ax[0].set_xlabel('y/Δy')\n", + "ax[1].set_xlabel('y/Δy')\n", + "ax[2].set_xlabel('y/Δy')\n", + "ax[0].set_ylabel('x/Δx')\n", + "ax[1].set_ylabel('x/Δx')\n", + "ax[2].set_ylabel('x/Δx')\n", + "\n", + "fig.colorbar(ax=ax[0], shrink=0.8, label='price advectee values at cell centers')\n", + "\n", + "# add colorbar\n", + "\n", + "fig.tight_layout()\n", + "\n", + "show_plot('advectee_over_time.pdf')" + ], + "id": "e3d021b74dcba062", + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "self.l2=13.618282707432003\n", + "CFL 0.05999999999999997\n", + "courant_x=4.20449728625708e-19, courant_y=0.05999999999999997\n", + "x_dim_advector.shape=(22, 31), self.a_dim_advector.shape=(21, 32)\n" + ] + }, + { + "ename": "TypeError", + "evalue": "FigureBase.colorbar() missing 1 required positional argument: 'mappable'", + "output_type": "error", + "traceback": [ + "\u001B[1;31m---------------------------------------------------------------------------\u001B[0m", + "\u001B[1;31mTypeError\u001B[0m Traceback (most recent call last)", + "Cell \u001B[1;32mIn[61], line 28\u001B[0m\n\u001B[0;32m 25\u001B[0m ax[\u001B[38;5;241m1\u001B[39m]\u001B[38;5;241m.\u001B[39mset_ylabel(\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mx/Δx\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[0;32m 26\u001B[0m ax[\u001B[38;5;241m2\u001B[39m]\u001B[38;5;241m.\u001B[39mset_ylabel(\u001B[38;5;124m'\u001B[39m\u001B[38;5;124mx/Δx\u001B[39m\u001B[38;5;124m'\u001B[39m)\n\u001B[1;32m---> 28\u001B[0m \u001B[43mfig\u001B[49m\u001B[38;5;241;43m.\u001B[39;49m\u001B[43mcolorbar\u001B[49m\u001B[43m(\u001B[49m\u001B[43max\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[43max\u001B[49m\u001B[43m[\u001B[49m\u001B[38;5;241;43m0\u001B[39;49m\u001B[43m]\u001B[49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mshrink\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;241;43m0.8\u001B[39;49m\u001B[43m,\u001B[49m\u001B[43m \u001B[49m\u001B[43mlabel\u001B[49m\u001B[38;5;241;43m=\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[38;5;124;43mprice advectee values at cell centers\u001B[39;49m\u001B[38;5;124;43m'\u001B[39;49m\u001B[43m)\u001B[49m\n\u001B[0;32m 30\u001B[0m \u001B[38;5;66;03m# add colorbar\u001B[39;00m\n\u001B[0;32m 32\u001B[0m fig\u001B[38;5;241m.\u001B[39mtight_layout()\n", + "\u001B[1;31mTypeError\u001B[0m: FigureBase.colorbar() missing 1 required positional argument: 'mappable'" + ] + }, + { + "data": { + "text/plain": [ + "
" + ], + "image/svg+xml": "\n\n\n \n \n \n \n 2025-04-25T14:27:25.671242\n image/svg+xml\n \n \n Matplotlib v3.7.1, https://matplotlib.org/\n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n \n\n" + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "execution_count": 61 + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": "", + "id": "48d086e0e753ec59" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/table_1_v2.ipynb b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/table_1_v2.ipynb new file mode 100644 index 00000000..f9c0149e --- /dev/null +++ b/examples/PyMPDATA_examples/Magnuszewski_et_al_2025/table_1_v2.ipynb @@ -0,0 +1,127 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "initial_id", + "metadata": { + "collapsed": true + }, + "outputs": [], + "source": [ + "# import os\n", + "# os.environ[\"NUMBA_DISABLE_JIT\"] = \"1\"\n", + "\n", + "from asian_option import AsianArithmetic, Settings, plot_solution, plot_difference_arithmetic\n", + "\n", + "import numpy as np\n", + "from matplotlib import pyplot\n", + "from ipywidgets import IntProgress\n", + "from tqdm import tqdm\n", + "\n", + "from open_atmos_jupyter_utils import show_plot, show_anim\n", + "from monte_carlo import BSModel, FixedStrikeGeometricAsianOption, FixedStrikeArithmeticAsianOption\n", + "import time" + ] + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": [ + "def run_numeric_and_mc(params, nx=31, ny=41, nt=300, variant='call'):\n", + " s_max = params.get('S_max', params['spot']*2)\n", + " s_min = params.get('S_min', params['spot']/2)\n", + " settings = Settings(T=params['T'], K=params['K'], r=params['r'], sgma=params['sgma'], S_max=s_max, S_min=s_min)\n", + " simulation = AsianArithmetic(settings, nx=nx, ny=ny, nt=nt, variant=variant)\n", + " \n", + " \n", + " history = []\n", + " progbar = IntProgress(max = simulation.nt)\n", + " display(progbar)\n", + " start = time.time()\n", + " for progbar.value in range(simulation.nt + 1):\n", + " if progbar.value != 0:\n", + " res = simulation.step()\n", + " history.append(simulation.solver.advectee.get().copy())\n", + " end = time.time()\n", + " print(f\"MPDATA elapsed time: {end - start}\")\n", + " print(f\"Numeric price: {np.interp(params['spot'], simulation.S, history[-1][:,0])}\")\n", + " start = time.time()\n", + " arithmetic_by_mc = np.zeros_like(simulation.S)\n", + " for idx, spot in tqdm(enumerate(simulation.S)):\n", + " model = BSModel(spot, settings.params.r, settings.params.sgma, settings.params.T, 1000)\n", + " arithmetic_option = FixedStrikeArithmeticAsianOption(settings.params.T, settings.params.K, variant, model, 100000)\n", + " arithmetic_by_mc[idx] = arithmetic_option.price_by_mc()\n", + " end = time.time()\n", + " print(f\"MC elapsed time: {end - start}\")\n", + " _, ax = pyplot.subplots(1, 1, figsize=(10, 5))\n", + " plot_solution(settings=settings,\n", + " frame_index=-1,\n", + " ax=ax,\n", + " history=history,\n", + " arithmetic_by_mc=arithmetic_by_mc,\n", + " S_linspace=simulation.S,\n", + " option_type='arithmetic call',\n", + " variant=variant)\n", + " show_plot('numeric_vs_analytic.pdf')\n", + " _, ax = pyplot.subplots(1, 1, figsize=(10, 5))\n", + " plot_difference_arithmetic(settings=settings,\n", + " frame_index=-1,\n", + " ax=ax,\n", + " history=history,\n", + " arithmetic_by_mc=arithmetic_by_mc,\n", + " S_linspace=simulation.S,\n", + " option_type=f'arithmetic {variant}')\n", + " show_plot('numeric_vs_analytic_error.pdf')\n", + " \n", + " print(f\"True price: {params['true_price']}\")\n", + " print(f\"Numeric price: {np.interp(params['spot'], simulation.S, history[-1][:,0])}\")\n", + " print(f\"MC price: {np.interp(params['spot'], simulation.S, arithmetic_by_mc)}\")" + ], + "id": "ca9aa67fdd306bf0" + }, + { + "metadata": {}, + "cell_type": "code", + "outputs": [], + "execution_count": null, + "source": [ + "params = {\n", + " 'T': 0.25,\n", + " 'K': 95,\n", + " 'r': 0.1,\n", + " 'sgma': 0.1,\n", + " 'spot': 100,\n", + " 'true_price': 6.132,\n", + " 'S_max': 120,\n", + " 'S_min': 80\n", + " }\n", + "run_numeric_and_mc(params, nx=121, ny=500, nt=1500)" + ], + "id": "5ba7647d2511c71c" + } + ], + "metadata": { + "kernelspec": { + "display_name": "Python 3", + "language": "python", + "name": "python3" + }, + "language_info": { + "codemirror_mode": { + "name": "ipython", + "version": 2 + }, + "file_extension": ".py", + "mimetype": "text/x-python", + "name": "python", + "nbconvert_exporter": "python", + "pygments_lexer": "ipython2", + "version": "2.7.6" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/examples/PyMPDATA_examples/advection_diffusion_2d/advection-diffusion-2d.ipynb b/examples/PyMPDATA_examples/advection_diffusion_2d/advection-diffusion-2d.ipynb index 1a97aea4..e811e939 100644 --- a/examples/PyMPDATA_examples/advection_diffusion_2d/advection-diffusion-2d.ipynb +++ b/examples/PyMPDATA_examples/advection_diffusion_2d/advection-diffusion-2d.ipynb @@ -47,21 +47,37 @@ "outputs": [], "execution_count": 59 }, + { + "metadata": { + "ExecuteTime": { + "end_time": "2025-02-12T11:32:04.822623Z", + "start_time": "2025-02-12T11:32:04.799557Z" + } + }, + "cell_type": "code", + "source": [ + "import os\n", + "os.environ[\"NUMBA_DISABLE_JIT\"] = \"1\"" + ], + "id": "ab0bbb13ee2e920a", + "outputs": [], + "execution_count": 1 + }, { "cell_type": "code", "id": "43d2893d-f472-43ac-ad5b-bf342a3783b9", "metadata": { "id": "43d2893d-f472-43ac-ad5b-bf342a3783b9", "ExecuteTime": { - "end_time": "2024-11-17T10:48:24.064Z", - "start_time": "2024-11-17T10:48:24.058632Z" + "end_time": "2025-02-12T11:32:05.733105Z", + "start_time": "2025-02-12T11:32:04.832910Z" } }, "source": [ "from open_atmos_jupyter_utils import show_plot" ], "outputs": [], - "execution_count": 60 + "execution_count": 2 }, { "cell_type": "code", @@ -69,8 +85,8 @@ "metadata": { "id": "9aaadc4a5234804a", "ExecuteTime": { - "end_time": "2024-11-17T10:48:24.074911Z", - "start_time": "2024-11-17T10:48:24.072769Z" + "end_time": "2025-02-12T11:32:07.117965Z", + "start_time": "2025-02-12T11:32:06.726029Z" } }, "source": [ @@ -84,7 +100,7 @@ "from PyMPDATA.boundary_conditions import Periodic" ], "outputs": [], - "execution_count": 61 + "execution_count": 3 }, { "cell_type": "code", diff --git a/examples/PyMPDATA_examples/utils/financial_formulae/asian_option.py b/examples/PyMPDATA_examples/utils/financial_formulae/asian_option.py index df537d48..c0078dc0 100644 --- a/examples/PyMPDATA_examples/utils/financial_formulae/asian_option.py +++ b/examples/PyMPDATA_examples/utils/financial_formulae/asian_option.py @@ -1,60 +1,75 @@ # pylint: disable=line-too-long """ Closed-forms for geometric Asian options are taken from: -[Derivatives Markets Appendix 19A](https://media.pearsoncmg.com/ph/bp/bridgepages/teamsite/mcdonald/McDonald-web-19-A.pdf) +[McDonald 2013, "Derivatives Markets", Appendix 19A](https://media.pearsoncmg.com/ph/bp/bridgepages/teamsite/mcdonald/McDonald-web-19-A.pdf) """ import numpy as np +from scipy.stats import norm from .Black_Scholes_1973 import c_euro_with_dividend, p_euro_with_dividend -# for fun in (c_euro_with_dividend, p_euro_with_dividend): -# locals()['geometric_asian_average_price_'+fun.__name__[0]] = lambda **args: fun( -# **{key:value for key, value in args.items() if key not in ('sgma', 'dividend_yield')}, -# sgma=args['sgma']/np.sqrt(3), -# dividend_yield=0.5*(args['r'] + args['dividend_yield'] + args['sgma']**2/6), +# def geometric_asian_average_price_c(S, K, T, r, sgma, dividend_yield): +# return c_euro_with_dividend( +# S=S, +# K=K, +# T=T, +# r=r, +# sgma=sgma / np.sqrt(3), +# dividend_yield=0.5 * (r + dividend_yield + sgma**2 / 6), # ) +# +# +# def geometric_asian_average_price_p(S, K, T, r, sgma, dividend_yield): +# return p_euro_with_dividend( +# S=S, +# K=K, +# T=T, +# r=r, +# sgma=sgma / np.sqrt(3), +# dividend_yield=0.5 * (r + dividend_yield + sgma**2 / 6), +# ) + + +# def geometric_asian_average_strike_c(S, K, T, r, sgma, dividend_yield): +# return c_euro_with_dividend( +# S=S, +# K=K, +# T=T, +# dividend_yield=dividend_yield, +# sgma=sgma * np.sqrt(T / 3), +# r=0.5 * (r + dividend_yield + sgma**2 / 6), +# ) +# +# +# def geometric_asian_average_strike_p(S, K, T, r, sgma, dividend_yield): +# return p_euro_with_dividend( +# S=S, +# K=K, +# T=T, +# dividend_yield=dividend_yield, +# sgma=sgma * np.sqrt(T / 3), +# r=0.5 * (r + dividend_yield + sgma**2 / 6), +# ) + + +def calculate_d_asian(S, K, T, r, sgma): + d_1 = (np.log(S / K) + 0.5 * (r + (sgma**2) / 6) * T) / (sgma * np.sqrt(T / 3)) + d_2 = d_1 - sgma * np.sqrt(T / 3) + return d_1, d_2 def geometric_asian_average_price_c(S, K, T, r, sgma, dividend_yield): - return c_euro_with_dividend( - S=S, - K=K, - T=T, - r=r, - sgma=sgma / np.sqrt(3), - dividend_yield=0.5 * (r + dividend_yield + sgma**2 / 6), - ) + d_1, d_2 = calculate_d_asian(S, K, T, r, sgma) + call_value = S * np.exp(-0.5 * (r + (sgma**2) / 6) * T) * norm.cdf( + d_1 + ) - K * np.exp(-r * T) * norm.cdf(d_2) + return call_value def geometric_asian_average_price_p(S, K, T, r, sgma, dividend_yield): - return p_euro_with_dividend( - S=S, - K=K, - T=T, - r=r, - sgma=sgma / np.sqrt(3), - dividend_yield=0.5 * (r + dividend_yield + sgma**2 / 6), - ) - - -def geometric_asian_average_strike_c(S, K, T, r, sgma, dividend_yield): - return c_euro_with_dividend( - S=S, - K=K, - T=T, - dividend_yield=dividend_yield, - sgma=sgma * np.sqrt(T / 3), - r=0.5 * (r + dividend_yield + sgma**2 / 6), - ) - - -def geometric_asian_average_strike_p(S, K, T, r, sgma, dividend_yield): - return p_euro_with_dividend( - S=S, - K=K, - T=T, - dividend_yield=dividend_yield, - sgma=sgma * np.sqrt(T / 3), - r=0.5 * (r + dividend_yield + sgma**2 / 6), - ) + d_1, d_2 = calculate_d_asian(S, K, T, r, sgma) + put_value = K * np.exp(-r * T) * norm.cdf(-d_2) - S * np.exp( + -0.5 * (r + (sgma**2) / 6) * T + ) * norm.cdf(-d_1) + return put_value diff --git a/examples/PyMPDATA_examples/utils/quick_look.py b/examples/PyMPDATA_examples/utils/quick_look.py new file mode 100644 index 00000000..42193673 --- /dev/null +++ b/examples/PyMPDATA_examples/utils/quick_look.py @@ -0,0 +1,91 @@ +"""utility routines for plotting 2D fields""" + +import numpy as np +from matplotlib import colors, pyplot + +from PyMPDATA import ScalarField, VectorField +from PyMPDATA.impl.field import Field + + +def quick_look(field: Field, plot: bool = True): + """plots either scalar or vector field together with halo region + rendering arrows in a staggered-grid-aware manner""" + halo = field.halo + grid = field.grid + pyplot.title(f"{grid=} {halo=} class={field.__class__.__name__}") + if isinstance(field, ScalarField): + norm = colors.Normalize(vmin=np.amin(field.get()), vmax=np.amax(field.get())) + pyplot.imshow( + X=field.data.T, + origin="lower", + extent=(-halo, grid[0] + halo, -halo, grid[1] + halo), + cmap="gray", + norm=norm, + ) + pyplot.colorbar() + elif isinstance(field, VectorField): + arrow_colors = ("green", "blue") + quiver_common_kwargs = {"pivot": "mid", "width": 0.005} + abs_max_in_domain = max([np.amax(np.abs(field.get_component(i))) for i in (0, 1)]) + arrows_xy = ( + np.mgrid[ + -(halo - 1) : grid[0] + 1 + (halo - 1) : 1, + 1 / 2 - halo : grid[1] + halo : 1, + ], + np.mgrid[ + 1 / 2 - halo : grid[0] + halo : 1, + -(halo - 1) : grid[1] + 1 + (halo - 1) : 1, + ], + ) + pyplot.xlim(-halo, grid[0] + halo) + pyplot.ylim(-halo, grid[1] + halo) + for dim in (0, 1): + pyplot.quiver( + *arrows_xy[dim], + field.data[dim].flatten() / abs_max_in_domain if dim == 0 else 0, + field.data[dim].flatten() / abs_max_in_domain if dim == 1 else 0, + color=arrow_colors[dim], + **quiver_common_kwargs, + ) + for i, val in enumerate(field.data[dim].flatten()): + if np.isfinite(val): + continue + pyplot.annotate( + text="NaN", + xy=( + arrows_xy[dim][0].flatten()[i], + arrows_xy[dim][1].flatten()[i], + ), + ha="center", + va="center", + color=arrow_colors[dim], + ) + else: + assert False + pyplot.hlines( + y=range(-halo, grid[1] + 1 + halo), + xmin=-halo, + xmax=grid[0] + halo, + color="r", + linewidth=0.5, + ) + pyplot.vlines( + x=range(-halo, grid[0] + 1 + halo), + ymin=-halo, + ymax=grid[1] + halo, + color="r", + linewidth=0.5, + ) + pyplot.hlines(y=range(grid[1] + 1), xmin=0, xmax=grid[0], color="r", linewidth=3) + pyplot.vlines(x=range(grid[0] + 1), ymin=0, ymax=grid[1], color="r", linewidth=3) + for i, x_y in enumerate(("x", "y")): + getattr(pyplot, f"{x_y}ticks")( + np.linspace(-halo + 0.5, grid[i] + halo - 0.5, grid[i] + 2 * halo) + ) + pyplot.xlabel("x/dx (outer dim)") + pyplot.ylabel("y/dy (inner dim)") + pyplot.grid(linestyle=":") + if plot: + pyplot.show() + else: + pyplot.clf()