{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "# import packages\n",
    "import h5py                     # hdf5 reader\n",
    "import numpy as np              # numpy\n",
    "import matplotlib.pyplot as plt # plotting\n",
    "\n",
    "plt.rcParams.update({\n",
    "    \"pgf.texsystem\": \"pdflatex\",  # Use pdflatex for compatibility\n",
    "    \"text.usetex\": True,           # Use LaTeX for text rendering\n",
    "    \"font.family\": \"serif\",        # Use serif fonts\n",
    "    \"pgf.preamble\": r\"\\usepackage{amssymb}\\usepackage{amsmath}\",  # Add any necessary packages\n",
    "    \"pgf.rcfonts\": False,          # Disable rc fonts to avoid extra font definitions\n",
    "    \"font.size\": 22,\n",
    "    \"figure.figsize\": (12,4.6)\n",
    "})"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "wave1_samples_path = 'raw-data/32ksamples_wave1.hdf'\n",
    "wave1_training_path = 'training-results/32ksamples_wave1-NN.hdf'\n",
    "wave4_samples_path = 'raw-data/32ksamples_wave4.hdf'\n",
    "wave4_training_path = 'training-results/32ksamples_wave4-NN.hdf'"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "def load_hdf5_list_num(file, levels, dataset):\n",
    "    l = list()\n",
    "    for L in levels:\n",
    "        l.append(file[dataset+'/'+str(L)][()])\n",
    "    return l\n",
    "def load_hdf5_list_list(file, levels, dataset):\n",
    "    l = list()\n",
    "    for L in levels:\n",
    "        l.append(file[dataset+'/'+str(L)][:])\n",
    "    return l\n",
    "\n",
    "#load data from NN training\n",
    "wave1_training_f = h5py.File(wave1_training_path, 'r')\n",
    "levels = wave1_training_f['/levels'][:]\n",
    "number_of_training_samples = wave1_training_f['/number_of_training_samples'][:]\n",
    "wave1_POD_generalization_error = np.array(load_hdf5_list_num(wave1_training_f, levels, '/POD_generalization_error'))\n",
    "wave1_NN_generalization_error = np.array(load_hdf5_list_list(wave1_training_f, levels, '/NN_generalization_error'))\n",
    "wave1_training_f.close()\n",
    "wave4_training_f = h5py.File(wave4_training_path, 'r')\n",
    "levels = wave4_training_f['/levels'][:]\n",
    "number_of_training_samples = wave4_training_f['/number_of_training_samples'][:]\n",
    "wave4_POD_generalization_error = np.array(load_hdf5_list_num(wave4_training_f, levels, '/POD_generalization_error'))\n",
    "wave4_NN_generalization_error = np.array(load_hdf5_list_list(wave4_training_f, levels, '/NN_generalization_error'))\n",
    "wave4_training_f.close()\n",
    "\n",
    "# load samples for relative error\n",
    "wave1_samples_f = h5py.File(wave1_samples_path, 'r')\n",
    "wave1_HaltonSamples = wave1_samples_f['/HaltonSamples'][:]\n",
    "wave1_samples_f.close()\n",
    "wave4_samples_f = h5py.File(wave4_samples_path, 'r')\n",
    "wave4_HaltonSamples = wave4_samples_f['/HaltonSamples'][:]\n",
    "wave4_samples_f.close()"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "number_of_samples = int(wave1_HaltonSamples.shape[1]/2)\n",
    "wave1_L2norm = np.sqrt(np.sum(np.abs(wave1_HaltonSamples[:,number_of_samples:])**2)/number_of_samples)\n",
    "wave4_L2norm = np.sqrt(np.sum(np.abs(wave4_HaltonSamples[:,number_of_samples:])**2)/number_of_samples)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": [
    "levels = levels.reshape((-1,1)).transpose()[0]\n",
    "wave1_POD_generalization_error = wave1_POD_generalization_error.reshape((-1,1)).transpose()[0]\n",
    "wave1_NN_generalization_error = wave1_NN_generalization_error.reshape((-1,1)).transpose()[0]\n",
    "wave4_POD_generalization_error = wave4_POD_generalization_error.reshape((-1,1)).transpose()[0]\n",
    "wave4_NN_generalization_error = wave4_NN_generalization_error.reshape((-1,1)).transpose()[0]\n",
    "\n",
    "plt.subplots(constrained_layout=True)\n",
    "plt.gca().set_prop_cycle(None)\n",
    "plt.loglog(2**levels,wave1_POD_generalization_error/wave1_L2norm, '+-')\n",
    "plt.loglog(2**levels,wave4_POD_generalization_error/wave4_L2norm, '+-')\n",
    "plt.loglog(2**levels,5e-1*2.**(-0.5*levels),'--',color='black')\n",
    "plt.xlabel('number of training samples $N$')\n",
    "plt.ylabel('relative $L^2(U;L^2(\\hat{\\Gamma}))$-error')\n",
    "plt.title('relative $L^2$-error of the POD')\n",
    "plt.legend(['$\\kappa=1$', '$\\kappa=4$', r'rate $N^{-\\alpha/2}$'])\n",
    "plt.savefig('plots/N-convergence-POD-L2.eps')\n",
    "plt.show()\n",
    "\n",
    "plt.subplots(constrained_layout=True)\n",
    "plt.gca().set_prop_cycle(None)\n",
    "plt.loglog(2**levels,np.sqrt(wave1_POD_generalization_error**2+wave1_NN_generalization_error)/wave1_L2norm, '+-')\n",
    "plt.loglog(2**levels,np.sqrt(wave4_POD_generalization_error**2+wave4_NN_generalization_error)/wave4_L2norm, '+-')\n",
    "plt.loglog(2**levels,6e-1*2.**(-0.5*levels),'--',color='black')\n",
    "plt.xlabel('number of training samples $N$')\n",
    "plt.ylabel('relative $L^2(U;L^2(\\hat{\\Gamma}))$-error')\n",
    "plt.title('combined relative $L^2$-error of the Galerkin-POD NN')\n",
    "plt.legend(['$\\kappa=1$', '$\\kappa=4$', r'rate $N^{-\\alpha/2}$'])\n",
    "plt.savefig('plots/N-convergence-NN-L2.eps')\n",
    "plt.show()"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "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": 2
}
