{
 "cells": [
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "This notebook shows how to convert to a mixmod ensemble. To drive the point home, we'll start with an initial mixmod ensemble based on 3 normal distributions. However to make it easier to see what's going on, we'll focus on the first normal distribution centered at 0.5"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "import numpy as np\n",
    "import qp\n",
    "\n",
    "import matplotlib.pyplot as plt\n",
    "\n",
    "mu = np.array([[0.5,1.1, 2.9], [0.5, 1.25, 2.8], [0.3, 1.9, 2.2]])\n",
    "sig = np.array([[0.05,0.01,0.04], [0.05,0.01,0.02], [0.025, 0.01, 0.025]])\n",
    "wt = np.array([[1,1,1], [1,1,1], [1,1,1]])\n",
    "\n",
    "ens = qp.Ensemble(qp.mixmod, data=dict(means=mu, stds=sig, weights=wt))\n",
    "ens[1].plot_native(xlim=(0,1))"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "In the following example we use the default parameters to convert the input mixmod ensemble into another mixmod ensemble. We do the conversion 10 times and plot each on top of the original distribution. \n",
    "\n",
    "Note that the peaks of the converted distributions are not consistent."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xvals = np.linspace(0, 1., 301)\n",
    "\n",
    "axes_m = ens.plot_native(xlim=(0,1.), label='Original', marker='.')\n",
    "\n",
    "for i in range(10):\n",
    "    ens_m = qp.convert(ens, 'mixmod', xvals=xvals, ncomps=3)\n",
    "    _ = ens_m.plot(axes=axes_m, label=f'iteration_{i}', color=np.random.rand(3,))\n",
    "\n",
    "leg_m = axes_m.legend()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Reproducing the above plots, but this time specifying the number of random variates to be drawn from the input distribution to be 100_000 instead of the default 1000. Note that the peaks are now more consistent across the 10 iterations, but still show some jitter."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xvals = np.linspace(0, 1., 301)\n",
    "\n",
    "axes_m = ens.plot_native(xlim=(0,1.), label='Original', marker='.')\n",
    "\n",
    "for i in range(10):\n",
    "    ens_m = qp.convert(ens, 'mixmod', xvals=xvals, ncomps=3, nsamples=100_000)\n",
    "    _ = ens_m.plot(axes=axes_m, label=f'iteration_{i}', color=np.random.rand(3,))\n",
    "\n",
    "leg_m = axes_m.legend()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Here we use the default number of samples (1000), but specify the random_state value for drawing the random variates. This results in all iterations being identical, and reproducible. "
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xvals = np.linspace(0, 1., 301)\n",
    "\n",
    "axes_m = ens.plot_native(xlim=(0,1.), label='Original', marker='.')\n",
    "\n",
    "for i in range(10):\n",
    "    ens_m = qp.convert(ens, 'mixmod', xvals=xvals, ncomps=3, random_state=42)\n",
    "    _ = ens_m.plot(axes=axes_m, label=f'iteration_{i}', color=np.random.rand(3,))\n",
    "\n",
    "leg_m = axes_m.legend()"
   ]
  },
  {
   "attachments": {},
   "cell_type": "markdown",
   "metadata": {},
   "source": [
    "Finally, holding random_state constant, and increasing the number of samples results in the converted distributions consistently having the same values and showing a better reproduction of the input distribution."
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "xvals = np.linspace(0, 1., 301)\n",
    "\n",
    "axes_m = ens.plot_native(xlim=(0,1.), label='Original', marker='.')\n",
    "\n",
    "for i in range(10):\n",
    "    ens_m = qp.convert(ens, 'mixmod', xvals=xvals, ncomps=3, nsamples=100_000, random_state=42)\n",
    "    _ = ens_m.plot(axes=axes_m, label=f'iteration_{i}', color=np.random.rand(3,))\n",
    "\n",
    "leg_m = axes_m.legend()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "qp_issue_25",
   "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.10.6"
  },
  "orig_nbformat": 4,
  "vscode": {
   "interpreter": {
    "hash": "9be1a7334e581107f2753dc5e5ebb12b8975e5f80325d35375311bd0b6b51792"
   }
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}
