diff --git a/.gitignore b/.gitignore index 9198ee1c..25ae00a3 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ +.DS_Store # TEMPO file formats tests/data/temp/ tests/data/performance_results/ @@ -146,3 +147,10 @@ dmypy.json # pdf output from example scripts examples/*.pdf + +# +results/ + +gitkey + +results_paper/ diff --git a/BIBLIOGRAPHY.md b/BIBLIOGRAPHY.md index d683f291..ef2a7b8a 100644 --- a/BIBLIOGRAPHY.md +++ b/BIBLIOGRAPHY.md @@ -16,7 +16,8 @@ The code in this project is based on ideas from the following publications: - **[FowlerWright2022]** Fowler-Wright et al., *Efficient Many-Body Non-Markovian Dynamics of Organic Polaritons*, [Phys. Rev. Lett. 129, 173001](https://doi.org/10.1103/PhysRevLett.129.173001) (2022). - **[Fux2023]** Fux et al., *Tensor network simulation of chains of non-Markovian open quantum systems*, [Phys. Rev. Research 5, 033078 ](https://doi.org/10.1103/PhysRevResearch.5.033078}) (2023). - **[Butler2024]** Butler et al., *Optimizing Performance of Quantum Operations with Non-Markovian Decoherence: The Tortoise or the Hare?*, [Phys. Rev. Lett. 132, 060401 ](https://doi.org/10.1103/PhysRevLett.132.060401}) (2024). - +- **[Link2024]** Link et al., *Open Quantum System Dynamics from Infinite Tensor Network Contraction*, `Phys. Rev. Lett. 132, + 200403 `__ (2024). BibTeX: ------- @@ -142,6 +143,21 @@ BibTeX: url = {https://doi.org/10.1103/PhysRevLett.123.240602} } +@article{Link2024, + title = {Open Quantum System Dynamics from Infinite Tensor Network Contraction}, + author = {Link, Valentin and Tu, Hong-Hao and Strunz, Walter T.}, + journal = {Phys. Rev. Lett.}, + volume = {132}, + issue = {20}, + pages = {200403}, + numpages = {7}, + year = {2024}, + month = {May}, + publisher = {American Physical Society}, + doi = {10.1103/PhysRevLett.132.200403}, + url = {https://link.aps.org/doi/10.1103/PhysRevLett.132.200403} +} + @misc{OQuPy-code-v0.5.0, author={{The TEMPO collaboration}}, title={{OQuPy: A Python package to efficiently simulate non-Markovian open quantum systems with process tensors.}}, diff --git a/HOW_TO_CITE.md b/HOW_TO_CITE.md index f082d91b..c34bf3fa 100644 --- a/HOW_TO_CITE.md +++ b/HOW_TO_CITE.md @@ -20,7 +20,7 @@ Also, please consider citing: - Chains (PT-TEBD): **[Fux2023]** - Mean-Field TEMPO: **[FowlerWright2022]** - Gibbs TEMPO: **[Chiu2022]** - +- Time translational invariant TEMPO: **[Link2024]** BibTeX ------ diff --git a/README.md b/README.md index 85e106d2..17db6c00 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Furthermore, OQuPy implements methods to ... - **[9]** Butler et al., [Phys. Rev. Lett. 132, 060401 ](https://doi.org/10.1103/PhysRevLett.132.060401) (2024). - **[10]** Gribben et al., [Quantum, 6, 847](https://doi.org/10.22331/q-2022-10-25-847) (2022). - **[11]** Chiu et al., [Phys. Rev. A 106, 012204](https://doi.org/10.1103/PhysRevA.106.012204) (2022). - +- **[12]** Link et al., [Phys. Rev. Lett. 132, 200403](https://doi.org/10.1103/PhysRevLett.132.200403) (2024). ------------------------------------------------------------------------------- diff --git a/docs/index.rst b/docs/index.rst index 16e2eaf2..029c19e6 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -61,7 +61,8 @@ Furthermore, OQuPy implements methods to ... 847 `__ (2022). - **[11]** Chiu et al., `Phys. Rev. A 106, 012204 `__ (2022). - +- **[12]** Link et al., `Phys. Rev. Lett. 132, + 200403 `__ (2024). .. |binder-tutorial| image:: https://mybinder.org/badge_logo.svg :target: https://mybinder.org/v2/gh/tempoCollaboration/OQuPy/main?filepath=tutorials%2Fquickstart.ipynb diff --git a/docs/pages/bibliography.rst b/docs/pages/bibliography.rst index d4c30356..fdc28a36 100644 --- a/docs/pages/bibliography.rst +++ b/docs/pages/bibliography.rst @@ -45,6 +45,9 @@ publications: Operations with Non-Markovian Decoherence: The Tortoise or the Hare?*, `Phys. Rev. Lett. 132, 060401 `__ (2024). +- **[Link2024]** Link et al., *Open Quantum System Dynamics from Infinite + Tensor Network Contraction*, `Phys. Rev. Lett. 132, + 200403 `__ (2024). .. _bibtex: @@ -173,6 +176,21 @@ BibTeX: url = {https://doi.org/10.1103/PhysRevLett.123.240602} } + @article{Link2024, + title = {Open Quantum System Dynamics from Infinite Tensor Network Contraction}, + author = {Link, Valentin and Tu, Hong-Hao and Strunz, Walter T.}, + journal = {Phys. Rev. Lett.}, + volume = {132}, + issue = {20}, + pages = {200403}, + numpages = {7}, + year = {2024}, + month = {May}, + publisher = {American Physical Society}, + doi = {10.1103/PhysRevLett.132.200403}, + url = {https://link.aps.org/doi/10.1103/PhysRevLett.132.200403} + } + @misc{OQuPy-code-v0.5.0, author={{The TEMPO collaboration}}, title={{OQuPy: A Python package to efficiently simulate non-Markovian open quantum systems with process tensors.}}, diff --git a/docs/pages/how_to_cite.rst b/docs/pages/how_to_cite.rst index a00f1063..fd68401c 100644 --- a/docs/pages/how_to_cite.rst +++ b/docs/pages/how_to_cite.rst @@ -20,6 +20,7 @@ Also, please consider citing: - Chains (PT-TEBD): **[Fux2023]** - Mean-Field TEMPO: **[FowlerWright2022]** - Gibbs TEMPO: **[Chiu2022]** +- Time translational invariant TEMPO: **[Link2024]** BibTeX ------ diff --git a/examples/fidelity-gradient-tti.ipynb b/examples/fidelity-gradient-tti.ipynb new file mode 100644 index 00000000..a8d149a4 --- /dev/null +++ b/examples/fidelity-gradient-tti.ipynb @@ -0,0 +1,291 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "# %load examples/fidelity-gradient-tti.py\n", + "#!/usr/bin/env python\n", + "\n", + "# Computation takes roughly 10 minutes.\n", + "\n", + "import sys\n", + "sys.path.insert(0,'..')\n", + "\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt\n", + "\n", + "import oqupy\n", + "import oqupy.operators as op\n", + "\n", + "from oqupy.tti_tempo import TTITempo\n", + "from scipy.optimize import minimize\n", + "\n", + "# --- Parameters --------------------------------------------------------------\n", + "\n", + "# parameters used in https://arxiv.org/abs/2303.16002\n", + "\n", + "# -- time steps --\n", + "end_time = 2.5\n", + "num_steps = 50\n", + "dt = end_time / num_steps\n", + "\n", + "num_steps = 200\n", + "\n", + "# -- bath --\n", + "alpha = 0.126 \n", + "omega_cutoff = 3.04 \n", + "temperature = 5 * 0.1309 \n", + "pt_dkmax = 60 \n", + "pt_epsrel = 10**(-7) \n", + "\n", + "# -- initial and target state --\n", + "initial_state = op.spin_dm('x-')\n", + "target_derivative = op.spin_dm('x+').T\n", + "\n", + "# -- initial parameter guess, defined over half-timesteps --\n", + "y0 = np.zeros(2*num_steps)\n", + "z0 = np.ones(2*num_steps) * (np.pi) / (num_steps*dt)\n", + "x0 = np.zeros(2*num_steps)\n", + "\n", + "parameters = np.vstack((x0,y0,z0)).T\n", + "num_params = parameters.shape[1]\n", + "print(parameters.shape)\n", + "\n", + "# --- Compute process tensors -------------------------------------------------\n", + "\n", + "correlations = oqupy.PowerLawSD(\n", + " alpha=alpha,\n", + " zeta=3,\n", + " cutoff=omega_cutoff,\n", + " cutoff_type='gaussian',\n", + " temperature=temperature)\n", + "bath = oqupy.Bath(0.5* op.sigma('z'), correlations)\n", + "pt_tempo_parameters = oqupy.TempoParameters(\n", + " dt=dt,\n", + " epsrel=pt_epsrel,\n", + " dkmax=pt_dkmax)\n", + "\n", + "pt=TTITempo(bath,start_time=0.0,parameters=pt_tempo_parameters)\n", + "process_tensor=pt.get_process_tensor()\n", + "\n", + "#process_tensor = oqupy.pt_tempo_compute(\n", + "# bath=bath,\n", + "# start_time=0.0,\n", + "# end_time=pt_end_time,\n", + "# parameters=pt_tempo_parameters)\n", + "\n", + "# --- Define parameterized system ----------------------------------------------\n", + "\n", + "hs_dim = 2\n", + "\n", + "def hamiltonian(x, y, z):\n", + " h = np.zeros((2,2),dtype='complex128')\n", + " for var, var_name in zip([x,y,z], ['x', 'y', 'z']):\n", + " h += 0.5* var * op.sigma(var_name)\n", + " return h\n", + "\n", + "parametrized_system = oqupy.ParameterizedSystem(hamiltonian)\n", + "\n", + "# --- Compute fidelity, dynamics, and fidelity gradient -----------------------\n", + "\n", + "from oqupy.gradient import state_gradient\n", + "\n", + "fidelity_dict = state_gradient(\n", + " system=parametrized_system,\n", + " initial_state=initial_state,\n", + " target_derivative=target_derivative,\n", + " process_tensors=[process_tensor],\n", + " parameters=parameters,\n", + " num_steps=num_steps)\n", + "\n", + "final_state = fidelity_dict['dynamics'].states[-1]\n", + "v_final_state = np.reshape(final_state,hs_dim**2)\n", + "v_target_derivative = np.reshape(target_derivative.T,hs_dim**2)\n", + "fidelity = v_target_derivative @ v_final_state\n", + "\n", + "print(f\"the fidelity is {fidelity.real}\")\n", + "#print(f\"the fidelity gradient is {fidelity_dict['gradient'].real}\")\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "t, s_x = fidelity_dict['dynamics'].expectations(op.sigma(\"x\"), real=True)\n", + "t, s_y = fidelity_dict['dynamics'].expectations(op.sigma(\"y\"), real=True)\n", + "t, s_z = fidelity_dict['dynamics'].expectations(op.sigma(\"z\"), real=True)\n", + "bloch_length = np.sqrt(s_x**2 +s_y**2 + s_z**2)\n", + "\n", + "plt.title(\"Pre-optimisation evolution of components\")\n", + "plt.plot(t,s_x,label='x')\n", + "plt.plot(t,s_y,label='y')\n", + "plt.plot(t,s_z,label='z')\n", + "plt.plot(t,bloch_length,label=r'$|\\mathbf{\\sigma}|$')\n", + "\n", + "plt.ylabel(r\"$\\langle \\sigma \\rangle$\",rotation=0,fontsize=16)\n", + "plt.xlabel(\"t\")\n", + "\n", + "plt.legend()\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "# ----------- Optimisation of control parameters w.r.t. infidelity ---------------\n", + "\n", + "def infidandgrad(paras):\n", + " \"\"\"\"\"\n", + " Take a numpy array [hx0, hz0, hx1, hz1, ...] over full timesteps and\n", + " return the fidelity and gradient of the fidelity to the global target_derivative\n", + " \"\"\"\n", + "\n", + " # Reshape flat parameter list to form accepted by state_gradient: [[hx0,hz0],[hx1,hz1,]...]\n", + " reshapedparas = [i for i in (paras.reshape((-1,num_params))).tolist() for j in range(2)]\n", + " reshapedparas = np.array(reshapedparas)\n", + "\n", + " gradient_dict = oqupy.state_gradient(\n", + " system=parametrized_system,\n", + " initial_state=initial_state,\n", + " target_derivative=target_derivative,\n", + " process_tensors=[process_tensor],\n", + " parameters=reshapedparas,\n", + " num_steps=num_steps,\n", + " progress_type='silent')\n", + " \n", + " fs=gradient_dict['final_state']\n", + " gps=gradient_dict['gradient']\n", + " fidelity=np.sum(fs*target_derivative.T)\n", + "\n", + " # Adding adjacent elements\n", + " for i in range(0,gps.shape[0],2): \n", + " gps[i,:]=gps[i,:]+gps[i+1,:]\n", + " \n", + " gps=gps[0::2]\n", + "\n", + " # Return the minus the gradient as infidelity is being minimized \n", + " return 1-fidelity.real,(-1.0*gps.reshape((-1)).real).tolist()\n", + "\n", + "# Set upper and lower bounds on control parameters\n", + "x_bound = [-5*np.pi,5*np.pi]\n", + "y_bound = [0,0] \n", + "z_bound = [-np.pi,np.pi]\n", + "\n", + "bounds = np.zeros((num_steps*num_params,2))\n", + "\n", + "for i in range(0, num_params*num_steps,num_params):\n", + " bounds[i] = x_bound\n", + " bounds[i+1] = y_bound\n", + " bounds[i+2] = z_bound\n", + "\n", + "y0 = np.zeros(num_steps)\n", + "z0 = np.ones(num_steps) * (np.pi) / (dt*num_steps)\n", + "x0 = np.zeros(num_steps)\n", + "\n", + "# Flatten list for input to optimizer\n", + "parameter_list=[item for pair in zip(x0, y0, z0) for item in pair]\n", + "\n", + "optimization_result = minimize(\n", + " fun=infidandgrad,\n", + " x0=parameter_list,\n", + " method='L-BFGS-B',\n", + " jac=True,\n", + " bounds=bounds,\n", + " options = {'disp':True, 'gtol': 7e-05}\n", + ")\n", + "\n", + "print(\"The maximal fidelity was found to be : \",1-optimization_result.fun)\n", + "\n", + "#print(\"The Jacobian was found to be : \",optimization_result.jac)\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "optimized_params = optimization_result.x\n", + "reshapedparas=np.array([i for i in (optimized_params.reshape((-1,num_params))).tolist() for j in range(2)])\n", + "\n", + "# Input optimized controls into state_gradient to show dynamics of system under optimized fields\n", + "optimized_dynamics = state_gradient(\n", + " system=parametrized_system,\n", + " initial_state=initial_state,\n", + " target_derivative=target_derivative,\n", + " process_tensors=[process_tensor],\n", + " parameters=reshapedparas,\n", + " num_steps=num_steps)\n", + "\n", + "fig, (ax1, ax2) = plt.subplots(nrows=2, ncols=1) \n", + "fig.suptitle(\"Optimisation results\")\n", + "\n", + "field_labels = [\"x\",\"y\",\"z\"]\n", + "for i in range(0,num_params):\n", + " ax1.plot(t[:-1],optimization_result['x'][i::num_params],label=field_labels[i])\n", + "ax1.set_ylabel(r\"$h_i$\",rotation=0,fontsize=16)\n", + "ax1.set_xlabel(\"t\")\n", + "ax1.legend()\n", + "\n", + "dynamics = optimized_dynamics['dynamics']\n", + "\n", + "t, bloch_x =optimized_dynamics['dynamics'].expectations(op.sigma(\"x\"))\n", + "t, bloch_y = optimized_dynamics['dynamics'].expectations(op.sigma(\"y\"))\n", + "t, bloch_z = optimized_dynamics['dynamics'].expectations(op.sigma(\"z\"))\n", + "\n", + "ax2.plot(t,bloch_x,label='x')\n", + "ax2.plot(t,bloch_y,label='y')\n", + "ax2.plot(t,bloch_z,label='z')\n", + "bloch_length = np.sqrt(bloch_x**2 +bloch_y**2 + bloch_z**2)\n", + "ax2.plot(t,bloch_length,label=r'$|\\mathbf{\\sigma}|$')\n", + "ax2.set_ylabel(r\"$\\langle \\sigma \\rangle$\",rotation=0,fontsize=16)\n", + "ax2.set_xlabel(\"t\")\n", + "\n", + "plt.legend()\n", + "plt.show()\n", + "\n", + "# -----------------------------------------------------------------------------\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "oqupy", + "language": "python", + "name": "oqupy" + }, + "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.19" + } + }, + "nbformat": 4, + "nbformat_minor": 4 +} diff --git a/examples/fidelity-gradient.py b/examples/fidelity-gradient.py index 32da49a0..32e7f33e 100644 --- a/examples/fidelity-gradient.py +++ b/examples/fidelity-gradient.py @@ -23,6 +23,10 @@ num_steps = 50 dt = end_time / num_steps +# this is the length of the PT to compute, which may be longer than the time above, to which the dynamics is considered + +pt_end_time = 5.0 + # -- bath -- alpha = 0.126 omega_cutoff = 3.04 @@ -59,7 +63,7 @@ process_tensor = oqupy.pt_tempo_compute( bath=bath, start_time=0.0, - end_time=end_time, + end_time=pt_end_time, parameters=pt_tempo_parameters) # --- Define parameterized system ---------------------------------------------- @@ -83,7 +87,8 @@ def hamiltonian(x, y, z): initial_state=initial_state, target_derivative=target_derivative, process_tensors=[process_tensor], - parameters=parameters) + parameters=parameters, + num_steps=num_steps) final_state = fidelity_dict['dynamics'].states[-1] v_final_state = np.reshape(final_state,hs_dim**2) @@ -126,6 +131,7 @@ def infidandgrad(paras): target_derivative=target_derivative, process_tensors=[process_tensor], parameters=reshapedparas, + num_steps=num_steps, progress_type='silent') fs=gradient_dict['final_state'] @@ -182,7 +188,8 @@ def infidandgrad(paras): initial_state=initial_state, target_derivative=target_derivative, process_tensors=[process_tensor], - parameters=reshapedparas) + parameters=reshapedparas, + num_steps=num_steps) fig, (ax1, ax2) = plt.subplots(nrows=2, ncols=1) fig.suptitle("Optimisation results") diff --git a/examples/tti-tempo.ipynb b/examples/tti-tempo.ipynb new file mode 100644 index 00000000..0aa84d92 --- /dev/null +++ b/examples/tti-tempo.ipynb @@ -0,0 +1,124 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": null, + "id": "8a85fd69", + "metadata": {}, + "outputs": [], + "source": [ + "# Demonstration of iTEBD within OQuPy\n", + "# Uses the original iTEBD code by Valentin Link from https://github.com/val-link/iTEBD-TEMPO.git.\n", + "# Minimally modified by Paul Eastham to take a bath correlation object from OQuPy.\n", + "# The resulting object can turned into a new proces tensor subclass, TTInvariantProcessTensor, which should function as all other PTs in OQuPy\n", + "# Todo: fully integrate the creation of iTEBD process tensors so we can skip calls to iTEBD_TEMPO_oqupy class." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f906bed1", + "metadata": {}, + "outputs": [], + "source": [ + "import sys\n", + "sys.path.insert(0,'..')\n", + "\n", + "import oqupy as oqupy\n", + "from oqupy.tti_tempo import TTITempo\n", + "import numpy as np\n", + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "f314d374", + "metadata": {}, + "outputs": [], + "source": [ + "sigma_z = oqupy.operators.sigma(\"z\")\n", + "sigma_x = oqupy.operators.sigma(\"x\")\n", + "sigma_y = oqupy.operators.sigma(\"y\")\n", + "omega_cutoff = 3.04 \n", + "alpha = 0.126\n", + "temperature = 0.1309\n", + "correlations = oqupy.PowerLawSD(alpha=alpha,\n", + " zeta=3,\n", + " cutoff=omega_cutoff,\n", + " cutoff_type='gaussian',\n", + " temperature=temperature)\n", + "bath = oqupy.Bath(sigma_x/2.0, correlations)\n", + "parameters=oqupy.TempoParameters(dt=0.1,epsrel=1e-7,dkmax=100)\n", + "pt=TTITempo(bath,start_time=0.0,parameters=parameters)\n", + "pt.compute()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "6dc20eab", + "metadata": {}, + "outputs": [], + "source": [ + "detuning = lambda t: 0.0 * t\n", + "def gaussian_shape(t, area = 1.0, tau = 1.0, t_0 = 0.0):\n", + " return area/(tau*np.sqrt(np.pi)) * np.exp(-(t-t_0)**2/(tau**2))\n", + "\n", + "def hamiltonian_t(t):\n", + " return detuning(t)/2.0 * sigma_z \\\n", + " + gaussian_shape(t, area = np.pi/2.0, tau = 0.5)/2.0 * sigma_y\n", + "\n", + "system = oqupy.TimeDependentSystem(hamiltonian_t)\n", + "\n", + "Rho_0=oqupy.operators.spin_dm('x-')\n", + "\n", + "dynamics = oqupy.compute_dynamics(\n", + " process_tensor=pt.get_process_tensor(), \n", + " system=system,\n", + " initial_state=Rho_0,\n", + " start_time=-5.0,\n", + " num_steps=200)\n", + "\n", + "t, s_x = dynamics.expectations(sigma_x, real=True)\n", + "_, s_y = dynamics.expectations(sigma_y, real=True)\n", + "_, s_z = dynamics.expectations(sigma_z, real=True)\n", + "\n", + "plt.plot(t,s_x,label='sx')\n", + "plt.plot(t,s_y,label='sy')\n", + "plt.plot(t,s_z,label='sz')\n", + "plt.ylim((-1.0,1.0))\n", + "plt.legend(loc=4)" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "be7831c4-0a8a-4625-b9d9-da735ed1210d", + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "OQuPy", + "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.20" + } + }, + "nbformat": 4, + "nbformat_minor": 5 +} diff --git a/oqupy/__init__.py b/oqupy/__init__.py index 1a72fe52..44990fea 100644 --- a/oqupy/__init__.py +++ b/oqupy/__init__.py @@ -39,13 +39,14 @@ (https://doi.org/10.1103/PhysRevLett.129.173001) (2022). [8] Fux et al., [Phys. Rev. Lett. 126, 200401] (https://doi.org/10.1103/PhysRevLett.126.200401) (2021). -[9] Butler et al., [Phys. Rev. Lett. 132, 060401 ] +[9] Butler et al., [Phys. Rev. Lett. 132, 060401] (https://doi.org/10.1103/PhysRevLett.132.060401}) (2024). [10] Gribben et al., [Quantum, 6, 847] (https://doi.org/10.22331/q-2022-10-25-847) (2022). [11] Chiu et al., [Phys. Rev. A 106, 012204] - (https://doi.org/10.1103/PhysRevA.106.012204}) (2022). - + (https://doi.org/10.1103/PhysRevA.106.012204) (2022). +[12] Link et al., [Phys. Rev. Lett. 132, 200403] + (https://doi.org/10.1103/PhysRevLett.132.200403) (2024). """ from oqupy.version import __version__ @@ -80,8 +81,13 @@ 'PtTebdParameters', 'PtTempo', 'pt_tempo_compute', + 'TTITempo', + 'tti_tempo_compute', 'SimpleProcessTensor', + 'SimpleProcessTensorFinite', + 'SimpleProcessTensorInfinite', 'state_gradient', + 'state_gradient_env_dependent', 'System', 'SystemChain', 'Tempo', @@ -115,6 +121,7 @@ from oqupy.dynamics import MeanFieldDynamics from oqupy.gradient import state_gradient +from oqupy.gradient import state_gradient_env_dependent from oqupy.gradient import compute_gradient_and_dynamics from oqupy import helpers @@ -126,6 +133,8 @@ from oqupy.process_tensor import import_process_tensor from oqupy.process_tensor import TrivialProcessTensor from oqupy.process_tensor import SimpleProcessTensor +from oqupy.process_tensor import SimpleProcessTensorFinite +from oqupy.process_tensor import SimpleProcessTensorInfinite from oqupy.process_tensor import FileProcessTensor from oqupy.pt_tebd import PtTebd @@ -137,10 +146,14 @@ from oqupy.system import TimeDependentSystemWithField from oqupy.system import MeanFieldSystem from oqupy.system import ParameterizedSystem +from oqupy.system import ParameterizedSystem2ls from oqupy.pt_tempo import PtTempo from oqupy.pt_tempo import pt_tempo_compute +from oqupy.tti_tempo import TTITempo +from oqupy.tti_tempo import tti_tempo_compute + from oqupy.tempo import Tempo from oqupy.tempo import TempoParameters from oqupy.tempo import GibbsTempo diff --git a/oqupy/backends/pt_tempo_backend.py b/oqupy/backends/pt_tempo_backend.py index a2086ada..ded30ce8 100644 --- a/oqupy/backends/pt_tempo_backend.py +++ b/oqupy/backends/pt_tempo_backend.py @@ -29,6 +29,328 @@ class PtTempoBackend: """ Base class for process tensor tempo backends. + Parameters + ---------- + influence: callable(int) -> ndarray + Callable that takes an integer `step` and returns the influence super + operator of that `step`. + process_tensor: BaseProcessTensor + Todo + sum_north: ndarray + The summing vector for the north leggs. + sum_west: ndarray + The summing vector for the west leggs. + num_steps: int + Todo + dkmax: int + Number of influences to include. If ``dkmax == None`` then all + influences are included. + epsrel: float + Maximal relative SVD truncation error. + config: Dict + Todo + degeneracy_maps: Optional[List[ndarray]] (default None) + List of two arrays to invert the degeneracy in the north and west + directions (respectively). If None then no degeneracy checks are used. + """ + def __init__( + self, + dimension: int, + influence: Callable[[int], ndarray], + process_tensor: BaseProcessTensor, + sum_north: ndarray, + sum_west: ndarray, + num_steps: int, + dkmax: int, + epsrel: float, + config: Dict, + degeneracy_maps: Optional[List[ndarray]] = None, + alpha_t: Optional[ndarray] = None): + """Create a BasePtTempoBackend object. """ + self._dimension = dimension + self._influence = influence + self._process_tensor = process_tensor + self._sum_north = sum_north + self._sum_west = sum_west + self._num_steps = num_steps + self._dkmax = dkmax + self._epsrel = epsrel + self._alpha_t=alpha_t + self._config = config + self._step = None + self._degeneracy_maps = degeneracy_maps + + if "backend" in config: + self._backend = config["backend"] + else: + self._backend = None + + self._mps = None + self._mpo = None + self._last_infl_na = None + self._num_infl = min(num_steps, dkmax+1) + self._super_u = None + self._super_u_dagg = None + self._sum_north_scaled = None + self._one_na = None + + @property + def step(self) -> int: + """The current step in the PT-TEMPO computation. """ + return self._step + + @property + def num_steps(self) -> int: + """The current step in the PT-TEMPO computation. """ + return self._num_steps + + def initialize(self) -> None: + """Initializes the PT-TEMPO tensor network. """ + # create mpo + # create mpo last + # copy and contract mpo to mps + scale = self._dimension + + + #scale = 1 + + self._sum_north_scaled = self._sum_north * scale + + if self._degeneracy_maps is not None: + north_degeneracy_map, west_degeneracy_map = self._degeneracy_maps + tmp_north_deg_num_vals = numpy_max(north_degeneracy_map)+1 + tmp_west_deg_num_vals = numpy_max(west_degeneracy_map)+1 + + influences_mpo = [] + influences_mps = [] + for i in range(self._num_infl): + + if self._alpha_t is not None: + ifpow=np.sqrt(self._alpha_t[0]*self._alpha_t[i]) + else: + ifpow=1 + + if i == 0: + infl = self._influence(i) + infl = infl / scale + if self._degeneracy_maps is not None: + tmp_mpo = zeros((tmp_west_deg_num_vals, + self._dimension**2, + tmp_north_deg_num_vals), + dtype=complex) + tmp_mps = zeros((self._dimension**2, + tmp_north_deg_num_vals), + dtype=complex) + for i1 in range(self._dimension**2): + tmp_mpo[west_degeneracy_map[i1]][i1]\ + [north_degeneracy_map[i1]] = \ + infl[north_degeneracy_map[i1]] + tmp_mps[i1][north_degeneracy_map[i1]] = \ + infl[north_degeneracy_map[i1]]/ scale + infl_mpo = tmp_mpo + infl_mps = (tmp_mps ** ifpow) * scale**(2*ifpow-2) # not tested + else: + infl_mpo = util.create_delta(infl, [1, 1, 0]) # nb this block includes 1/scale + infl_mps = (infl**ifpow).T * scale**(ifpow-2) + elif i == self._num_infl-1: + infl = self._influence(i) + infl_mpo = util.add_singleton(infl, 1) + infl_mpo = util.add_singleton(infl_mpo, 3) + infl_mps = util.add_singleton((infl**ifpow), 2) + else: + infl = self._influence(i) + infl_mpo = util.create_delta(infl, [0, 1, 1, 0]) + infl_mps = util.create_delta((infl**ifpow) / scale, [0, 1, 0]) + + influences_mpo.append(infl_mpo) + influences_mps.append(infl_mps) + + + + self._mpo = na.NodeArray(influences_mpo, + left=False, + right=True, + name="Thee Time Evolving MPO", + backend=self._backend) + + self._mps = na.NodeArray(influences_mps, + left=False, + right=True, + name="Thee MPS", + backend=self._backend) + + self._mps.svd_sweep(from_index=-1, + to_index=0, + max_singular_values=None, + max_truncation_err=self._epsrel, + relative=True) + + self._mps.svd_sweep(from_index=0, + to_index=-1, + max_singular_values=None, + max_truncation_err=self._epsrel, + relative=True) + + one = np.array([[1.0]], dtype=NpDtype) + self._one_na = na.NodeArray([one], + left=True, + right=False, + name="The id", + backend=self._backend) + + self._step = 1 + + def compute_step(self) -> None: + """ + See BasePtBackend.compute_step() for docstring. + + For example, for at step 4, we start with: + + A ... self._mps + B ... self._mpo + 1 ... [[1.0]] + n ... self._sum_north_array + + n + | | + 1~ ~B~ A~ ~B~ + | | | | + A~ ~B~ A~ ~B~ + | | | | + A~ ~B~ or A~ ~B~ + | | | | + A~ ~B~ A~ ~B~ + | | + A~ A~ + | | + A~ A~ + + + effects: + if in grow phase: + self._mps will be contraction of A, B, 1 + if in end phase: + self._mps will be a contraction of A, B, n + self._mpo will be one element shorter + """ + self._step += 1 + + end_phase = bool(self._step > self._num_steps - self._num_infl + 1) + + if end_phase: + self._mpo, _ = na.split(self._mpo, + index=-1, + copy=False, + name_left="Shortened MPO") + self._mpo.apply_vector(self._sum_north_scaled, left=False) + if self._mps.right: + self._mps.apply_vector(np.array([1.0]), left=False) + else: + if self._dkmax is not None: + dk = int(0 - self._step) + infl = self._influence(dk) + if infl is not None: + infl_mpo = util.add_singleton(infl, 1) + infl_mpo = util.add_singleton(infl_mpo, 3) + last_mpo = na.NodeArray( + [infl_mpo], + left=True, + right=True, + name="The integrating back to zero infl. func.", + backend=self._backend) + self._mpo, _ = na.split(self._mpo, + index=-1, + copy=False, + name_left="Shortened MPO") + self._mpo = na.join(self._mpo, + last_mpo, + copy=False, + name="Thee updated MPO") + + one = self._one_na.copy() + self._mps = na.join(self._mps, + one, + copy=False, + name="Thee updated MPS") + mpo = self._mpo.copy() + + if self._alpha_t is not None: + tensors = [node.get_tensor() for node in mpo.nodes] + k1 = self._step - 1 + exponents_cut = [ + np.sqrt(self._alpha_t[k1] * self._alpha_t[k2]) + for k2 in range(k1, len(tensors)+k1) + ] + + for i in range(len(tensors)): + tensors[i]=tensors[i] ** exponents_cut[i] + if (len(tensors)>1): + if i==0: + scale=self._dimension + tensors[i]=tensors[i] * scale**(exponents_cut[i]-1) + elif (end_phase and i==len(tensors)-1): + scale=self._dimension + tensors[i]=tensors[i] / scale**(exponents_cut[i]-1) + + for node, tensor, exponent in zip(mpo.nodes, tensors, exponents_cut): + node.set_tensor(tensor) + + self._mps.zip_up(mpo, + axes=[(0,0)], + right_index=-1, + direction="left", + max_singular_values=None, + max_truncation_err=self._epsrel, + relative=True, + copy=False) + + self._mps.svd_sweep(from_index=self._step-2, + to_index=-1, + max_singular_values=None, + max_truncation_err=self._epsrel, + relative=True) + + return self._step < self._num_steps + + def get_mpo_tensor(self, step: int) -> ndarray: + """ToDo. """ + n = len(self._mps.nodes) + assert n == self._num_steps + assert step < n + + if step == 0: + order = [self._mps.bond_edges[0],self._mps.array_edges[0][0]] + first_t = self._mps.nodes[0].reorder_edges(order).get_tensor() + first_t = util.add_singleton(first_t, 0) + tensor = first_t * self._dimension + elif step == n-1: + order = [self._mps.bond_edges[-1],self._mps.array_edges[-1][0]] + last_t = self._mps.nodes[-1].reorder_edges(order).get_tensor() + last_t = util.add_singleton(last_t, 1) + tensor = last_t * self._dimension + else: + order = [self._mps.bond_edges[step-1], + self._mps.bond_edges[step], + self._mps.array_edges[step][0]] + temp_t = self._mps.nodes[step].reorder_edges(order).get_tensor() + tensor = temp_t * self._dimension + + return tensor + + def update_process_tensor(self) -> None: + """Update the process tensor. """ + assert self._step >= self._num_steps + + for step in reversed(range(self.num_steps)): + mpo_tensor = self.get_mpo_tensor(step) + self._process_tensor.set_mpo_tensor(step, mpo_tensor) + self._process_tensor.compute_caps() + + +class PtTempoBackendOld: + """ + Base class for process tensor tempo backends. + Parameters ---------- influence: callable(int) -> ndarray diff --git a/oqupy/backends/tempo_backend.py b/oqupy/backends/tempo_backend.py index e5e30158..3ef54803 100644 --- a/oqupy/backends/tempo_backend.py +++ b/oqupy/backends/tempo_backend.py @@ -351,7 +351,8 @@ def __init__( epsrel: float, config: Optional[Dict] = None, degeneracy_maps: Optional[List[ndarray]] = None, - dim: Optional[int] = None): + dim: Optional[int] = None, + alpha_t : Optional[ndarray] = None): """Create a TempoBackend object. """ self._initial_state = initial_state self._influence = influence @@ -360,6 +361,7 @@ def __init__( self._sum_west = sum_west self._dkmax = dkmax self._epsrel = epsrel + self._alpha_t = alpha_t self._step = None self._state = None self._config = TEMPO_BACKEND_CONFIG if config is None else config @@ -515,6 +517,14 @@ def compute_system_step(self, current_step, prop_1, prop_2) -> ndarray: name="Thee Time Evolving MPO", copy=False) + if self._alpha_t is not None: + tensors = [nodes.get_tensor() for nodes in mpo.nodes] + + exponents = [np.sqrt(self._alpha_t[current_step-1]*self._alpha_t[k2]) for k2 in range(0,current_step)] + exponents_cut = exponents[:len(tensors)] + + [node.set_tensor(tensor**exponent) for node,tensor,exponent in zip(mpo.nodes, tensors, exponents_cut)] + mpo.name = "temporary MPO" mpo.apply_vector(self._sum_west, left=True) @@ -592,7 +602,8 @@ def __init__( epsrel: float, config: Optional[Dict] = None, degeneracy_maps: Optional[List[ndarray]] = None, - dim: Optional[int] = None): + dim: Optional[int] = None, + alpha_t: Optional[ndarray] = None): """Create a TempoBackend object. """ super().__init__( initial_state, @@ -604,7 +615,8 @@ def __init__( epsrel, config, degeneracy_maps, - dim) + dim, + alpha_t=alpha_t) self._propagators = propagators def initialize(self) -> Tuple[int, ndarray]: diff --git a/oqupy/backends/tti_tempo_backend.py b/oqupy/backends/tti_tempo_backend.py new file mode 100644 index 00000000..9e778273 --- /dev/null +++ b/oqupy/backends/tti_tempo_backend.py @@ -0,0 +1,208 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Module for the time translational invariant time evolving matrix product +operator algorithm (TTI-TEMPO) backend. This module is based on [Link2024]. + +**[Link2024]** +V. Link, H. Tu, and W. T. Strunz, *Open Quantum System Dynamics from Infinite +Tensor Network Contraction*, `Phys. Rev. Lett. 132, 200403 +`__ (2024). + +Original code taken from https://github.com/val-link/iTEBD-TEMPO.git +# Implementation of iTEBD-TEMPO +# Author: Valentin Link (valentin.link@tu-dresden.de) +# Original code from https://github.com/val-link/iTEBD-TEMPO.git +# Modified by Paul Eastham (easthamp@tcd.ie) to use the OQuPy BathCorrelations +# class to define the bath correlations rather than the bath correlation +# function itself. +# Please cite the corresponding publication: +# https://doi.org/10.1103/PhysRevLett.132.200403. +""" + +from typing import Callable, Dict + +import numpy as np +from scipy.linalg import norm, svd +from scipy.sparse.linalg import eigs + +from oqupy.process_tensor import SimpleProcessTensorInfinite + +class TTITempoBackend(): + """ + Base class for TTI process tensor tempo backends. + + Parameters + ---------- + influence: callable(int) -> ndarray + Callable that takes an integer `step` and returns the influence super + operator of that `step`. + process_tensor: BaseProcessTensor + Todo + dkmax: int + Number of influences to include. If ``dkmax == None`` then all + influences are included. + epsrel: float + Maximal relative SVD truncation error. + rank: int + Maximal SVD truncation rank + config: Dict + Todo + """ + + def __init__( + self, + dimension: int, + influence: Callable[[int], np.ndarray], + process_tensor: SimpleProcessTensorInfinite, + dkmax: int, + epsrel: float, + rank: int, + config: Dict): + + self.repeating_cell = (1, 1) + self._dkmax = dkmax + self._dimension = dimension + self._influence = influence + self._process_tensor = process_tensor + self._nu_dim = self._dimension**2 + 1 + self._epsrel = epsrel + self._rank = rank + self._itol = config["itol"] + self._A = None + self._B = None + self._sAB = None + self._sBA = None + self._rank_is_one = None + self._step = None + + @property + def step(self) -> int: + """The current step in the TTI-TEMPO computation. """ + return self._step + + @property + def num_steps(self) -> int: + """The current step in the TTI-TEMPO computation. """ + return self._dkmax + + def initialize(self) -> None: + """Initializes the iTEBD algorithm. """ + self._A = np.ones((1, self._nu_dim, 1)) + self._B = np.ones((1, self._nu_dim, 1)) + self._sAB = np.ones((1)) + self._sBA = np.ones((1)) + self._rank_is_one = True + self._step = 1 + + def compute_step(self) -> None: + """ + Compute a step of the iTEBD algorithm. + """ + i_tens = self._influence(self._dkmax - self._step) + + if self._step % 2 == 0: + self._sBA, self._sAB = self._sAB, self._sBA + self._B, self._A, = self._A, self._B + + # renormalize weights + self._sAB = self._sAB * norm(self._sBA) + self._sBA = self._sBA / norm(self._sBA) + + # ensure weights are above tolerance (needed for inversion) + self._sBA[np.abs(self._sBA) < self._itol] = self._itol + + # MPS - gate contraction + d1 = i_tens.shape[1] + d2 = i_tens.shape[-1] + rank_BA = self._sBA.shape[0] + + if self._step == self._dkmax: + d1 = 1 + u, s_vals, v = svd(np.einsum('a,acd,d,dcg,g,i,c->aicg', self._sBA, + self._A, self._sAB, self._B, self._sBA, + np.ones((1)), np.diagonal(i_tens) + ).reshape([d1*rank_BA, d2*rank_BA]), + full_matrices=False) + else: + u, s_vals, v = svd(np.einsum('a,acd,d,dfg,g,fc->afcg', self._sBA, + self._A, self._sAB, self._B, self._sBA, + i_tens + ).reshape([d1*rank_BA, d2*rank_BA]), + full_matrices=False) + + # truncate singular values + if self._epsrel is None: + rank_new = min(self._rank, len(s_vals)) + else: + s_vals_sum = np.cumsum(s_vals) / np.sum(s_vals) + rank_rtol = np.searchsorted(s_vals_sum, 1 - self._epsrel) + 1 + rank_new = min(self._rank, len(s_vals), rank_rtol) + u = u[:, :rank_new].reshape(self._sBA.shape[0], d1 * rank_new) + v = v[:rank_new, :].reshape(rank_new * d2, rank_BA) + + # factor out sAB weights from A and B + self._A = (np.diag(1 / self._sBA) @ u).reshape( + self._sBA.shape[0], d1, rank_new) + self._B = (v @ np.diag(1 / self._sBA)).reshape(rank_new, d2, rank_BA) + + # new weights + self._sAB = s_vals[:rank_new] + + if self._step % 2 == 0: + self._sBA, self._sAB = self._sAB, self._sBA + self._B, self._A, = self._A, self._B + + if self._rank_is_one: + if all([self._sAB.shape[0] == 1, self._sAB.shape[-1] == 1, + self._sBA.shape[0] == 1, self._sBA.shape[-1] == 1]): + # reset to initial mps if rank is still one + self._sAB = np.ones((1)) + self._sBA = np.ones((1)) + self._A = np.ones((1, self._nu_dim, 1)) + self._B = np.ones((1, self._nu_dim, 1)) + else: + self._rank_is_one = False +# print(f"Effective memory depth dkmax={self._dkmax - self._step + 1}") + if self._step == 1: + print("Warning: the memory cutoff dkmax may be too small"\ + "for the given epsrel value. The algorithm may"\ + "become unstable and inaccurate. It is recommended"\ + "to increase dkmax until this message does no"\ + "longer appear.") + self._step += 1 + return self._step-1 < self.num_steps + + def update_process_tensor(self) -> None: + """Update the process tensor. """ + assert self._step >= self._dkmax + f = np.squeeze(np.einsum('i,ikl,l,lop->ikop', self._sAB, self._B, + self._sBA, self._A)) + + if self._sAB.shape[0] == 1: + # handle trivial f + f = np.ones((1, self._nu_dim, 1)) + + # compute f[:,-1,:]^\inf = v_r * v_l^T using Lanczos + _, v_r = eigs(f[:, -1, :], 1, which='LR') + _, v_l = eigs(f[:, -1, :].T, 1, which='LR') + v_l = v_l / (v_l[:, 0] @ v_r[:, 0]) + + self._process_tensor.set_mpo_tensor(0, np.einsum('ia,ikj->ajk', + v_l, f[:,:-1,:])) + self._process_tensor.set_mpo_tensor(1, np.swapaxes(f[:,:-1,:], 1, 2)) + self._process_tensor.set_cap_tensor(0, np.array([1.0])) + self._process_tensor.set_cap_tensor(1, v_r[:, 0]) + try: + self._process_tensor.repeating_cell = self.repeating_cell + except Exception: + pass diff --git a/oqupy/bath_correlations.py b/oqupy/bath_correlations.py index 3bc40b4f..13312540 100644 --- a/oqupy/bath_correlations.py +++ b/oqupy/bath_correlations.py @@ -13,12 +13,13 @@ Module for environment correlations. """ -from typing import Callable, Optional, Text +from typing import Callable, Optional, Text,Dict from typing import Any as ArrayLike from functools import lru_cache import numpy as np from scipy import integrate +from scipy import special from oqupy.base_api import BaseAPIClass from oqupy.config import INTEGRATE_EPSREL, SUBDIV_LIMIT @@ -662,7 +663,7 @@ def correlation_2d_integral( if matsubara: integral = integral.real return integral - + class PowerLawSD(CustomSD): r""" @@ -757,3 +758,29 @@ def __str__(self) -> Text: ret.append(" zeta = {} \n".format(self.zeta)) return "".join(ret) + + def eta_function( + self, + tau: ArrayLike, + epsrel: Optional[float] = INTEGRATE_EPSREL, + subdiv_limit: Optional[int] = SUBDIV_LIMIT, + matsubara: Optional[bool] = False) -> ArrayLike: + r""" + Auto-correlation function associated to the spectral density at the + given temperature :math:`T`. Including analytical solution""" + + if self.cutoff_type == 'exponential' and self.zeta == 1 and not matsubara: + if self.temperature == 0.0: + + i1 = -2.0*self.alpha*np.log(1.0j*self.cutoff*tau+1.0) + i2 = 2.0*self.alpha*1j*tau*self.cutoff + + else: + + i1 = 2.0*self.alpha*sum([k2*np.real(special.loggamma(self.temperature/self.cutoff+(k1+1.0)/2+1j*self.temperature*tau*(k2+1.0)/2.0)) for k1 in [1.0,-1.0] for k2 in [1.0,-1.0]]) + i2 = -1j*2.0*self.alpha*(np.arctan(self.cutoff*tau)-self.cutoff*tau) + + return -(i1+i2) + + else: + return super().eta_function(tau,epsrel,subdiv_limit,matsubara) diff --git a/oqupy/bath_dynamics.py b/oqupy/bath_dynamics.py index b9b4cd45..563479e6 100644 --- a/oqupy/bath_dynamics.py +++ b/oqupy/bath_dynamics.py @@ -143,7 +143,64 @@ def generate_system_correlations( self._system_correlations = np.append(self._system_correlations, _new_sys_correlations, axis = 1) + def occupationTTI( + self, + freq: float, + n_steps:int, + dw: Optional[float] = 1.0, + change_only: Optional[bool] = False, + progress_type: Optional[Text] = None) -> Tuple[ndarray, ndarray]: + r""" + Function to calculate the change in bath occupation in a particular + bandwidth. Overloaded to include n_steps. + + Parameters + ---------- + freq: float + Central frequency of the frequency band. + dw: float + Width of the the frequency band. By default this method returns a + a *density* by setting the frequency band `dw=1.0`. + change_only: bool + Option to include the initial occupation (density) in the result. + progress_type: str (default = None) + The progress report type during the computation. Types are: + {``silent``, ``simple``, ``bar``}. If `None` then + the default progress type is used. + Returns + ------- + times: ndarray + Times of the occupation dynamics. + bath_occupation: ndarray + Occupation (density) (difference) of the bath in the specified + frequency band. + """ + corr_mat_dim = n_steps + dt = self._process_tensor.dt + last_time = corr_mat_dim * dt + tlist = np.arange(0, last_time+dt, dt) + if freq == 0: + return tlist, np.ones(len(tlist), + dtype=NpDtype) * (np.nan + 1.0j*np.nan) + self.generate_system_correlations(last_time, progress_type) + _sys_correlations = self._system_correlations[:corr_mat_dim, + :corr_mat_dim] + _sys_correlations = np.nan_to_num(_sys_correlations) + last_time = n_steps * self._process_tensor.dt + re_kernel, im_kernel = self._calc_kernel(freq, last_time, + freq, last_time, (1, 0)) + coup = self._bath.correlations.spectral_density(freq) * dw + bath_occupation = np.cumsum( + np.sum(_sys_correlations.real*re_kernel \ + + 1j*_sys_correlations.imag*im_kernel, axis = 0) + ).real * coup + bath_occupation = np.append([0], bath_occupation) + if not change_only and self._temp > 0: + bath_occupation += np.exp(-freq/self._temp) \ + / (1 - np.exp(-freq/self._temp)) + return tlist, bath_occupation + def occupation( self, freq: float, diff --git a/oqupy/config.py b/oqupy/config.py index 592dfa7b..398528f9 100644 --- a/oqupy/config.py +++ b/oqupy/config.py @@ -68,6 +68,12 @@ PT_TEBD_DEFAULT_EPSREL = 1.0e-5 +# -- TTI_TEMPO --------------------------------------------------------------- + +# Default TTI-TEMPO backend configuration +TTI_TEMPO_BACKEND_CONFIG = {"itol": 1e-13} + + # -- BATH -------------------------------------------------------------------- diff --git a/oqupy/counting_bath_correlations.py b/oqupy/counting_bath_correlations.py new file mode 100644 index 00000000..3caacdb1 --- /dev/null +++ b/oqupy/counting_bath_correlations.py @@ -0,0 +1,1263 @@ + +from typing import Callable, Dict, List, Optional, Text, Tuple, Union +from typing import Any as ArrayLike +from functools import lru_cache +from oqupy.config import INTEGRATE_EPSREL,SUBDIV_LIMIT +from oqupy.bath_correlations import CustomSD + + +import numpy as np + +from scipy import integrate +from scipy import special + + +class CustomCountingSD(CustomSD): + r""" + Correlations corresponding to a custom spectral density, with the counting fields. The resulting + spectral density is + + .. math:: + + J(\omega) = j(\omega) X(\omega,\omega_c) , + + with `j_function` :math:`j`, `cutoff` :math:`\omega_c` and a cutoff type + :math:`X`. + + If `cutoff_type` is + + - ``'hard'`` then + :math:`X(\omega,\omega_c)=\Theta(\omega_c-\omega)`, where + :math:`\Theta` is the Heaviside step function. + - ``'exponential'`` then + :math:`X(\omega,\omega_c)=\exp(-\omega/\omega_c)`. + - ``'gaussian'`` then + :math:`X(\omega,\omega_c)=\exp(-\omega^2/\omega_c^2)`. + + + Parameters + ---------- + j_function : callable + The spectral density :math:`j` without the cutoff. + cutoff : float + The cutoff frequency :math:`\omega_c`. + u : float + The value of the counting field :math: u at which to compute the correlation functions. + cutoff_type : str (default = ``'exponential'``) + The cutoff type. Types are: {``'hard'``, ``'exponential'``, + ``'gaussian'``} + temperature: float + The environment's temperature. + max_correlation_time : float + The maximal occuring correlation time :math:`\tau_\mathrm{max}`. + name: str + An optional name for the correlations. + description: str + An optional description of the correlations. + description_dict: dict + An optional dictionary with descriptive data. + """ + + def __init__( + self, + j_function: Callable[[float], float], + cutoff: float, + u: float, + cutoff_type: Optional[Text] = 'exponential', + temperature: Optional[float] = 0.0, + max_correlation_time: Optional[float] = None, + name: Optional[Text] = None, + description: Optional[Text] = None, + description_dict: Optional[Dict] = None) -> None: + """Create a CustomFunctionSD (spectral density) object. """ + self._u=u + super().__init__(j_function,cutoff,cutoff_type,temperature,name,description) + # self.alpha = j_function(0.5) ##### TODO Doesn't break anything + + def correlationA1( + self, + tau: ArrayLike, + epsrel: Optional[float] = INTEGRATE_EPSREL, + subdiv_limit: Optional[int] = SUBDIV_LIMIT) -> ArrayLike: + r""" + Counting-field dressed auto-correlation function A1 associated to the spectral density at the + given temperature :math:`T` + + .. math:: + + A_1(\tau) = \int_0^{\infty} J(\omega) \cos^2(u\omega/2)\ + \left[ \cos(\omega \tau) \ + \coth\left( \frac{\omega}{2 T}\right) \ + - i \sin(\omega \tau) \right] \mathrm{d}\omega . + + with time difference `tau` :math:`\tau`. + + Parameters + ---------- + tau : ndarray + Time difference :math:`\tau` + epsrel : float (default = 1.49e-08) + Relative error tollerance. + epsrel : float + Relative error tollerance. + subdiv_limit: int + Maximal number of interval subdivisions for numerical integration. + + Returns + ------- + correlation : ndarray + The auto-correlation function :math:`C(\tau)` at time :math:`\tau`. + """ + # real and imaginary part of the integrand + if self.temperature == 0.0: + re_integrand = lambda w: self._spectral_density(w) * (np.cos(self._u*w/2)**2.0) * np.cos(w*tau) + else: + re_integrand = lambda w: self._spectral_density(w) * (np.cos(self._u*w/2)**2.0) * np.cos(w*tau) \ + / np.tanh(w/(2.0*self.temperature)) + im_integrand = lambda w: -1.0 * self._spectral_density(w) * (np.cos(self._u*w/2)**2.0) \ + * np.sin(w*tau) + # real and imaginary part of the integral + re_int = integrate.quad(re_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int = integrate.quad(im_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + if self.cutoff_type != "hard": + re_int += integrate.quad(re_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int += integrate.quad(im_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + return re_int+1j*im_int + + def correlationA2( + self, + tau: ArrayLike, + epsrel: Optional[float] = INTEGRATE_EPSREL, + subdiv_limit: Optional[int] = SUBDIV_LIMIT) -> ArrayLike: + r""" + Counting-field dressed auto-correlation function A2 associated to the spectral density at the + given temperature :math:`T` + + .. math:: + + A_2(\tau) = \int_0^{\infty} J(\omega) \sin^2(u\omega/2)\ + \left[ \cos(\omega \tau) \ + \coth\left( \frac{\omega}{2 T}\right) \ + - i \sin(\omega \tau) \right] \mathrm{d}\omega . + + with time difference `tau` :math:`\tau`. + + Parameters + ---------- + tau : ndarray + Time difference :math:`\tau` + epsrel : float (default = 1.49e-08) + Relative error tollerance. + epsrel : float + Relative error tollerance. + subdiv_limit: int + Maximal number of interval subdivisions for numerical integration. + + Returns + ------- + correlation : ndarray + The auto-correlation function :math:`C(\tau)` at time :math:`\tau`. + """ + # real and imaginary part of the integrand + if self.temperature == 0.0: + re_integrand = lambda w: self._spectral_density(w) * (np.sin(self._u*w/2)**2.0) * np.cos(w*tau) + else: + re_integrand = lambda w: self._spectral_density(w) * (np.sin(self._u*w/2)**2.0) * np.cos(w*tau) \ + / np.tanh(w/(2.0*self.temperature)) + im_integrand = lambda w: -1.0 * self._spectral_density(w) * (np.sin(self._u*w/2)**2.0) \ + * np.sin(w*tau) + # real and imaginary part of the integral + re_int = integrate.quad(re_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int = integrate.quad(im_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + if self.cutoff_type != "hard": + re_int += integrate.quad(re_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int += integrate.quad(im_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + return re_int+1j*im_int + + def correlationC( + self, + tau: ArrayLike, + epsrel: Optional[float] = INTEGRATE_EPSREL, + subdiv_limit: Optional[int] = SUBDIV_LIMIT) -> ArrayLike: + r""" + Counting-field dressed auto-correlation function C associated to the spectral density at the + given temperature :math:`T` + + .. math:: + + A_1(\tau) = \int_0^{\infty} J(\omega) \cos^2(u\omega/2)\ + \left[ \cos(\omega \tau) \ + \coth\left( \frac{\omega}{2 T}\right) \ + - i \sin(\omega \tau) \right] \mathrm{d}\omega . + + with time difference `tau` :math:`\tau`. + + Parameters + ---------- + tau : ndarray + Time difference :math:`\tau` + epsrel : float (default = 1.49e-08) + Relative error tollerance. + epsrel : float + Relative error tollerance. + subdiv_limit: int + Maximal number of interval subdivisions for numerical integration. + + Returns + ------- + correlation : ndarray + The auto-correlation function :math:`C(\tau)` at time :math:`\tau`. + """ + # real and imaginary part of the integrand + if self.temperature == 0.0: + re_integrand = lambda w: -1.0 * self._spectral_density(w) * (np.sin(self._u*w)/2.0) * np.sin(w*tau) + else: + re_integrand = lambda w: -1.0 * self._spectral_density(w) * (np.sin(self._u*w)/2.0) * np.sin(w*tau) \ + / np.tanh(w/(2.0*self.temperature)) + im_integrand = lambda w: -1.0 * self._spectral_density(w) * (np.sin(self._u*w)/2.0) \ + * np.cos(w*tau) + # real and imaginary part of the integral + re_int = integrate.quad(re_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int = integrate.quad(im_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + if self.cutoff_type != "hard": + re_int += integrate.quad(re_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int += integrate.quad(im_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + return re_int+1j*im_int + + @lru_cache(maxsize=2**10, typed=False) + def correlation_2d_integral_marked_old( + self, + delta: float, + time_1: float, + time_2: Optional[float] = None, + shape: Optional[Text] = 'square', + which_corr: Optional[Text] = 'A1', + epsrel: Optional[float] = INTEGRATE_EPSREL, + subdiv_limit: Optional[int] = SUBDIV_LIMIT) -> complex: + r""" + 2D integrals of the correlation function + + .. math:: + + \eta_\mathrm{square} = + \int_{t_1}^{t_1+\Delta} \int_{0}^{\Delta} C(t'-t'') dt'' dt' + + \eta_\mathrm{upper-triangle} = + \int_{t_1}^{t_1+\Delta} \int_{0}^{t'-t_1} C(t'-t'') dt'' dt' + + \eta_\mathrm{lower-triangle} = + \int_{t_1}^{t_1+\Delta} \int_{t'-t_1}^{\Delta} C(t'-t'') dt'' dt' + + \eta_\mathrm{rectangle} = + \int_{t_1}^{t_2} \int_{0}^{\Delta} C(t'-t'') dt'' dt' + + for `shape` either ``'square'``, ``'upper-triangle'``, + ``'lower-triangle'``, or ``'rectangle'``. + + Parameters + ---------- + delta : float + Length of integration intevals. + time_1 : float + Lower bound of integration interval of :math:`dt'`. + time_2 : float + Upper bound of integration interval of :math:`dt'` for `shape` = + ``'rectangle'``. + shape : str (default = ``'square'``) + The shape of the 2D integral. Shapes are: {``'square'``, + ``'upper-triangle'``, ``'lower-triangle'``, ``'lower-triangle'``} + epsrel : float + Relative error tollerance. + subdiv_limit: int + Maximal number of interval subdivisions for numerical integration. + + Returns + ------- + integral : float + The numerical value for the two dimensional integral + :math:`\eta_\mathrm{shape}`. + """ + + selected_corr={ + 'A1': self.correlationA1, + 'A2': self.correlationA2, + 'C': self.correlationC, + } + + c_real = lambda y, x: np.real(selected_corr[which_corr](x-y)) + c_imag = lambda y, x: np.imag(selected_corr[which_corr](x-y)) + + if time_2 is None: + time_2 = time_1 + delta + else: + assert shape == 'rectangle', \ + "paramter 'time_2' can only be used in conjunction with " \ + "'shape' = ``rectangle`` !" + + lower_boundary = {'square': lambda x: 0.0, + 'upper-triangle': lambda x: 0.0, + 'lower-triangle': lambda x: x-time_1, + 'rectangle': lambda x: 0.0} + upper_boundary = {'square': lambda x: delta, + 'upper-triangle': lambda x: x-time_1, + 'lower-triangle': lambda x: delta, + 'rectangle': lambda x: delta,} + + int_real = integrate.dblquad(func=c_real, + a=time_1, + b=time_2, + gfun=lower_boundary[shape], + hfun=upper_boundary[shape], + epsrel=epsrel)[0] + int_imag = integrate.dblquad(func=c_imag, + a=time_1, + b=time_2, + gfun=lower_boundary[shape], + hfun=upper_boundary[shape], + epsrel=epsrel)[0] + return int_real+1.0j*int_imag + + @lru_cache(maxsize=2**10, typed=False) + def correlation_2d_integral_marked( + self, + delta: float, + time_1: float, + time_2: Optional[float] = None, + shape: Optional[Text] = 'square', + which_corr: Optional[Text] = 'A1', + epsrel: Optional[float] = INTEGRATE_EPSREL, + subdiv_limit: Optional[int] = SUBDIV_LIMIT) -> complex: + r""" + 2D integrals of the correlation function + + .. math:: + + \eta_\mathrm{square} = + \int_{t_1}^{t_1+\Delta} \int_{0}^{\Delta} C(t'-t'') dt'' dt' + + \eta_\mathrm{upper-triangle} = + \int_{t_1}^{t_1+\Delta} \int_{0}^{t'-t_1} C(t'-t'') dt'' dt' + + \eta_\mathrm{lower-triangle} = + \int_{t_1}^{t_1+\Delta} \int_{t'-t_1}^{\Delta} C(t'-t'') dt'' dt' + + \eta_\mathrm{rectangle} = + \int_{t_1}^{t_2} \int_{0}^{\Delta} C(t'-t'') dt'' dt' + + for `shape` either ``'square'``, ``'upper-triangle'``, + ``'lower-triangle'``, or ``'rectangle'``. + + Parameters + ---------- + delta : float + Length of integration intevals. + time_1 : float + Lower bound of integration interval of :math:`dt'`. + time_2 : float + Upper bound of integration interval of :math:`dt'` for `shape` = + ``'rectangle'``. + shape : str (default = ``'square'``) + The shape of the 2D integral. Shapes are: {``'square'``, + ``'upper-triangle'``, ``'lower-triangle'``, ``'lower-triangle'``} + epsrel : float + Relative error tollerance. + subdiv_limit: int + Maximal number of interval subdivisions for numerical integration. + + Returns + ------- + integral : float + The numerical value for the two dimensional integral + :math:`\eta_\mathrm{shape}`. + """ + + if (which_corr=='A1'): + # real and imaginary part of the integrand + if self.temperature == 0.0: + re_integrand = lambda w: \ + (np.cos(self._u*w/2.0)**2)*self._spectral_density(w) \ + * INTEGRAND_DICT[shape][0](w, + delta, + time_1, + time_2, + self.temperature) + else: + re_integrand = lambda w: \ + (np.cos(self._u*w/2.0)**2)*self._spectral_density(w) \ + * INTEGRAND_DICT[shape][1](w, + delta, + time_1, + time_2, + self.temperature) + im_integrand = lambda w: \ + (np.cos(self._u*w/2.0)**2)*self._spectral_density(w) \ + * INTEGRAND_DICT[shape][2](w, + delta, + time_1, + time_2, + self.temperature) + + elif (which_corr=='A2'): + if self.temperature == 0.0: + re_integrand = lambda w: \ + (np.sin(self._u*w/2)**2)*self._spectral_density(w) \ + * INTEGRAND_DICT[shape][0](w, + delta, + time_1, + time_2, + self.temperature) + else: + re_integrand = lambda w: \ + (np.sin(self._u*w/2.0)**2)*self._spectral_density(w) \ + * INTEGRAND_DICT[shape][1](w, + delta, + time_1, + time_2, + self.temperature) + im_integrand = lambda w: \ + (np.sin(self._u*w/2.0)**2)*self._spectral_density(w) \ + * INTEGRAND_DICT[shape][2](w, + delta, + time_1, + time_2, + self.temperature) + elif (which_corr=='C'): + if self.temperature == 0.0: + re_integrand = lambda w: \ + (np.sin(self._u*w)/2.0)*self._spectral_density(w) \ + * INTEGRAND_DICT_C[shape][0](w, + delta, + time_1, + time_2, + self.temperature) + else: + re_integrand = lambda w: \ + (np.sin(self._u*w)/2.0)*self._spectral_density(w) \ + * INTEGRAND_DICT_C[shape][1](w, + delta, + time_1, + time_2, + self.temperature) + im_integrand = lambda w: \ + -1.0*(np.sin(self._u*w)/2.0)*self._spectral_density(w) \ + * INTEGRAND_DICT_C[shape][2](w, + delta, + time_1, + time_2, + self.temperature) + + # real and imaginary part of the integral + re_int = integrate.quad(re_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int = integrate.quad(im_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + if self.cutoff_type != "hard": + re_int += integrate.quad(re_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int += integrate.quad(im_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + + return re_int+1j*im_int + + + +# Class which contains analytical results for an Ohmic spectral density with exponential cut-off +class CustomCountingSD_analytical(CustomSD): + r""" + Correlations corresponding to a custom spectral density, with the counting fields. The resulting + spectral density is + + .. math:: + + J(\omega) = j(\omega) X(\omega,\omega_c) , + + with `j_function` :math:`j`, `cutoff` :math:`\omega_c` and a cutoff type + :math:`X`. + + If `cutoff_type` is + + - ``'hard'`` then + :math:`X(\omega,\omega_c)=\Theta(\omega_c-\omega)`, where + :math:`\Theta` is the Heaviside step function. + - ``'exponential'`` then + :math:`X(\omega,\omega_c)=\exp(-\omega/\omega_c)`. + - ``'gaussian'`` then + :math:`X(\omega,\omega_c)=\exp(-\omega^2/\omega_c^2)`. + + + Parameters + ---------- + j_function : callable + The spectral density :math:`j` without the cutoff. + cutoff : float + The cutoff frequency :math:`\omega_c`. + u : float + The value of the counting field :math: u at which to compute the correlation functions. + cutoff_type : str (default = ``'exponential'``) + The cutoff type. Types are: {``'hard'``, ``'exponential'``, + ``'gaussian'``} + temperature: float + The environment's temperature. + max_correlation_time : float + The maximal occuring correlation time :math:`\tau_\mathrm{max}`. + name: str + An optional name for the correlations. + description: str + An optional description of the correlations. + description_dict: dict + An optional dictionary with descriptive data. + """ + + def __init__( + self, + j_function: Callable[[float], float], + cutoff: float, + u: float, + zeta: Optional[float]=1, + cutoff_type: Optional[Text] = 'exponential', + temperature: Optional[float] = 0.0, + max_correlation_time: Optional[float] = None, + name: Optional[Text] = None, + description: Optional[Text] = None, + description_dict: Optional[Dict] = None) -> None: + """Create a CustomFunctionSD (spectral density) object. """ + self._u=u + self.zeta=zeta + super().__init__(j_function,cutoff,cutoff_type,temperature,name,description) + self.alpha = j_function(0.5) + + def correlationA1( + self, + tau: ArrayLike, + epsrel: Optional[float] = INTEGRATE_EPSREL, + subdiv_limit: Optional[int] = SUBDIV_LIMIT) -> ArrayLike: + r""" + Counting-field dressed auto-correlation function A1 associated to the spectral density at the + given temperature :math:`T` + + .. math:: + + A_1(\tau) = \int_0^{\infty} J(\omega) \cos^2(u\omega/2)\ + \left[ \cos(\omega \tau) \ + \coth\left( \frac{\omega}{2 T}\right) \ + - i \sin(\omega \tau) \right] \mathrm{d}\omega . + + with time difference `tau` :math:`\tau`. + + Parameters + ---------- + tau : ndarray + Time difference :math:`\tau` + epsrel : float (default = 1.49e-08) + Relative error tollerance. + epsrel : float + Relative error tollerance. + subdiv_limit: int + Maximal number of interval subdivisions for numerical integration. + + Returns + ------- + correlation : ndarray + The auto-correlation function :math:`C(\tau)` at time :math:`\tau`. + """ + # real and imaginary part of the integrand + if self.temperature == 0.0: + re_integrand = lambda w: self._spectral_density(w) * (np.cos(self._u*w/2)**2.0) * np.cos(w*tau) + else: + re_integrand = lambda w: self._spectral_density(w) * (np.cos(self._u*w/2)**2.0) * np.cos(w*tau) \ + / np.tanh(w/(2.0*self.temperature)) + im_integrand = lambda w: -1.0 * self._spectral_density(w) * (np.cos(self._u*w/2)**2.0) \ + * np.sin(w*tau) + # real and imaginary part of the integral + re_int = integrate.quad(re_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int = integrate.quad(im_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + if self.cutoff_type != "hard": + re_int += integrate.quad(re_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int += integrate.quad(im_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + return re_int+1j*im_int + + def correlationA2( + self, + tau: ArrayLike, + epsrel: Optional[float] = INTEGRATE_EPSREL, + subdiv_limit: Optional[int] = SUBDIV_LIMIT) -> ArrayLike: + r""" + Counting-field dressed auto-correlation function A2 associated to the spectral density at the + given temperature :math:`T` + + .. math:: + + A_2(\tau) = \int_0^{\infty} J(\omega) \sin^2(u\omega/2)\ + \left[ \cos(\omega \tau) \ + \coth\left( \frac{\omega}{2 T}\right) \ + - i \sin(\omega \tau) \right] \mathrm{d}\omega . + + with time difference `tau` :math:`\tau`. + + Parameters + ---------- + tau : ndarray + Time difference :math:`\tau` + epsrel : float (default = 1.49e-08) + Relative error tollerance. + epsrel : float + Relative error tollerance. + subdiv_limit: int + Maximal number of interval subdivisions for numerical integration. + + Returns + ------- + correlation : ndarray + The auto-correlation function :math:`C(\tau)` at time :math:`\tau`. + """ + # real and imaginary part of the integrand + if self.temperature == 0.0: + re_integrand = lambda w: self._spectral_density(w) * (np.sin(self._u*w/2)**2.0) * np.cos(w*tau) + else: + re_integrand = lambda w: self._spectral_density(w) * (np.sin(self._u*w/2)**2.0) * np.cos(w*tau) \ + / np.tanh(w/(2.0*self.temperature)) + im_integrand = lambda w: -1.0 * self._spectral_density(w) * (np.sin(self._u*w/2)**2.0) \ + * np.sin(w*tau) + # real and imaginary part of the integral + re_int = integrate.quad(re_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int = integrate.quad(im_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + if self.cutoff_type != "hard": + re_int += integrate.quad(re_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int += integrate.quad(im_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + return re_int+1j*im_int + + def correlationC( + self, + tau: ArrayLike, + epsrel: Optional[float] = INTEGRATE_EPSREL, + subdiv_limit: Optional[int] = SUBDIV_LIMIT) -> ArrayLike: + r""" + Counting-field dressed auto-correlation function C associated to the spectral density at the + given temperature :math:`T` + + .. math:: + + A_1(\tau) = \int_0^{\infty} J(\omega) \cos^2(u\omega/2)\ + \left[ \cos(\omega \tau) \ + \coth\left( \frac{\omega}{2 T}\right) \ + - i \sin(\omega \tau) \right] \mathrm{d}\omega . + + with time difference `tau` :math:`\tau`. + + Parameters + ---------- + tau : ndarray + Time difference :math:`\tau` + epsrel : float (default = 1.49e-08) + Relative error tollerance. + epsrel : float + Relative error tollerance. + subdiv_limit: int + Maximal number of interval subdivisions for numerical integration. + + Returns + ------- + correlation : ndarray + The auto-correlation function :math:`C(\tau)` at time :math:`\tau`. + """ + # real and imaginary part of the integrand + if self.temperature == 0.0: + re_integrand = lambda w: -1.0 * self._spectral_density(w) * (np.sin(self._u*w)/2.0) * np.sin(w*tau) + else: + re_integrand = lambda w: -1.0 * self._spectral_density(w) * (np.sin(self._u*w)/2.0) * np.sin(w*tau) \ + / np.tanh(w/(2.0*self.temperature)) + im_integrand = lambda w: -1.0 * self._spectral_density(w) * (np.sin(self._u*w)/2.0) \ + * np.cos(w*tau) + # real and imaginary part of the integral + re_int = integrate.quad(re_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int = integrate.quad(im_integrand, + a=0.0, + b=self.cutoff, + epsrel=epsrel, + limit=subdiv_limit)[0] + if self.cutoff_type != "hard": + re_int += integrate.quad(re_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + im_int += integrate.quad(im_integrand, + a=self.cutoff, + b=np.inf, + epsrel=epsrel, + limit=subdiv_limit)[0] + return re_int+1j*im_int + + @lru_cache(maxsize=2**10, typed=False) + def eta_function_marked( + self, + tau: ArrayLike, + epsrel: Optional[float] = INTEGRATE_EPSREL, + subdiv_limit: Optional[int] = SUBDIV_LIMIT, + matsubara: Optional[bool] = False, + which_corr: Optional[Text] = 'A1' ) -> ArrayLike: + r""" obtained for ohmic baths with exponential cutoff""" + + # only real part changed at zero/finite temp + if (which_corr=='A1'): + if self.temperature == 0.0: + i1 = (self.alpha/4.0)*(2*np.log(1 + (self.cutoff*tau)**2)+ np.log(1 + (self.cutoff*(tau+self._u))**2)+ np.log(1 + (self.cutoff*(tau-self._u))**2) - 2*np.log(1 + (self.cutoff*self._u)**2)) + else: + i1 = 0.5*self.alpha*sum([k4*np.real(special.loggamma(self.temperature/self.cutoff+(k1+1.0)/2+1j*(k2+k3)/2*self._u*self.temperature+1j*self.temperature*tau*(k4+1.0)/2.0)) for k1 in [1.0,-1.0] for k2 in [1.0,-1.0] for k3 in [1.0,-1.0] for k4 in [1.0,-1.0]]) + i2 = -1j*self.alpha*(np.arctan(self.cutoff*tau)+0.5*np.arctan(self.cutoff*(self._u+tau))-0.5*np.arctan(self.cutoff*(self._u-tau)))\ + +1.0j*self.alpha*self.cutoff*tau*(1.0+1.0/(1+(self._u*self.cutoff)**2)) + + elif (which_corr=='A2'): + if self.temperature == 0.0: + i1= -(self.alpha/4.0) * (np.log(1+(self.cutoff*(tau-self._u))**2)-2*np.log((1+(self.cutoff*tau)**2)*(1+(self.cutoff*self._u)**2)) + np.log(1+(self.cutoff*(tau+self._u))**2)) + else: + i1 = 2.0*self.alpha*sum([k4*np.real(special.loggamma(self.temperature/self.cutoff+(k1+1.0)/2+1j*self.temperature*tau*(k4+1.0)/2.0)) for k1 in [1.0,-1.0] for k4 in [1.0,-1.0]]) \ + -0.5*self.alpha*sum([k4*np.real(special.loggamma(self.temperature/self.cutoff+(k1+1.0)/2+1j*(k2+k3)/2*self._u*self.temperature+1j*self.temperature*tau*(k4+1.0)/2.0)) for k1 in [1.0,-1.0] for k2 in [1.0,-1.0] for k3 in [1.0,-1.0] for k4 in [1.0,-1.0]]) + i2 = -2j*self.alpha*np.arctan(self.cutoff*tau)+2.0j*self.alpha*self.cutoff*tau \ + +1j*self.alpha*(np.arctan(self.cutoff*tau)+0.5*np.arctan(self.cutoff*(self._u+tau))-0.5*np.arctan(self.cutoff*(self._u-tau)))\ + -1.0j*self.alpha*self.cutoff*tau*(1.0+1.0/(1+(self._u*self.cutoff)**2)) + + elif (which_corr=='C'): + if self.temperature == 0.0: + i1= (self.alpha/2.0) * (-(2*tau*self._u*self.cutoff**2)/(1+(self._u*self.cutoff)**2) + np.arctanh(2*tau*self._u*self.cutoff**2/(1+(tau**2+self._u**2)*self.cutoff**2))) + else: + i1 = -self.alpha/2*sum([k2*k3*np.real(special.loggamma(self.temperature/self.cutoff+(k1+1.0)/2+1j*self.temperature*(self._u-k3*tau)*(k2+1.0)/2.0)) for k1 in [1.0,-1.0] for k2 in [1.0,-1.0] for k3 in [1.0,-1.0] ]) + i2 = -self.alpha*self.temperature*tau*sum([np.imag( special.digamma(self.temperature/self.cutoff+(k1+1.0)/2-1.0j*self._u*self.temperature) ) for k1 in [1.0,-1.0]]) + i2 += -1j*self.alpha/2*(np.arctan(self.cutoff*(tau+self._u))-np.arctan(self.cutoff*(tau-self._u))-2.0*np.arctan(self._u*self.cutoff)) + + + return -i1-i2 + + def correlation_2d_integral_marked( + self, + delta: float, + time_1: float, + time_2: Optional[float] = None, + shape: Optional[Text] = 'square', + which_corr: Optional[Text] = 'A1', + epsrel: Optional[float] = INTEGRATE_EPSREL, + subdiv_limit: Optional[int] = SUBDIV_LIMIT, + matsubara: Optional[bool] = False) -> complex: + r""" + 2D integrals of the correlation function + + .. math:: + + \eta_\mathrm{square} = + \int_{t_1}^{t_1+\Delta} \int_{0}^{\Delta} C(t'-t'') dt'' dt' + + \eta_\mathrm{upper-triangle} = + \int_{t_1}^{t_1+\Delta} \int_{0}^{t'-t_1} C(t'-t'') dt'' dt' + + \eta_\mathrm{rectangle} = + \int_{t_1}^{t_2} \int_{0}^{\Delta} C(t'-t'') dt'' dt' + + for `shape` either ``'square'``, ``'upper-triangle'``, + or ``'rectangle'``. + + Parameters + ---------- + delta : float + Length of integration intervals. + time_1 : float + Lower bound of integration interval of :math:`dt'`. + time_2 : float + Upper bound of integration interval of :math:`dt'` for `shape` = + ``'rectangle'``. + shape : str (default = ``'square'``) + The shape of the 2D integral. Shapes are: {``'square'``, + ``'upper-triangle'``, ``'rectangle'``} + epsrel : float + Relative error tolerance. + subdiv_limit: int + Maximal number of interval subdivisions for numerical integration. + + Returns + ------- + integral : float + The numerical value for the two dimensional integral + :math:`\eta_\mathrm{shape}`. + """ + kwargs = { + 'epsrel': epsrel, + 'subdiv_limit': subdiv_limit, + 'matsubara': matsubara, + 'which_corr': which_corr} + + if shape == 'upper-triangle': + integral = self.eta_function_marked(time_1 + delta, **kwargs) \ + - self.eta_function_marked(time_1, **kwargs) + elif shape == 'square': + integral = self.eta_function_marked(time_1 + delta, **kwargs) \ + - 2.0 * self.eta_function_marked(time_1, **kwargs) \ + + self.eta_function_marked(time_1 - delta, **kwargs) + elif shape == 'rectangle': + integral = self.eta_function_marked(time_2, **kwargs) \ + - self.eta_function_marked(time_1, **kwargs) \ + - self.eta_function_marked(time_2 - delta, **kwargs) \ + + self.eta_function_marked(time_1 - delta, **kwargs) + else: + raise NotImplementedError("Shape '{shape}' not implemented.") + + if matsubara: + integral = integral.real + return integral + + + +# === CORRELATIONS FROM SPECTRAL DENSITIES ==================================== + + +# --- the cutoffs ------------------------------------------------------------- + +def _hard_cutoff(omega: ArrayLike, omega_c: float) -> ArrayLike: + """Hard cutoff function.""" + return np.heaviside(omega_c - omega, 0) + +def _exponential_cutoff(omega: ArrayLike, omega_c: float) -> ArrayLike: + """Exponential cutoff function.""" + return np.exp(-omega/omega_c) + +def _gaussian_cutoff(omega: ArrayLike, omega_c: float) -> ArrayLike: + """Gaussian cutoff function.""" + return np.exp(-(omega/omega_c)**2) + +# dictionary for the various cutoffs in the form: +# 'cutoff_name': cutoff_function +CUTOFF_DICT = { + 'hard':_hard_cutoff, + 'exponential':_exponential_cutoff, + 'gaussian':_gaussian_cutoff, + } + +# --- 2d integrals ------------------------------------------------------------ + +def _2d_square_integrand_real( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of square 2D time integral at zero + temperature without J(omega). """ + return 1.0/omega**2 * 2 * np.cos(time_1*omega) * (1 - np.cos(delta*omega)) + +def _2d_square_integrand_real_t( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of square 2D time integral at finite + temperature without J(omega). """ + integrand = 1.0/omega**2 * 2 * np.cos(time_1*omega) \ + * (1 - np.cos(delta*omega)) + return integrand / np.tanh(omega/(2*temperature)) + +def _2d_square_integrand_imag( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for imaginary part of square 2D time integral without + J(omega). """ + return -1.0/omega**2 * 2 * np.sin(time_1*omega) * (1 - np.cos(delta*omega)) + +def _2d_upper_triangle_integrand_real( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of upper triangle 2D time integral at zero + temperature without J(omega). """ + return 1.0/omega**2 * (np.cos(omega*time_1) \ + - np.cos(omega*(time_1+delta)) \ + - omega * delta * np.sin(omega*time_1)) + +def _2d_upper_triangle_integrand_real_t( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of upper triangle 2D time integral at finite + temperature without J(omega). """ + return 1.0/omega**2 * (np.cos(omega*time_1) \ + - np.cos(omega*(time_1+delta)) \ + - omega * delta * np.sin(omega*time_1)) \ + / np.tanh(omega/(2*temperature)) + +def _2d_upper_triangle_integrand_imag( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for imaginary part of upper triangle 2D time integral without + J(omega). """ + return -1.0/omega**2 * (np.sin(omega*time_1) \ + - np.sin(omega*(time_1+delta)) \ + + omega * delta * np.cos(omega*time_1)) + +def _2d_lower_triangle_integrand_real( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of lower triangle 2D time integral at zero + temperature without J(omega). """ + return 1.0/omega**2 * (np.cos(omega*time_1) \ + - np.cos(omega*(time_1-delta)) \ + + omega * delta * np.sin(omega*time_1)) + +def _2d_lower_triangle_integrand_real_t( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of lower triangle 2D time integral at finite + temperature without J(omega). """ + return 1.0/omega**2 * (np.cos(omega*time_1) \ + - np.cos(omega*(time_1-delta)) \ + + omega * delta * np.sin(omega*time_1)) \ + / np.tanh(omega/(2*temperature)) + +def _2d_lower_triangle_integrand_imag( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for imaginary part of lower triangle 2D time integral without + J(omega). """ + return -1.0/omega**2 * (np.sin(omega*time_1) + - np.sin(omega*(time_1-delta)) + - omega * delta * np.cos(omega*time_1)) + +def _2d_rectangle_integrand_real( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of rectangle 2D time integral at zero + temperature without J(omega). """ + return 1.0/omega**2 * (np.cos((time_2 - delta) * omega) + - np.cos((time_1 - delta) * omega) + - np.cos(time_2 * omega) + + np.cos(time_1 * omega)) + +def _2d_rectangle_integrand_real_t( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of rectangle 2D time integral at finite + temperature without J(omega). """ + integrand = 1.0/omega**2 * (np.cos((time_2 - delta) * omega) + - np.cos((time_1 - delta) * omega) + - np.cos(time_2 * omega) + + np.cos(time_1 * omega)) + return integrand / np.tanh(omega/(2*temperature)) + +def _2d_rectangle_integrand_imag( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for imaginary part of rectangle 2D time integral without + J(omega). """ + return -1.0/omega**2 * (np.sin((time_2 - delta) * omega) + - np.sin((time_1 - delta) * omega) + - np.sin(time_2 * omega) + + np.sin(time_1 * omega)) + + +# dictionary for the various integrands for the 2d time integral +INTEGRAND_DICT = { + 'square': (_2d_square_integrand_real, + _2d_square_integrand_real_t, + _2d_square_integrand_imag), + 'upper-triangle': (_2d_upper_triangle_integrand_real, + _2d_upper_triangle_integrand_real_t, + _2d_upper_triangle_integrand_imag), + 'lower-triangle': (_2d_lower_triangle_integrand_real, + _2d_lower_triangle_integrand_real_t, + _2d_lower_triangle_integrand_imag), + 'rectangle': (_2d_rectangle_integrand_real, + _2d_rectangle_integrand_real_t, + _2d_rectangle_integrand_imag), + } + + +## new class to calculate the correlation functions for the case with heat markers/counting fields + +# --- 2d integrals for the C correlation function (the A1 and A2 use the same as before) --- +# note that the 2d integral for C and those for A1 are related as +# Re part of integral for C is Im part of that for A1 times the temperature factor +# Im part of integral for C is Re part of that for A1 without the temperature factor +# This may be a slightly clunky way to do it but hope it is clear. This code was +# constructed by editing the square_integrand case, then cut-and-paste and replace square with the relevant +# text for the other cases. + +def _2d_square_integrand_C_real( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of square 2D time integral at zero + temperature without J(omega). """ + #return 1.0/omega**2 * 2 * np.cos(time_1*omega) * (1 - np.cos(delta*omega)) + return _2d_square_integrand_imag(omega,delta,time_1,time_2,temperature) + +def _2d_square_integrand_C_real_t( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of square 2D time integral at finite + temperature without J(omega). """ + #integrand = 1.0/omega**2 * 2 * np.cos(time_1*omega) \ + # * (1 - np.cos(delta*omega)) + integrand = _2d_square_integrand_imag(omega,delta,time_1,time_2,temperature) + return integrand / np.tanh(omega/(2*temperature)) + +def _2d_square_integrand_C_imag( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for imaginary part of square 2D time integral without + J(omega). """ + #return -1.0/omega**2 * 2 * np.sin(time_1*omega) * (1 - np.cos(delta*omega)) + return _2d_square_integrand_real(omega,delta,time_1,time_2,temperature) + +# above code copied then search and replace square->upper_triangle +def _2d_upper_triangle_integrand_C_real( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of square 2D time integral at zero + temperature without J(omega). """ + #return 1.0/omega**2 * 2 * np.cos(time_1*omega) * (1 - np.cos(delta*omega)) + return _2d_upper_triangle_integrand_imag(omega,delta,time_1,time_2,temperature) + +def _2d_upper_triangle_integrand_C_real_t( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of square 2D time integral at finite + temperature without J(omega). """ + #integrand = 1.0/omega**2 * 2 * np.cos(time_1*omega) \ + # * (1 - np.cos(delta*omega)) + integrand = _2d_upper_triangle_integrand_imag(omega,delta,time_1,time_2,temperature) + return integrand / np.tanh(omega/(2*temperature)) + +def _2d_upper_triangle_integrand_C_imag( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for imaginary part of square 2D time integral without + J(omega). """ + #return -1.0/omega**2 * 2 * np.sin(time_1*omega) * (1 - np.cos(delta*omega)) + return _2d_upper_triangle_integrand_real(omega,delta,time_1,time_2,temperature) + +# above code copied then search and replace square->lower_triangle +def _2d_lower_triangle_integrand_C_real( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of square 2D time integral at zero + temperature without J(omega). """ + #return 1.0/omega**2 * 2 * np.cos(time_1*omega) * (1 - np.cos(delta*omega)) + return _2d_lower_triangle_integrand_imag(omega,delta,time_1,time_2,temperature) + +def _2d_lower_triangle_integrand_C_real_t( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of square 2D time integral at finite + temperature without J(omega). """ + #integrand = 1.0/omega**2 * 2 * np.cos(time_1*omega) \ + # * (1 - np.cos(delta*omega)) + integrand = _2d_lower_triangle_integrand_imag(omega,delta,time_1,time_2,temperature) + return integrand / np.tanh(omega/(2*temperature)) + +def _2d_lower_triangle_integrand_C_imag( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for imaginary part of square 2D time integral without + J(omega). """ + #return -1.0/omega**2 * 2 * np.sin(time_1*omega) * (1 - np.cos(delta*omega)) + return _2d_lower_triangle_integrand_real(omega,delta,time_1,time_2,temperature) + +# above code copied then search and replace square->rectangle + +def _2d_rectangle_integrand_C_real( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of square 2D time integral at zero + temperature without J(omega). """ + #return 1.0/omega**2 * 2 * np.cos(time_1*omega) * (1 - np.cos(delta*omega)) + return _2d_rectangle_integrand_imag(omega,delta,time_1,time_2,temperature) + +def _2d_rectangle_integrand_C_real_t( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for real part of square 2D time integral at finite + temperature without J(omega). """ + #integrand = 1.0/omega**2 * 2 * np.cos(time_1*omega) \ + # * (1 - np.cos(delta*omega)) + integrand = _2d_rectangle_integrand_imag(omega,delta,time_1,time_2,temperature) + return integrand / np.tanh(omega/(2*temperature)) + +def _2d_rectangle_integrand_C_imag( + omega: ArrayLike, + delta: float, + time_1: float, + time_2: Optional[float] = None, + temperature: Optional[float] = None) -> ArrayLike: + """Integrand for imaginary part of square 2D time integral without + J(omega). """ + #return -1.0/omega**2 * 2 * np.sin(time_1*omega) * (1 - np.cos(delta*omega)) + return _2d_rectangle_integrand_real(omega,delta,time_1,time_2,temperature) + + +INTEGRAND_DICT_C = { + 'square': (_2d_square_integrand_C_real, + _2d_square_integrand_C_real_t, + _2d_square_integrand_C_imag), + 'upper-triangle': (_2d_upper_triangle_integrand_C_real, + _2d_upper_triangle_integrand_C_real_t, + _2d_upper_triangle_integrand_C_imag), + 'lower-triangle': (_2d_lower_triangle_integrand_C_real, + _2d_lower_triangle_integrand_C_real_t, + _2d_lower_triangle_integrand_C_imag), + 'rectangle': (_2d_rectangle_integrand_C_real, + _2d_rectangle_integrand_C_real_t, + _2d_rectangle_integrand_C_imag), + } diff --git a/oqupy/gradient.py b/oqupy/gradient.py index 9c177436..29343b77 100644 --- a/oqupy/gradient.py +++ b/oqupy/gradient.py @@ -25,16 +25,20 @@ from oqupy.control import Control from oqupy.dynamics import Dynamics from oqupy.process_tensor import BaseProcessTensor -from oqupy.system import ParameterizedSystem +from oqupy.system import ParameterizedSystem,ParameterizedSystem2ls from oqupy.util import get_progress, check_isinstance +from functools import reduce + + def state_gradient( - system: ParameterizedSystem, + system: Union[ParameterizedSystem,ParameterizedSystem2ls], initial_state: ndarray, target_derivative: Union[Callable, ndarray], process_tensors: List[BaseProcessTensor], parameters: ndarray, start_time: Optional[float] = 0.0, + num_steps: Optional[int]=None, progress_type: Optional[Text] = None) -> Dict: """ Compute system dynamics and gradient of an objective function Z with @@ -75,9 +79,8 @@ def state_gradient( """ check_isinstance(parameters, ndarray, 'parameters') - num_steps = len(process_tensors[0]) dt = process_tensors[0].dt - num_parameters = parameters.shape[1] + num_parameters = parameters.shape[1] grad_prop, dynamics = compute_gradient_and_dynamics( system=system, @@ -90,7 +93,6 @@ def state_gradient( num_steps=num_steps, progress_type=progress_type) - get_half_props= system.get_propagators(dt,parameters) get_prop_derivatives = system.get_propagator_derivatives(dt,parameters) @@ -98,7 +100,93 @@ def state_gradient( adjoint_tensor=grad_prop, dprop_dparam=get_prop_derivatives, propagators=get_half_props, + num_steps=len(grad_prop), + num_parameters=num_parameters, + progress_type=progress_type) + + return_dict = { + 'final_state':dynamics.states[-1], + 'gradprop':grad_prop, + 'gradient':final_derivs, + 'dynamics':dynamics + } + + return return_dict + +def state_gradient_env_dependent( + system: Union[ParameterizedSystem,ParameterizedSystem2ls], + initial_state: ndarray, + target_derivative: Union[Callable, ndarray], + process_tensors: List[BaseProcessTensor], + parameters: ndarray, + mpo_derivatives: List[ndarray], + start_time: Optional[float] = 0.0, + num_steps: Optional[int]=None, + progress_type: Optional[Text] = None) -> Dict: + """ + Compute system dynamics and gradient of an objective function Z with + respect to a parameterized System for a given set of control + parameters, accounting for the interaction with an environment described by + process tensors. The target state corresponds to (dZ/drho_f). + + Parameters: + ----------- + system: ParametrizedSystem + Parameterized system taking M parameters. + initial_state: ndarray + The initial density matrix to propagate forwards + target_derivative: Union[Callable, ndarray] + A pure target state transposed or derivative w.r.t. an objective + function. + process_tensors: List[BaseProcessTensor] + A list of process tensors (each with N time steps) representing the + environment. + parameters: ndarray + A matrix of dimension 2N x M corresponding to the M parameters at each + half time step. + start_time: float + Optional start time offset. + progress_type: str (default = None) + The progress report type during the computation. Types are: + {``silent``, ``simple``, ``bar``}. If `None` then + the default progress type is used. + + Returns: + -------- + return_dict: Dict + The return dictionary has the fields: + 'final_state' : the final state after evolving the initial state + 'gradprop' : derivatives of Z with respect to half-step propagators + 'gradient' : derivatives of Z with respect to the parameters + 'dynamics' : the dynamics of the system + """ + check_isinstance(parameters, ndarray, 'parameters') + + dt = process_tensors[0].dt + num_parameters = parameters.shape[1] + + grad_prop, grad_mpo,dynamics = compute_gradient_and_dynamics_env_dependent( + system=system, + initial_state=initial_state, + target_derivative=target_derivative, + process_tensors=process_tensors, + parameters=parameters, + mpo_derivatives=mpo_derivatives, + start_time=start_time, + dt=dt, num_steps=num_steps, + progress_type=progress_type) + + + get_half_props= system.get_propagators(dt,parameters) + get_prop_derivatives = system.get_propagator_derivatives(dt,parameters) + + final_derivs = _chain_rule_with_mpo( + adjoint_tensor_prop=grad_prop, + adjoint_tensor_mpo=grad_mpo, + dprop_dparam=get_prop_derivatives, + propagators=get_half_props, + num_steps=len(grad_prop), num_parameters=num_parameters, progress_type=progress_type) @@ -111,6 +199,155 @@ def state_gradient( return return_dict +def state_gradient_coarse( + system: Union[ParameterizedSystem,ParameterizedSystem2ls], + initial_state: ndarray, + target_derivative: Union[Callable, ndarray], + process_tensors: List[BaseProcessTensor], + parameters: ndarray, + opt_steps: ndarray, + start_time: Optional[float] = 0.0, + num_steps: Optional[int]=None, + progress_type: Optional[Text] = None) -> Dict: + """ + Compute system dynamics and gradient of an objective function Z with + respect to a parameterized System for a given set of control + parameters, accounting for the interaction with an environment described by + process tensors. The target state corresponds to (dZ/drho_f). + + Parameters: + ----------- + system: ParametrizedSystem + Parameterized system taking M parameters. + initial_state: ndarray + The initial density matrix to propagate forwards + target_derivative: Union[Callable, ndarray] + A pure target state transposed or derivative w.r.t. an objective + function. + process_tensors: List[BaseProcessTensor] + A list of process tensors (each with N time steps) representing the + environment. + parameters: ndarray + A matrix of dimension 2N x M corresponding to the M parameters at the specified half time steps + opt_steps : ndarray + A matrix of dimension N x M corresponding + start_time: float + Optional start time offset. + progress_type: str (default = None) + The progress report type during the computation. Types are: + {``silent``, ``simple``, ``bar``}. If `None` then + the default progress type is used. + + Returns: + -------- + return_dict: Dict + The return dictionary has the fields: + 'final_state' : the final state after evolving the initial state + 'gradprop' : derivatives of Z with respect to half-step propagators + 'gradient' : derivatives of Z with respect to the parameters + 'dynamics' : the dynamics of the system + """ + check_isinstance(parameters, ndarray, 'parameters') + + assert opt_steps[-1]==num_steps, \ + 'last element of opt_steps must number of steps' + + dt = process_tensors[0].dt + num_parameters = parameters.shape[1] + + grad_prop, dynamics = compute_gradient_and_dynamics( + system=system, + initial_state=initial_state, + target_derivative=target_derivative, + process_tensors=process_tensors, + parameters=parameters, + start_time=start_time, + dt=dt, + num_steps=num_steps, + progress_type=progress_type) + + + get_half_props= system.get_propagators(dt,parameters) + get_prop_derivatives = system.get_propagator_derivatives(dt,parameters) + + final_derivs = _chain_rule_coarse( + adjoint_tensor=grad_prop, + dprop_dparam=get_prop_derivatives, + propagators=get_half_props, + num_steps=num_steps, + opt_steps=opt_steps, + num_parameters=num_parameters, + progress_type=progress_type) + + + return_dict = { + 'final_state':dynamics.states[-1], + 'gradprop':grad_prop, + 'gradient':final_derivs, + 'dynamics':dynamics + } + + return return_dict + +def _chain_rule_coarse( + adjoint_tensor:ndarray, + dprop_dparam:Callable[[int], Tuple[ndarray,ndarray]], + propagators:Callable[[int], Tuple[ndarray,ndarray]], + num_steps:int, + opt_steps:ndarray, + num_parameters:int, + progress_type: Optional[Text] = None): + + def combine_derivs( + target_deriv, + pre_prop, + post_prop): + target_deriv = tn.Node(target_deriv) + pre_node=tn.Node(pre_prop) + post_node=tn.Node(post_prop) + target_deriv[3] ^ post_node[1] + target_deriv[2] ^ post_node[0] + target_deriv[1] ^ pre_node[1] + target_deriv[0] ^ pre_node[0] + + final_node = target_deriv @ pre_node \ + @ post_node + tensor = final_node.tensor + + return tensor + + total_derivs = np.zeros((2*num_steps,num_parameters),dtype='complex128') + + title = "--> Apply chain rule:" + prog_bar = get_progress(progress_type)(num_steps, title) + prog_bar.enter() + + start=0 + for end in opt_steps: + first_half_prop_derivs,second_half_prop_derivs = dprop_dparam(start) + first_half_prop, second_half_prop = propagators(start) + + for k in range(start,end): + + prog_bar.update(k) + + for j in range(0,num_parameters): + total_derivs[2*k][j] = combine_derivs( + adjoint_tensor[k], + first_half_prop_derivs[j].T, + second_half_prop.T) + total_derivs[2*k+1][j] = combine_derivs( + adjoint_tensor[k], + first_half_prop.T, + second_half_prop_derivs[j].T) + + start=end + + prog_bar.update(num_steps) + prog_bar.exit() + + return total_derivs + def _chain_rule( adjoint_tensor:ndarray, dprop_dparam:Callable[[int], Tuple[ndarray,ndarray]], @@ -165,9 +402,66 @@ def combine_derivs( return total_derivs +def _chain_rule_with_mpo( + adjoint_tensor_prop:ndarray, + adjoint_tensor_mpo:ndarray, + dprop_dparam:Callable[[int], Tuple[ndarray,ndarray]], + propagators:Callable[[int], Tuple[ndarray,ndarray]], + num_steps:int, + num_parameters:int, + progress_type: Optional[Text] = None): + + def combine_derivs( + target_deriv, + pre_prop, + post_prop): + target_deriv = tn.Node(target_deriv) + pre_node=tn.Node(pre_prop) + post_node=tn.Node(post_prop) + target_deriv[3] ^ post_node[1] + target_deriv[2] ^ post_node[0] + target_deriv[1] ^ pre_node[1] + target_deriv[0] ^ pre_node[0] + + final_node = target_deriv @ pre_node \ + @ post_node + tensor = final_node.tensor + + return tensor + + total_derivs = np.zeros((2*num_steps,num_parameters),dtype='complex128') + + title = "--> Apply chain rule:" + prog_bar = get_progress(progress_type)(num_steps, title) + prog_bar.enter() + + for i in range(0,num_steps): # populating two elements each step + + first_half_prop, second_half_prop = propagators(i) + first_half_prop_derivs,second_half_prop_derivs = dprop_dparam(i) + + prog_bar.update(i) + + mpo_deriv=combine_derivs(adjoint_tensor_mpo[i], first_half_prop.T, second_half_prop.T) + for j in range(0,num_parameters): + total_derivs[2*i][j] = combine_derivs( + adjoint_tensor_prop[i], + first_half_prop_derivs[j].T, + second_half_prop.T) + 0.5*mpo_deriv + + total_derivs[2*i+1][j] = combine_derivs( + adjoint_tensor_prop[i], + first_half_prop.T, + second_half_prop_derivs[j].T) + 0.5*mpo_deriv + + prog_bar.update(num_steps) + prog_bar.exit() + + return total_derivs + def compute_gradient_and_dynamics( - system: ParameterizedSystem, + system: Union[ParameterizedSystem,ParameterizedSystem2ls], initial_state: ndarray, target_derivative: Union[Callable,ndarray], process_tensors: List[BaseProcessTensor], @@ -235,13 +529,16 @@ def compute_gradient_and_dynamics( system, initial_state, dt, num_steps, start_time, \ process_tensors, control, record_all, hs_dim = parsed_parameters - check_isinstance(system, ParameterizedSystem, "system") + check_isinstance(system, (ParameterizedSystem, ParameterizedSystem2ls), "system") assert target_derivative is not None, \ 'target state must be given explicitly' num_envs = len(process_tensors) + if num_steps is None: + num_steps=len(process_tensors[0]) + # -- prepare propagators -- propagators = system.get_propagators(dt, parameters) @@ -261,6 +558,7 @@ def controls(step: int): # Initial state including the bond legs to the environments with: # edges 0, 1, .., num_envs-1 are the bond legs of the environments # edge -1 is the state leg + initial_ndarray = initial_state.reshape(hs_dim**2) initial_ndarray.shape = tuple([1]*num_envs+[hs_dim**2]) current_node = tn.Node(initial_ndarray) @@ -350,10 +648,9 @@ def controls(step: int): if callable(target_derivative): target_derivative=target_derivative(states[-1]) - target_ndarray = target_derivative target_ndarray = target_ndarray.reshape(hs_dim**2) - target_ndarray.shape = tuple([1]*num_envs+[hs_dim**2]) + target_ndarray = reduce(lambda x,y: np.tensordot(x,y,axes=0),caps + [target_ndarray]) current_node = tn.Node(target_ndarray) current_edges = current_node[:] @@ -435,3 +732,267 @@ def controls(step: int): prog_bar.exit() return propagator_derivatives, dynamics + +def compute_gradient_and_dynamics_env_dependent( + system: Union[ParameterizedSystem,ParameterizedSystem2ls], + initial_state: ndarray, + target_derivative: Union[Callable,ndarray], + process_tensors: List[BaseProcessTensor], + parameters: ndarray, + mpo_derivatives: List[ndarray], + start_time: Optional[float] = 0.0, + dt: Optional[float] = None, + num_steps: Optional[int] = None, + control: Optional[Control] = None, + record_all: Optional[bool] = True, + progress_type: Optional[Text] = None) -> Tuple[List, Dynamics]: + """ + Compute some objective function and calculate its gradient w.r.t. + some control parameters, accounting for interaction with an environment + using one or more process tensors. + + Parameters: + ----------- + system: ParametrizedSystem + Parameterized system taking M parameters. + initial_state: ndarray + The initial density matrix to propagate forwards + target_derivative: Union[Callable, ndarray] + A pure target state transposed or derivative w.r.t. an objective + function. + process_tensors: List[BaseProcessTensor] + A list of process tensors (each with N time steps) representing the + environment. + parameters: List[Tuple] + A list of M-tuples with length 2N. Each tuple corresponds to the values + of the parameters at a given half time step. + start_time: float + Optional start time offset. + dt: float + Length of a single time step. + num_steps: int + Optional number of time steps to be computed. + control: Control + Optional control operations. + record_all: bool + If `false` function only computes the final state. + progress_type: str (default = None) + The progress report type during the computation. Types are: + {``silent``, ``simple``, ``bar``}. If `None` then + the default progress type is used. + + Returns: + -------- + propagator_derivatives: List[ndarray] + List of 4-rank tensors. The nth entry corresponds to the derivative of + the objective function with respect to a propagator at the nth + time step. The axis are ordered as follows: + * [0] : output leg of 2nd half-propagator from step (n-1) + * [1] : input system leg of MPO from step n + * [2] : output system leg of MPO from step n + * [3] : input lef of 1st half-propagator from step (n+1) + dynamics: Dynamics + The system dynamics for the given system Hamiltonian + (accounting for the interaction with the environment). + """ + + # -- input parsing -- + parsed_parameters = _compute_dynamics_input_parse( + False, system, initial_state, dt, num_steps, start_time, + process_tensors, control, record_all) + system, initial_state, dt, num_steps, start_time, \ + process_tensors, control, record_all, hs_dim = parsed_parameters + + check_isinstance(system, (ParameterizedSystem, ParameterizedSystem2ls), "system") + + assert target_derivative is not None, \ + 'target state must be given explicitly' + + num_envs = len(process_tensors) + + if num_steps is None: + num_steps=len(process_tensors[0]) + + # -- prepare propagators -- + propagators = system.get_propagators(dt, parameters) + + # -- prepare controls -- + def controls(step: int): + return control.get_controls( + step, + dt=dt, + start_time=start_time) + + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # ~~~~ Forwardpropagation ~~~~ + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + # -- initialize computation -- + # + # Initial state including the bond legs to the environments with: + # edges 0, 1, .., num_envs-1 are the bond legs of the environments + # edge -1 is the state leg + + initial_ndarray = initial_state.reshape(hs_dim**2) + initial_ndarray.shape = tuple([1]*num_envs+[hs_dim**2]) + current_node = tn.Node(initial_ndarray) + current_edges = current_node[:] + + states = [] + title = "--> Compute forward propagation:" + prog_bar = get_progress(progress_type)(num_steps, title) + prog_bar.enter() + + forwardprop_derivs_list = [] + mpo_list=[] + + for step in range(num_steps+1): + + # -- apply pre measurement control -- + pre_measurement_control, post_measurement_control = controls(step) + + if pre_measurement_control is not None: + current_node, current_edges = _apply_system_superoperator( + current_node, current_edges, pre_measurement_control) + + if step == num_steps: + break + + # -- extract current state -- update field -- + if record_all: + caps = _get_caps(process_tensors, step) + state_tensor = _apply_caps(current_node, current_edges, caps) + state = state_tensor.reshape(hs_dim, hs_dim) + states.append(state) + + prog_bar.update(step) + + # -- apply post measurement control -- + if post_measurement_control is not None: + current_node, current_edges = _apply_system_superoperator( + current_node, current_edges, post_measurement_control) + + forwardprop_derivs_list.append(tn.replicate_nodes([current_node])[0]) + + # -- propagate one time step -- + first_half_prop, second_half_prop = propagators(step) + + pt_mpos = _get_pt_mpos(process_tensors, step) + mpo_list.append(pt_mpos) + + current_node, current_edges = _apply_system_superoperator( + current_node, current_edges, first_half_prop) + current_node, current_edges = _apply_pt_mpos( + current_node, current_edges, pt_mpos) + + current_node, current_edges = _apply_system_superoperator( + current_node, current_edges, second_half_prop) + + # -- extract last state -- + caps = _get_caps(process_tensors, num_steps) + state_tensor = _apply_caps(current_node, current_edges, caps) + final_state = state_tensor.reshape(hs_dim, hs_dim) + states.append(final_state) + + prog_bar.update(num_steps) + prog_bar.exit() + + # -- create dynamics object -- + if record_all: + times = start_time + np.arange(len(states))*dt + else: + times = [start_time + len(states)*dt] + + dynamics = Dynamics(times=list(times),states=states) + + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + # ~~~~~ Backpropagation ~~~~~~ + # ~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + + title = "--> Compute backward propagation:" + prog_bar = get_progress(progress_type)(num_steps, title) + prog_bar.enter() + + if callable(target_derivative): + target_derivative = target_derivative(states[-1]) + + # reshape and include caps + target_ndarray = target_derivative.reshape(hs_dim**2) + caps = _get_caps(process_tensors, num_steps) + target_ndarray = np.outer(caps, target_ndarray) + current_node = tn.Node(target_ndarray) + current_edges = current_node[:] + + # initialize lists for derivatives + combined_deriv_list = [] + combined_deriv_list_mpo = [] + + # start from last forward tensor + backprop_tensor = tn.replicate_nodes([current_node])[0] + + # reversed loop over steps, 0-indexed + for loop, step in enumerate(reversed(range(num_steps))): + + prog_bar.update(loop) + + # get controls and propagators + pre_control, post_control = controls(step) + first_half_prop, second_half_prop = propagators(step) + + # get backward PT MPOs + pt_mpos_back = _get_pt_mpos_backprop(mpo_list, step) + + # -- apply backprop half-propagators and MPOs -- + current_node, current_edges = _apply_system_superoperator( + current_node, current_edges, second_half_prop.T) + current_node, current_edges = _apply_pt_mpos(current_node, current_edges, pt_mpos_back) + current_node, current_edges = _apply_system_superoperator( + current_node, current_edges, first_half_prop.T) + + if post_control is not None: + current_node, current_edges = _apply_system_superoperator( + current_node, current_edges, post_control.T) + if pre_control is not None: + current_node, current_edges = _apply_system_superoperator( + current_node, current_edges, pre_control.T) + + # forward tensor for this step + forward_tensor = forwardprop_derivs_list[step] + forward_tensor_copy = tn.replicate_nodes([forward_tensor])[0] + + # -------------------------- + # derivative w.r.t. props + # -------------------------- + fwd_edges = forward_tensor[:] + deriv_forward, fwd_edges = _apply_derivative_pt_mpos(forward_tensor, fwd_edges, mpo_list[step]) + + # connect edges with backprop + for i, _ in enumerate(pt_mpos_back): + fwd_edges[i] ^ backprop_tensor[i] + + deriv_tensor = deriv_forward @ backprop_tensor + combined_deriv_list.append(deriv_tensor.get_tensor()) + + # -------------------------- + # derivative w.r.t. props and mpo rates + # -------------------------- + fwd_edges_mpo = forward_tensor_copy[:] + deriv_forward_mpo, fwd_edges_mpo = _apply_derivative_pt_mpos(forward_tensor_copy, fwd_edges_mpo, mpo_derivatives[step]) + + for i, _ in enumerate(pt_mpos_back): + fwd_edges_mpo[i] ^ backprop_tensor[i] + + deriv_mpo_tensor = deriv_forward_mpo @ backprop_tensor + combined_deriv_list_mpo.append(deriv_mpo_tensor.get_tensor()) + + # update backprop tensor for next iteration + backprop_tensor = tn.replicate_nodes([current_node])[0] + + # reverse lists to match forward time ordering + propagator_derivs_out = list(reversed(combined_deriv_list)) + mpo_derivs_out = list(reversed(combined_deriv_list_mpo)) + + prog_bar.update(num_steps) + prog_bar.exit() + + return propagator_derivs_out, mpo_derivs_out, dynamics diff --git a/oqupy/iTEBD_TEMPO_useheatmarkers.py b/oqupy/iTEBD_TEMPO_useheatmarkers.py new file mode 100644 index 00000000..2e9dcc70 --- /dev/null +++ b/oqupy/iTEBD_TEMPO_useheatmarkers.py @@ -0,0 +1,272 @@ +# Implementation of iTEBD-TEMPO +# Author: Valentin Link (valentin.link@tu-dresden.de) +# Original code from https://github.com/val-link/iTEBD-TEMPO.git +# Modified by Paul Eastham (easthamp@tcd.ie) so that the iTEBD-TEMPO class uses the OQuPy BathCorrelations class +# to define the bath correlations rather than the bath correlation function itself. + + +import numpy as np +from scipy.integrate import dblquad +from scipy.linalg import expm, norm, svd +from scipy.sparse.linalg import eigs +from typing import Callable, Optional +from tqdm import tqdm +from ncon import ncon # ncon performs better than np.einsum + +from oqupy.bath_correlations import BaseCorrelations + + + +def iTEBD_apply_gate(gate: np.ndarray, A: np.ndarray, sAB: np.ndarray, B: np.ndarray, sBA: np.ndarray, rank: int, rtol: float, ctol: Optional[float] = 1e-13): + """ + single iTEBD step, scheme adapted from https://www.tensors.net/mps + :param gate: TEBD gate for A-B link + :param A: A tensor (left) + :param sAB: weight for A-B link + :param B: B tensor (right) + :param sBA: weight for B-A link + :param rank: maximum rank in svd compression + :param rtol: relative error for svd compression + :param ctol: cutoff for weights sBA which need to be inverted + :return: new tensors and weights A, sAB, B, sBA + """ + + # renormalize weights + sAB = sAB * norm(sBA) + sBA = sBA / norm(sBA) + + # ensure weights are above tolerance (needed for inversion) + sBA[np.abs(sBA) < ctol] = ctol + + # MPS - gate contraction + d1 = gate.shape[1] + d2 = gate.shape[-1] + rank_BA = sBA.shape[0] + + u, s_vals, v = svd(ncon([np.diag(sBA), A, np.diag(sAB), B, np.diag(sBA), gate], [[-1, 1], [1, 5, 2], [2, 4], [4, 6, 3], [3, -4], [5, -2, 6, -3]]).reshape([d1 * rank_BA, d2 * rank_BA]), full_matrices=False) + + # truncate singular values + if rtol is None: + rank_new = min(rank, len(s_vals)) + else: + s_vals_sum = np.cumsum(s_vals) / np.sum(s_vals) + rank_rtol = np.searchsorted(s_vals_sum, 1 - rtol) + 1 + rank_new = min(rank, len(s_vals), rank_rtol) + u = u[:, :rank_new].reshape(sBA.shape[0], d1 * rank_new) + v = v[:rank_new, :].reshape(rank_new * d2, rank_BA) + + # factor out sAB weights from A and B + A = (np.diag(1 / sBA) @ u).reshape(sBA.shape[0], d1, rank_new) + B = (v @ np.diag(1 / sBA)).reshape(rank_new, d2, rank_BA) + + # new weights + sAB = s_vals[:rank_new] + + return A, sAB, B, sBA + + +class BathCorrelation(): + """ A class to store the bath correlation function. """ + + def __init__(self, markedbc: BaseCorrelations): + """ + :param bcf: The bath correlation function. + """ + + self.markedbc=markedbc + + def compute_eta(self, n: int, delta: float) -> np.ndarray: + """ + Computes the discretized bath correlation function (eta) for n time steps delta. + :param n: Number of time steps. + :param delta: Time step. + :return: Discretized bath correlation function. + """ + + etaA1 = np.zeros(n, dtype=np.complex128) + etaA2 = np.zeros(n, dtype=np.complex128) + etaC = np.zeros(n, dtype=np.complex128) + + etaA1[0] = self.markedbc.correlation_2d_integral_marked(delta=delta,time_1=0.,shape='upper-triangle',which_corr='A1') # is there a reason to do this seperately? + etaA2[0] = self.markedbc.correlation_2d_integral_marked(delta=delta,time_1=0.,shape='upper-triangle',which_corr='A2') + etaC[0] = self.markedbc.correlation_2d_integral_marked(delta=delta,time_1=0.,shape='upper-triangle',which_corr='C') + #eta[0] += dblquad(lambda s, t: np.real(self.bcf(t - s)), 0, delta, lambda t: 0, lambda t: t)[0] + #eta[0] += dblquad(lambda s, t: np.imag(self.bcf(t - s)), 0, delta, lambda t: 0, lambda t: t)[0] * 1j + + for k in range(1, n): + etaA1[k] = self.markedbc.correlation_2d_integral_marked(delta=delta,time_1=k*delta,which_corr='A1') + etaA2[k] = self.markedbc.correlation_2d_integral_marked(delta=delta,time_1=k*delta,which_corr='A2') + etaC[k] = self.markedbc.correlation_2d_integral_marked(delta=delta,time_1=k*delta,which_corr='C') + #eta[k] += dblquad(lambda s, t: np.real(self.bcf(t - s)), k * delta, (k + 1) * delta, 0, delta)[0] + #eta[k] += dblquad(lambda s, t: np.imag(self.bcf(t - s)), k * delta, (k + 1) * delta, 0, delta)[0] * 1j + + return etaA1,etaA2,etaC + + +class iTEBD_TEMPO_counting(): + """ A class to compute and approximate the influence functional unsing iTEBD-TEMPO and compute dynamics. """ + + def __init__(self, s_vals: np.ndarray, delta: float, bath_correlations: BaseCorrelations, n_c: int): + """ + :param s_vals: Real eigenvalues of the system-bath coupling operator. + :param delta: time step for Trotter splitting. + :param bcf: Bath correlation function. + :param n_c: Memory cutoff. Should be chosen large enough. + """ + + self.n_c = n_c + self.n_c_eff = n_c + self.s_vals = s_vals + self.s_dim = self.s_vals.size + self.nu_dim = self.s_vals.size ** 2 + 1 + # total number of pairs of eigenvalues + 1 (e.g. for n=2, 4 possible pairs of eigenvalues) + self.bcf = BathCorrelation(bath_correlations) + self.delta = delta + self.etaA1,self.etaA2,self.etaC = self.bcf.compute_eta(self.n_c, delta) + self.s_diff = np.empty((self.nu_dim - 1), dtype=np.complex128) + self.s_sum = np.empty((self.nu_dim - 1), dtype=np.complex128) + for nu in range(self.nu_dim - 1): + i, j = int(nu / self.s_dim), nu % self.s_dim # indexing correspodning to all possible pairs of eigenvalues + self.s_diff[nu] = self.s_vals[i] - self.s_vals[j] + self.s_sum[nu] = self.s_vals[i] + self.s_vals[j] + self.s_diff = np.pad(self.s_diff, [(0, 1)]) # just adds extra zero to end of array + self.s_sum = np.pad(self.s_sum, [(0, 1)]) + + self.kron_delta = np.identity(self.nu_dim) + self.f = None + return + + def compute_f(self, rtol: float, rank: Optional[int] = np.inf): + """ + Compute the infinite influence functional tensor f using iTEBD. + + :param rtol: Relative tolerance for svd compression. + :param rank: Maximum allowed rank (bond dimension). + """ + + A = np.ones((1, self.nu_dim, 1)) + B = np.ones((1, self.nu_dim, 1)) + sAB = np.ones((1)) + sBA = np.ones((1)) + rank_is_one = True + + for k in tqdm(range(1, self.n_c + 1), desc='building influence functional'): + #i_tens = np.exp(-self.eta[self.n_c - k].real * np.outer(self.s_diff, self.s_diff) - 1j * self.eta[self.n_c - k].imag * np.outer(self.s_sum, self.s_diff)) + + i_tens =np.exp(np.outer(self.etaC[self.n_c-k].real*self.s_sum-1j*self.etaA1[self.n_c-k].imag*self.s_sum + +1j*self.etaC[self.n_c-k].imag*self.s_diff-self.etaA1[self.n_c-k].real*self.s_diff,self.s_diff) + -np.outer(self.etaA2[self.n_c-k].real*self.s_sum+1j*self.etaC[self.n_c-k].imag*self.s_sum + +self.etaC[self.n_c-k].real*self.s_diff+1j*self.etaA2[self.n_c-k].imag*self.s_diff,self.s_sum)) + + if k == self.n_c: + gate = np.einsum('a,ij,jb,j->jabi', np.ones((1)), self.kron_delta, self.kron_delta, np.diagonal(i_tens)) + else: + gate = np.einsum('ij,ab,aj->jabi', self.kron_delta, self.kron_delta, i_tens) + + if k % 2 == 0: + B, sBA, A, sAB = iTEBD_apply_gate(gate, B, sBA, A, sAB, rank, rtol=rtol) + else: + A, sAB, B, sBA = iTEBD_apply_gate(gate, A, sAB, B, sBA, rank, rtol=rtol) + + if rank_is_one: + if np.alltrue([sAB.shape[0] == 1, sAB.shape[-1] == 1, sBA.shape[0] == 1, sBA.shape[-1] == 1]): + # reset to initial mps if rank is still one + sAB = np.ones((1)) + sBA = np.ones((1)) + A = np.ones((1, self.nu_dim, 1)) + B = np.ones((1, self.nu_dim, 1)) + else: + rank_is_one = False + self.n_c_eff = self.n_c - k + 1 + if k == 1: + print('Warning: the memory cutoff n_c may be too small for the given rtol value. The algorithm may become unstable and inaccurate. It is recommended to increase n_c until this message does no longer appear.') + self.f = np.squeeze(ncon([np.diag(sAB), B, np.diag(sBA), A], [[-1, 1], [1, -2, 2], [2, 3], [3, -3, -4]])) + + if sAB.shape[0] == 1: + # handle trivial f + self.f = np.ones((1, self.nu_dim, 1)) + + # compute f[:,-1,:]^\inf = v_r * v_l^T using Lanczos + w, v_r = eigs(self.f[:, -1, :], 1, which='LR') + w, v_l = eigs(self.f[:, -1, :].T, 1, which='LR') + self.v_r = v_r[:, 0] + self.v_l = v_l[:, 0] / (v_l[:, 0] @ v_r[:, 0]) + + print('rank ', self.f.shape[0]) + return + + def get(self, i_path: np.ndarray) -> complex: + """ Computes the influence of a single path with indices i_path. + + :param i_path: Array of indices at which the generated influence functional should be evaluated. + :return: Value of the influence functional along the path. + """ + assert self.f is not None, "the influence functional has not yet been computed, run self.compute_f first" + assert type(i_path[0]) is np.int32, "i_path must be an integer numpy array" + val = 1. * self.v_l + for i in range(i_path.size): + val = val @ self.f[:, i_path[i], :] + return val @ self.v_r + + def get_exact(self, i_path: np.ndarray) -> complex: + """ Computes the exact influence of a single path with indices i_path. + + :param i_path: Array of indices at which the influence functional should be evaluated. + :return: Exact value of the influence functional along the path. + """ + assert type(i_path[0]) is np.int32, "i_path must be an integer numpy array" + n = i_path.size + if n > self.eta.size: + self.eta = self.bcf.compute_eta(n, self.delta) + s_diff_path = [self.s_diff[i] for i in np.flip(i_path)] + s_sum_path = [self.s_sum[i] for i in np.flip(i_path)] + are = np.concatenate((np.flip(self.eta[:n].real), np.zeros(n))) + aim = np.concatenate((np.flip(self.eta[:n].imag), np.zeros(n))) + return np.exp(-np.dot(s_diff_path, np.convolve(are, s_diff_path, 'valid')[:n]) - 1j * np.dot(s_diff_path, np.convolve(aim, s_sum_path, 'valid')[:n])) + + def evolve(self, h_s: np.ndarray, rho_0: np.ndarray, n: int) -> np.ndarray: + """ + Compute the time evolution for n time steps. + + :param h_s: System Hamiltonian in the eigenbasis of the coupling operator. + :param rho_0: System initial state in the eigenbasis of the coupling operator. + :param n: Number of time-steps for the propagation. + :return: Time evolution of density matrix. + """ + + assert self.f is not None, "the influence functional has not yet been computed, run self.compute_f first" + + liu_s = np.kron(expm(-1j * h_s * self.delta / 2), expm(1j * h_s * self.delta / 2).T) + u = np.einsum('ab,bc->abc', liu_s.T, liu_s.T) + + rho_t = np.empty((n + 1, self.s_dim, self.s_dim), dtype=np.complex128) + rho_t[0] = rho_0 + + evol_tens = ncon([self.f[:, :-1, :], u], [[-1, 2, -3], [-2, 2, -4]]) + state = ncon([self.v_l, rho_0.flatten()], [[-2], [-3]]) + + for i in tqdm(range(n), desc='time evolution running'): + state = ncon([state, evol_tens], [[1, 2], [1, 2, -2, -3]]) + rho_t[i + 1] = ncon([self.v_r, state], [[1], [1, -1]]).reshape(rho_0.shape) + return rho_t + + def steadystate(self, h_s: np.ndarray) -> np.ndarray: + """ + Compute the steady state using Lanczos. + + :param h_s: System Hamiltonian in the eigenbasis of the coupling operator. + :return: Steady state density matrix. + """ + + assert self.f is not None, "the influence functional has not yet been computed, run self.compute_f first" + + liu_s = np.kron(expm(-1j * h_s * self.delta / 2), expm(1j * h_s * self.delta / 2).T) + u = np.einsum('ab,bc->abc', liu_s.T, liu_s.T) + + evol_tens = ncon([self.f[:, :-1, :], u], [[-1, 1, -3], [-2, 1, -4]]) + + w, v = eigs(evol_tens.reshape([evol_tens.shape[0] * evol_tens.shape[1], evol_tens.shape[2] * evol_tens.shape[3]]).T, 1, which='LR') + + rho_ss = (self.v_r @ v.reshape([self.v_r.size, self.s_dim**2])).reshape([self.s_dim, self.s_dim]) + + return rho_ss / np.trace(rho_ss) diff --git a/oqupy/mps_mpo.py b/oqupy/mps_mpo.py index 580a158c..948fde4b 100644 --- a/oqupy/mps_mpo.py +++ b/oqupy/mps_mpo.py @@ -394,7 +394,7 @@ def __init__( shape = deepcopy(tmp_gamma.shape) rank = len(shape) if rank == 4: - tmp_gamma = np.swapaxes(tmp_gamma,2,3) + pass elif rank == 3: tmp_gamma.shape = (shape[0], shape[1], 1, shape[2]) elif rank == 2: diff --git a/oqupy/process_tensor.py b/oqupy/process_tensor.py index d5df0623..aed90110 100644 --- a/oqupy/process_tensor.py +++ b/oqupy/process_tensor.py @@ -18,7 +18,7 @@ framework and efficient characterization*, Phys. Rev. A 97, 012127 (2018). """ - +from functools import cache from abc import ABC, abstractmethod import os import tempfile @@ -35,6 +35,9 @@ from oqupy import util from oqupy.version import __version__ +NoneType = type(None) + + class BaseProcessTensor(BaseAPIClass, ABC): """ Abstract base class for process tensors in matrix product operator form @@ -275,6 +278,26 @@ def __len__(self) -> int: """Length of process tensor. """ return len(self._mpo_tensors) + @property + def repeating_cell(self) -> Union[tuple[int, int], NoneType]: + """ + Repeating unit cell of a time translational invariant process tensor. + """ + return None + + def effective_step(self, + step: int) -> None: + """ + Get the effective step for the _mpo_tensors and _cap_tensors lists + when there's a repeating cell. + """ + if self.repeating_cell is None: + k = step + else: + n, l = self.repeating_cell[0], self.repeating_cell[1] + k = step if step < n else n + ((step-n) % l) + return k + def set_initial_tensor( self, initial_tensor: Optional[ndarray] = None) -> None: @@ -339,12 +362,13 @@ def get_mpo_tensor( Applies the transformation (stored in `.transform_in` and `.transform_out`) when `transformed` is true. """ + step = self.effective_step(step) length = len(self._mpo_tensors) if step >= length or step < 0: raise IndexError("Process tensor index out of bound. ") tensor = self._mpo_tensors[step] if len(tensor.shape) == 3: - tensor = util.create_delta(tensor, [0, 1, 2, 2]) + tensor = util.create_delta_lastindex(tensor) if transformed is False: return tensor if self._transform_in is not None: @@ -359,6 +383,7 @@ def get_cap_tensor(self, step: int) -> ndarray: """ Get the cap tensor (vector) to terminate the PT-MPO at time step `step`. """ + step = self.effective_step(step) length = len(self._cap_tensors) if step >= length or step < 0: return None @@ -377,6 +402,37 @@ def get_bond_dimensions(self) -> ndarray: bond_dims.append(self._mpo_tensors[-1].shape[1]) return np.array(bond_dims) + def export(self, filename: Text, overwrite: bool = False): + """Export the process tensor as a FileProcessTensor.""" + if overwrite: + mode = "overwrite" + else: + mode = "write" + + pt_file = FileProcessTensor( + mode=mode, + filename=filename, + hilbert_space_dimension=self._hs_dim, + dt=self._dt, + transform_in=self._transform_in, + transform_out=self._transform_out, + name=self.name, + description=self.description) + + pt_file.set_initial_tensor(self._initial_tensor) + for step, mpo in enumerate(self._mpo_tensors): + pt_file.set_mpo_tensor(step, mpo) + for step, cap in enumerate(self._cap_tensors): + pt_file.set_cap_tensor(step, cap) + pt_file.close() + +class SimpleProcessTensorFinite(SimpleProcessTensor): + """Finite Process Tensor""" + + @property + def repeating_cell(self) -> NoneType: + return None + def compute_caps(self) -> None: """ Compute and store all caps from the PT-MPO. @@ -405,29 +461,31 @@ def compute_caps(self) -> None: last_cap = new_cap self._cap_tensors = caps - def export(self, filename: Text, overwrite: bool = False): - """Export the process tensor as a FileProcessTensor.""" - if overwrite: - mode = "overwrite" - else: - mode = "write" - pt_file = FileProcessTensor( - mode=mode, - filename=filename, - hilbert_space_dimension=self._hs_dim, - dt=self._dt, - transform_in=self._transform_in, - transform_out=self._transform_out, - name=self.name, - description=self.description) +class SimpleProcessTensorInfinite(SimpleProcessTensor): + """ + Simple infinite process tensor in matrix product operator form with + a repeating unit cell. + """ + + @property + def max_step(self) -> Union[int, float]: + """Maximal number of time steps.""" + return float('inf') + + @property + def repeating_cell(self) -> tuple[int, int]: + """Repeating unit cell of an infinite process tensor.""" + return (1, 1) + + @cache + def _cached_get_mpo_tensor(self, k: int, transformed: bool) -> ndarray: + """Caches the result of get_mpo_tensor""" + return super().get_mpo_tensor(k, transformed) + + def get_mpo_tensor(self, step: int, transformed: Optional[bool] = True) -> ndarray: + return self._cached_get_mpo_tensor(self.effective_step(step), transformed) - pt_file.set_initial_tensor(self._initial_tensor) - for step, mpo in enumerate(self._mpo_tensors): - pt_file.set_mpo_tensor(step, mpo) - for step, cap in enumerate(self._cap_tensors): - pt_file.set_cap_tensor(step, cap) - pt_file.close() HDF5None = [np.nan] @@ -836,19 +894,23 @@ def import_process_tensor( process_tensor_type: Text Type of process tensor object to create. May be 'file' to create `FileProcessTensor`, - or 'simple', to create a `SimpleProcessTensor`. + or 'simple', to create a generic `SimpleProcessTensor`, + or 'simple-finite', to create a `SimpleProcessTensorFinite`, + or 'simple-infinite' to create a `SimpleProcessTensorInfinite`. Returns ------- process_tensor: BaseProcessTensor The process tensor object with the data from the .hdf5 file. """ + map_dict = {"simple": SimpleProcessTensor, + "simple-finite": SimpleProcessTensorFinite, + "simple-infinite": SimpleProcessTensorInfinite} pt_file = FileProcessTensor(mode="read", filename=filename) - if process_tensor_type is None or process_tensor_type == "file": pt = pt_file - elif process_tensor_type == "simple": - pt = SimpleProcessTensor( + elif process_tensor_type in map_dict: + pt = map_dict[process_tensor_type]( hilbert_space_dimension=pt_file.hilbert_space_dimension, dt=pt_file.dt, transform_in=pt_file.transform_in, diff --git a/oqupy/pt_tempo.py b/oqupy/pt_tempo.py index 9cc6f822..72032a36 100644 --- a/oqupy/pt_tempo.py +++ b/oqupy/pt_tempo.py @@ -47,7 +47,7 @@ from oqupy.config import PT_DEFAULT_TOLERANCE from oqupy.config import PT_TEMPO_BACKEND_CONFIG from oqupy.process_tensor import BaseProcessTensor -from oqupy.process_tensor import SimpleProcessTensor +from oqupy.process_tensor import SimpleProcessTensorFinite from oqupy.process_tensor import FileProcessTensor from oqupy.backends.pt_tempo_backend import PtTempoBackend from oqupy.tempo import TempoParameters @@ -57,7 +57,7 @@ from oqupy.util import get_progress -PT_CLASS = {"simple": SimpleProcessTensor} +PT_CLASS = {"simple": SimpleProcessTensorFinite} @@ -97,7 +97,8 @@ def __init__( overwrite: Optional[bool] = False, backend_config: Optional[Dict] = None, name: Optional[Text] = None, - description: Optional[Text] = None) -> None: + description: Optional[Text] = None, + alpha_t : Optional[ndarray] = None) -> None: """Create a PtTempo object. """ assert isinstance(bath, Bath), \ "Argument 'bath' must be an instance of Bath." @@ -128,6 +129,9 @@ def __init__( self._unique = unique self._process_tensor = None + + # modification for time-dependent coupling + self._alpha_t = alpha_t if process_tensor_file or isinstance(process_tensor_file, Text): if isinstance(process_tensor_file, Text): filename = process_tensor_file @@ -165,7 +169,7 @@ def _init_simple_process_tensor(self): else: transform_in = None transform_out = None - self._process_tensor = SimpleProcessTensor( + self._process_tensor = SimpleProcessTensorFinite( hilbert_space_dimension=self._dimension, dt=self._parameters.dt, transform_in=transform_in, @@ -225,7 +229,8 @@ def _init_pt_tempo_backend(self): dkmax=dkmax, epsrel=self._parameters.epsrel, config=self._backend_config, - degeneracy_maps=degeneracy_maps) + degeneracy_maps=degeneracy_maps, + alpha_t=self._alpha_t) def _influence(self, dk: int) -> ndarray: """Create the influence functional matrix for a time step distance @@ -318,7 +323,8 @@ def pt_tempo_compute( backend_config: Optional[Dict] = None, progress_type: Optional[Text] = None, name: Optional[Text] = None, - description: Optional[Text] = None) -> BaseProcessTensor: + description: Optional[Text] = None, + alpha_t : Optional[ndarray] = None) -> BaseProcessTensor: """ Shortcut for creating a process tensor by performing a PT-TEMPO computation. @@ -370,6 +376,7 @@ def pt_tempo_compute( overwrite, backend_config, name, - description) + description, + alpha_t) ptt.compute(progress_type=progress_type) return ptt.get_process_tensor() diff --git a/oqupy/system.py b/oqupy/system.py index 13cc2d21..68a5cf91 100644 --- a/oqupy/system.py +++ b/oqupy/system.py @@ -638,6 +638,192 @@ def gammas(self) -> List[Callable[[Tuple], float]]: def lindblad_operators(self) -> List[Callable[[Tuple], ndarray]]: """List of lindblad operators. """ return copy(self._lindblad_operators) + +class ParameterizedSystem2ls(BaseSystem): + r""" + Represents a time discrete system with parameterized Hamiltonian H=hx(t)\sigma_x+hy(t)\sigma_y+hz(t)\sigma_z. + The equation of motion is + + .. math:: + + \frac{d}{dt}\rho(t) = &-i [\hat{H}(u_i(t)), \rho(t)] \\ + &+ \sum_n^N \gamma_n \left( + \hat{A}_n \rho(t) \hat{A}_n^\dagger + - \frac{1}{2} \hat{A}_n^\dagger \hat{A}_n \rho(t) + - \frac{1}{2} \rho(t) \hat{A}_n^\dagger \hat{A}_n \right) + + with `parameterized hamiltionian` :math:`\hat{H}(u_i(t))`, + the rates `gammas` :math:`\gamma_n` and `linblad_operators` + :math:`\hat{A}_n`. + + Parameters: + ----------- + hamiltonian: Callable + System-only Hamiltonian :math:`\hat{H}`. + gammas: List[Callable] + The rates :math:`\gamma_n`. + lindblad_operators: List[Callable] + The Lindblad operators :math:`\hat{A}_n`. + name: str + An optional name for the system. + description: str + An optional description of the system. + + """ + def __init__( + self, + hamiltonian: Callable[[Tuple], ndarray], + gammas: \ + Optional[List[Callable[[Tuple], float]]] = None, + lindblad_operators: \ + Optional[List[Callable[[Tuple], ndarray]]] = None, + propagator_derivatives: Callable[[float, Tuple], ndarray] = None, + name: Optional[Text] = None, + description: Optional[Text] = None) -> None: + """Create a ParameterizedSystem object.""" + # input check for Hamiltonian. + number_of_parameters = len(getfullargspec(hamiltonian).args) + self._hamiltonian = np.vectorize(hamiltonian) + trial_hamiltonian = hamiltonian(*(list([0.5]*number_of_parameters))) + _check_hamiltonian(trial_hamiltonian) + dimension = trial_hamiltonian.shape[0] + + self._dimension = dimension + self._number_of_parameters = number_of_parameters + self._hamiltonian = hamiltonian + self._gammas,self._lindblad_operators = \ + _check_parameterized_gammas_lindblad_operators( + gammas, lindblad_operators, number_of_parameters) + self._propagator_derivatives = propagator_derivatives + super().__init__(dimension, name, description) + + def liouvillian(self, *parameters: float) -> ndarray: + """ + Return the Liouvillian for a ParameterizedSystem with parameters given + """ + hamiltonian = self._hamiltonian(*parameters) + gammas=[gamma(*parameters) for gamma in self._gammas] + lindblad_operators = \ + [lop(*parameters) for lop in self._lindblad_operators] + return _liouvillian(hamiltonian, gammas,lindblad_operators) + + + def get_propagators( + self, + dt: float, + parameters: ndarray) -> Callable[[int], Tuple[ndarray,ndarray]]: + """ + ToDo + """ + def propagators(step: int): + """Create the system propagators (first and second half) for + the time step `step` """ + + [hx, hy, hz] = parameters[2*step][:] + h = np.linalg.norm( parameters[2*step][:] ) + A = np.cos(h*dt/2.0) + B = np.sin(h*dt/2.0) + + u1 = np.array([[A-1.0j*B*hz/h,-1.0j*B*(hx-1.0j*hy)/h],[-1j*B*(hx+1.0j*hy)/h,A+1.0j*B*hz/h]]) + first_step = np.kron(u1,np.conjugate(u1)) + + [hx, hy, hz] = parameters[2*step+1][:] + h = np.linalg.norm( parameters[2*step+1][:] ) + A = np.cos(h*dt/2.0) + B = np.sin(h*dt/2.0) + + u1 = np.array([[A-1.0j*B*hz/h,-1.0j*B*(hx-1.0j*hy)/h],[-1j*B*(hx+1.0j*hy)/h,A+1.0j*B*hz/h]]) + second_step = np.kron(u1,np.conjugate(u1)) + + + return first_step, second_step + return propagators + + + + def halfstep_propagator_derivative(self,dt): + """ + Returns a function which takes a list of parameters and returns the + derivative of the half-step propagator for those parameters. + The return is a list r, such that the derivative of the propagator with + respect to the ith parameter is r[i]. + """ + + def jacfun(parameters): + + [hx, hy, hz] = parameters + h = np.linalg.norm([hx, hy, hz] ) + A = np.cos(h*dt/2.0) + B = np.sin(h*dt/2.0) + + hhat = np.array([[hz,hx-1.0j*hy],[hx+1.0j*hy,-hz]]/h) + mat1 = (1.0j*B/h**2-1.0j*dt*A/2/h)*hhat-np.eye(2)*dt*B/2/h + sx = np.array([[0,1],[1,0]]) + sy = np.array([[0,-1.0j],[1.0j,0]]) + sz = np.array([[1,0],[0,-1]]) + + u1 = np.eye(2)*A -1.0j*hhat*B + + du1x = mat1*hx-1.0j*sx/h*B + dx = np.kron(du1x,np.conjugate(u1))+np.kron(u1,np.conjugate(du1x)) + + du1y = mat1*hy-1.0j*sy/h*B + dy = np.kron(du1y,np.conjugate(u1))+np.kron(u1,np.conjugate(du1y)) + + du1z = mat1*hz-1.0j*sz/h*B + dz = np.kron(du1z,np.conjugate(u1))+np.kron(u1,np.conjugate(du1z)) + + return [dx, dy, dz] + + return jacfun + + def get_propagator_derivatives( + self, + dt: float, + parameters: ndarray) -> Callable[[int],Tuple[ndarray,ndarray]]: + """ + ToDo + """ + if self._propagator_derivatives is not None: + def propagator_derivatives_a(step: int): + pre_params=parameters[2*step] + post_params= parameters[2*step+1] + pre_prop_derivs = self._propagator_derivatives(dt, pre_params) + post_prop_derivs = self._propagator_derivatives(dt, post_params) + # pre_prop_derivs[i] is the derivative of the propagator at + # the first half of time step `step` with respect to the + # ith parameter. + return pre_prop_derivs, post_prop_derivs + return propagator_derivatives_a + + pd=self.halfstep_propagator_derivative(dt) + def propagator_derivatives_b(step: int): + pre_params=parameters[2*step] + post_params= parameters[2*step+1] + pre_prop_derivs=pd(pre_params) + post_prop_derivs=pd(post_params) + return pre_prop_derivs,post_prop_derivs + return propagator_derivatives_b + + @property + def number_of_parameters(self) -> Callable[[Tuple], ndarray]: + """The system's number of parameters. """ + return copy(self._number_of_parameters) + + @property + def hamiltonian(self) -> Callable[[Tuple], ndarray]: + """The system Hamiltonian. """ + return copy(self._hamiltonian) + + @property + def gammas(self) -> List[Callable[[Tuple], float]]: + """List of gammas. """ + return copy(self._gammas) + + @property + def lindblad_operators(self) -> List[Callable[[Tuple], ndarray]]: + """List of lindblad operators. """ + return copy(self._lindblad_operators) class MeanFieldSystem(BaseAPIClass): r"""Represents a collection of time dependent systems interacting diff --git a/oqupy/system_dynamics.py b/oqupy/system_dynamics.py index 1ddc9659..08cda1f9 100644 --- a/oqupy/system_dynamics.py +++ b/oqupy/system_dynamics.py @@ -27,7 +27,7 @@ from oqupy.dynamics import Dynamics, MeanFieldDynamics from oqupy.process_tensor import BaseProcessTensor from oqupy.system import BaseSystem, System, TimeDependentSystem -from oqupy.system import ParameterizedSystem +from oqupy.system import ParameterizedSystem,ParameterizedSystem2ls from oqupy.system import MeanFieldSystem from oqupy.operators import left_super, right_super from oqupy.util import check_convert, check_isinstance, check_true @@ -484,7 +484,7 @@ def _compute_dynamics_input_parse( else: check_isinstance( system, - (System, TimeDependentSystem, ParameterizedSystem), + (System, TimeDependentSystem, ParameterizedSystem,ParameterizedSystem2ls), "system" ) @@ -521,7 +521,8 @@ def _compute_dynamics_input_parse( "One of the elements in `process_tensor` is not of type " \ + "`{BaseProcessTensor.__name__}`.") if pt.get_initial_tensor() is not None: - raise NotImplementedError() + warnings.warn("Initial correlated states are not yet "\ + "implemented, ignoring the initial correlations.") check_true( hs_dim == pt.hilbert_space_dimension, "All process tensor must have the same Hilbert "\ @@ -795,6 +796,7 @@ def compute_correlations_nt( ops_times: List[Union[Indices, float, Tuple[float, float]]], ops_order: List[Text], initial_state: Optional[ndarray] = None, + num_steps: Optional[int] = None, start_time: Optional[float] = 0.0, dt: Optional[float] = None, progress_type: Text = None, @@ -828,6 +830,8 @@ def compute_correlations_nt( Initial system state. start_time: float (default = 0.0) Initial time. + num_steps: int + Optional number of time steps to be computed. dt: float (default = None) Time step size. progress_type: str (default = None) @@ -875,8 +879,16 @@ def compute_correlations_nt( #Input parsing; ensures that specified times that are not an integer multiple #of dt are assigned the closest integer multiple.------------------------------ + max_step = process_tensor.max_step - max_step = len(process_tensor) + if num_steps is None: + max_step = process_tensor.max_step + check_true( + max_step < np.inf, + "Variable `num_steps` must be specified because all "\ + "process tensors involved are infinite.") + else: + max_step = num_steps ops_times_=[] ret_times=[] #These are the times returned by the function @@ -1102,7 +1114,16 @@ def _parse_times(times, max_step, dt, start_time): ret_times = np.array([times]) elif isinstance(times, (slice, list)): try: - ret_times = np.arange(max_step + 1)[times] + if isinstance(times, slice): + max_time = max(i for i in [times.stop, times.start] + if i is not None) + ret_times = range(max_time+1)[times] + else: + ret_times = times + ret_times = np.fromiter(ret_times, dtype=np.int64, + count=len(ret_times)) + if ((ret_times < 0) | (ret_times > max_step)).any(): + raise IndexError except Exception as e: raise IndexError("Specified times are invalid or out of bound.") \ from e @@ -1122,8 +1143,11 @@ def _parse_times(times, max_step, dt, start_time): if index_end < 0 or index_end > max_step: raise IndexError("Specified end time is out of bound.") direction = 1 if index_start <= index_end else -1 - ret_times = np.arange( - max_step + 1)[index_start:index_end+direction:direction] + trange = range(max(index_start, index_end)+1) + ret_times = trange[index_start:index_end+direction:direction] + ret_times = np.fromiter(ret_times, dtype=np.int64, count=len(ret_times)) + if ((ret_times < 0) | (ret_times > max_step)).any(): + raise IndexError else: raise TypeError("Parameters `times_a` and `times_b` must be either " \ + "int, slice, list, or tuple.") diff --git a/oqupy/tempo.py b/oqupy/tempo.py index 896679bc..d297b287 100644 --- a/oqupy/tempo.py +++ b/oqupy/tempo.py @@ -37,7 +37,8 @@ from oqupy.config import MAX_DKMAX, DEFAULT_TOLERANCE, MAX_SYS_SAMPLES from oqupy.config import INTEGRATE_EPSREL, SUBDIV_LIMIT from oqupy.config import TEMPO_BACKEND_CONFIG -from oqupy.bath_correlations import BaseCorrelations, CustomSD +from oqupy.bath_correlations import BaseCorrelations, CustomSD, PowerLawSD +from oqupy.counting_bath_correlations import CustomCountingSD_analytical, CustomCountingSD from oqupy.dynamics import Dynamics, MeanFieldDynamics from oqupy.system import BaseSystem, System, TimeDependentSystem,\ TimeDependentSystemWithField, MeanFieldSystem @@ -47,6 +48,8 @@ from oqupy.util import check_convert, check_isinstance, check_true,\ get_progress +NoneType = type(None) + class TempoParameters(BaseAPIClass): r""" Parameters for the TEMPO computation. @@ -63,6 +66,10 @@ class TempoParameters(BaseAPIClass): in the underlying tensor network algorithm). - It must be small enough such that the numerical compression (using tensor network algorithms) does not truncate relevant correlations. + rank: int (default = np.inf) + The maximal rank in the singular value truncation (done in the + underlying tensor network algorithm). The relative error in the + singular value truncation might end up higher than `epsrel`. tcut: float (default = None) Length of time :math:`t_\mathrm{cut}` included in the non-Markovian memory. - This should be large enough to capture all non-Markovian @@ -94,6 +101,7 @@ def __init__( self, dt: float, epsrel: float, + rank: Optional[Union[int, float, NoneType]] = np.inf, tcut: Optional[float] = None, dkmax: Optional[int] = None, add_correlation_time: Optional[float] = None, @@ -119,6 +127,17 @@ def __init__( raise ValueError("Argument 'epsrel' must be positive.") self._epsrel = tmp_epsrel + try: + if rank == np.inf or rank is None: + tmp_rank = np.inf + else: + tmp_rank = int(rank) + except Exception as e: + raise TypeError("Argument 'rank' must be an integer.") from e + if tmp_rank <= 0: + raise ValueError("Argument 'rank' must be strictly positive.") + self._rank = tmp_rank + self._tcut, self._dkmax = _parameter_memory_input_parse( tcut, dkmax, dt) @@ -167,6 +186,7 @@ def __str__(self) -> Text: ret.append(" tcut [dkmax] = {} [{}] \n".format( self.tcut, self.dkmax)) ret.append(" epsrel = {} \n".format(self.epsrel)) + ret.append(" rank = {} \n".format(self.rank)) ret.append(" add_correlation_time = {} \n".format( self.add_correlation_time)) return "".join(ret) @@ -183,6 +203,11 @@ def epsrel(self) -> float: # epsrel is error tolerance for both correlation omega integration and svds + @property + def rank(self) -> float: + """The maximal rank in the singular value truncation.""" + return self._rank + @property def tcut(self) -> float: """Length of non-Markovian memory""" @@ -314,7 +339,8 @@ def __init__( unique: Optional[bool] = False, backend_config: Optional[Dict] = None, name: Optional[Text] = None, - description: Optional[Text] = None) -> None: + description: Optional[Text] = None, + alpha_t : Optional[ndarray] = None) -> None: """Create a Tempo object. """ super().__init__(name, description) @@ -330,6 +356,8 @@ def __init__( "Argument 'parameters' must be an instance of TempoParameters." self._parameters = parameters + self._alpha_t = alpha_t + try: tmp_start_time = float(start_time) except Exception as e: @@ -371,6 +399,7 @@ def _influence(self, dk: int) -> ndarray: else: tmp_deg_positions = None + return influence_matrix( dk, parameters=self._parameters, @@ -421,6 +450,7 @@ def _prepare_backend(self): degeneracy_maps = None dkmax = self._parameters.dkmax epsrel = self._parameters.epsrel + alpha_t = self._alpha_t self._backend_instance = TempoBackend( initial_state, influence, @@ -432,7 +462,8 @@ def _prepare_backend(self): epsrel, config=self._backend_config, degeneracy_maps=degeneracy_maps, - dim=dim) + dim=dim, + alpha_t=alpha_t) def _init_dynamics(self): """Create a Dynamics object with metadata from the Tempo object. """ @@ -969,11 +1000,16 @@ def _check_time(end_time): def influence_matrix( dk: int, parameters: TempoParameters, - correlations: BaseCorrelations, + correlations:Union[ BaseCorrelations, CustomSD, PowerLawSD], coupling_acomm: ndarray, coupling_comm: ndarray, deg_positions: Optional[List[ndarray]] = None): - """Compute the influence functional matrix. """ + """Return the influence functional matrix. """ + + if isinstance(correlations,(CustomCountingSD, CustomCountingSD_analytical)): + return influence_matrix_marked(dk,parameters,correlations,coupling_acomm, + coupling_comm,deg_positions) + dt = parameters.dt dkmax = parameters.dkmax @@ -999,8 +1035,10 @@ def influence_matrix( delta=dt, time_1=time_1, time_2=time_2, - shape=shape, - epsrel=parameters.epsrel) + shape=shape) + # epsrel=parameters.epsrel) +#/!\ SVD truncation epsrel doesn't necessarily match the integration epsrel + op_p = coupling_acomm op_m = coupling_comm @@ -1019,6 +1057,69 @@ def influence_matrix( return infl +def influence_matrix_marked( + dk: int, + parameters: TempoParameters, + correlations: Union[CustomCountingSD_analytical,CustomCountingSD], + coupling_acomm: ndarray, + coupling_comm: ndarray, + deg_positions: Optional[List[ndarray]] = None): + """Compute the influence functional matrix. """ + dt = parameters.dt + dkmax = parameters.dkmax + + if dk == 0: + time_1 = 0.0 + time_2 = None + shape = "upper-triangle" + elif dk < 0: + time_1 = float(dkmax) * dt + if parameters.add_correlation_time is not None: + time_2 = float(dkmax) * dt \ + + np.min([float(-dk) * dt, + 1.0*dt + parameters.add_correlation_time]) + else: + return None + shape = "rectangle" + else: + time_1 = float(dk) * dt + time_2 = None + shape = "square" + + etaA1_dk = correlations.correlation_2d_integral_marked( \ + delta=dt, + time_1=time_1, + time_2=time_2, + shape=shape, + which_corr='A1') + #epsrel=parameters.epsrel) + etaA2_dk = correlations.correlation_2d_integral_marked( \ + delta=dt, + time_1=time_1, + time_2=time_2, + shape=shape, + which_corr='A2') + #epsrel=parameters.epsrel) + etaC_dk = correlations.correlation_2d_integral_marked( \ + delta=dt, + time_1=time_1, + time_2=time_2, + shape=shape, + which_corr='C') + #epsrel=parameters.epsrel) + op_p = coupling_acomm + op_m = coupling_comm + + if dk == 0: + infl = np.diag(np.exp((op_m*((etaC_dk.real-1j*etaA1_dk.imag)*op_p+ + (1j*etaC_dk.imag-etaA1_dk.real)*op_m)-op_p*((etaC_dk.real+1j*etaA2_dk.imag)*op_m+ + (etaA2_dk.real+1j*etaC_dk.imag)*op_p)))) + else: + infl = np.exp(np.outer(etaC_dk.real*op_p-1j*etaA1_dk.imag*op_p+ + 1j*etaC_dk.imag*op_m-etaA1_dk.real*op_m,op_m)-np.outer(etaA2_dk.real*op_p+ + 1j*etaC_dk.imag*op_p+etaC_dk.real*op_m+1j*etaA2_dk.imag*op_m,op_p)) + return infl + GUESS_WARNING_MSG = "Estimating TEMPO parameters. " \ + "No guarantee subsequent dynamics calculations are converged. " \ + "Please refer to the TEMPO documentation and check convergence by " \ @@ -1151,7 +1252,8 @@ def tempo_compute( backend_config: Optional[Dict] = None, progress_type: Optional[Text] = None, name: Optional[Text] = None, - description: Optional[Text] = None) -> Dynamics: + description: Optional[Text] = None, + alpha_t : Optional[ndarray] = None) -> Dynamics: """ Shortcut for creating a Tempo object and running the computation. Cannot be used to create MeanFieldTempo objects. @@ -1204,7 +1306,8 @@ def tempo_compute( unique, backend_config, name, - description) + description, + alpha_t) tempo.compute(end_time, progress_type=progress_type) return tempo.get_dynamics() diff --git a/oqupy/tti_tempo.py b/oqupy/tti_tempo.py new file mode 100644 index 00000000..0bcd40fa --- /dev/null +++ b/oqupy/tti_tempo.py @@ -0,0 +1,264 @@ +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +""" +Module for the time translational invariant time evolving matrix product +operator algorithm (TTI-TEMPO). This module is based on [Link2024]. + +**[Link2024]** +V. Link, H. Tu, and W. T. Strunz, *Open Quantum System Dynamics from Infinite +Tensor Network Contraction*, `Phys. Rev. Lett. 132, 200403 +`__ (2024). +""" + +from typing import Dict, Optional, Text, Union + +import numpy as np + +from oqupy.base_api import BaseAPIClass +from oqupy.bath import Bath +from oqupy.config import TTI_TEMPO_BACKEND_CONFIG +from oqupy.process_tensor import BaseProcessTensor, SimpleProcessTensorInfinite +from oqupy.process_tensor import FileProcessTensor +from oqupy.backends.tti_tempo_backend import TTITempoBackend +from oqupy.tempo import TempoParameters +from oqupy.tempo import influence_matrix +from oqupy.operators import left_right_super +from oqupy.util import get_progress + + +class TTITempo(BaseAPIClass): + """ + Class to facilitate a TTI-TEMPO computations. + + Parameters + ---------- + bath: Bath + The Bath (includes the coupling operator to the system). + parameters: TempoParameters + The parameters for the PT-TEMPO computation. + start_time: float + The start time. + backend_config: dict (default = None) + The configuration of the backend. If `backend_config` is + ``None`` then the default backend configuration is used. + name: str (default = None) + An optional name for the tempo object. + description: str (default = None) + An optional description of the tempo object. + """ + def __init__( + self, + bath: Bath, + start_time: float, + parameters: TempoParameters, + process_tensor_file: Optional[Union[Text, bool]] = None, + overwrite: Optional[bool] = False, + backend_config: Optional[Dict] = None, + name: Optional[Text] = None, + description: Optional[Text] = None) -> None: + """Create a TTITempo object. """ + assert isinstance(bath, Bath), \ + "Argument 'bath' must be an instance of Bath." + self._bath = bath + self._dimension = self._bath.dimension + self._correlations = self._bath.correlations + + super().__init__(name, description) + + try: + tmp_start_time = float(start_time) + except Exception as e: + raise AssertionError("Start time must be a float.") from e + self._start_time = tmp_start_time + + assert isinstance(parameters, TempoParameters), \ + "Argument 'parameters' must be an instance of TempoParameters." + self._parameters = parameters + + self._process_tensor = None + if process_tensor_file or isinstance(process_tensor_file, Text): + if isinstance(process_tensor_file, Text): + filename = process_tensor_file + else: + filename = None + self._init_file_process_tensor(filename, overwrite) + else: + self._init_infinite_process_tensor() + + if backend_config is None: + self._backend_config = TTI_TEMPO_BACKEND_CONFIG + else: + self._backend_config = TTI_TEMPO_BACKEND_CONFIG | backend_config + + self._coupling_comm = np.pad(self._bath._coupling_comm, [(0, 1)]) + self._coupling_acomm = np.pad(self._bath._coupling_acomm, [(0, 1)]) + + self._backend_instance = None + self._init_tti_tempo_backend() + + def _init_infinite_process_tensor(self): + """ToDo. """ + unitary = self._bath.unitary_transform + if not np.allclose(unitary, np.identity(self._dimension)): + transform_in = left_right_super(unitary.conjugate().T, + unitary).T + transform_out = left_right_super(unitary, + unitary.conjugate().T).T + else: + transform_in = None + transform_out = None + + self._process_tensor = SimpleProcessTensorInfinite( + hilbert_space_dimension=self._dimension, + dt=self._parameters.dt, + transform_in=transform_in, + transform_out=transform_out, + name=self.name, + description=self.description) + + def _init_file_process_tensor(self, filename, overwrite): + """ToDo. """ + unitary = self._bath.unitary_transform + if not np.allclose(unitary, np.identity(self._dimension)): + transform_in = left_right_super(unitary.conjugate().T, + unitary).T + transform_out = left_right_super(unitary, + unitary.conjugate().T).T + else: + transform_in = None + transform_out = None + + if overwrite: + mode = "overwrite" + else: + mode = "write" + self._process_tensor = FileProcessTensor( + mode=mode, + filename=filename, + hilbert_space_dimension=self._dimension, + dt=self._parameters.dt, + transform_in=transform_in, + transform_out=transform_out, + name=self.name, + description=self.description) + + def _init_tti_tempo_backend(self): + """Create and initialize the tti-tempo backend.""" + self._backend_instance = TTITempoBackend( + dimension=self._dimension, + influence=self._influence, + process_tensor=self._process_tensor, + dkmax=self._parameters.dkmax, + epsrel=self._parameters.epsrel, + rank=self._parameters.rank, + config=self._backend_config) + + def _influence(self, dk): + return influence_matrix( + dk, + parameters=self._parameters, + correlations=self._correlations, + coupling_acomm=self._coupling_acomm, + coupling_comm=self._coupling_comm) + + def compute(self, progress_type: Optional[Text] = None) -> None: + """ + Propagate (or continue to propagate) the TEMPO tensor network to + time `end_time`. + + Parameters + ---------- + progress_type: str (default = None) + The progress report type during the computation. Types are: + {``silent``, ``simple``, ``bar``}. If `None` then + the default progress type is used. + """ + if self._backend_instance.step is None: + self._backend_instance.initialize() + + progress = get_progress(progress_type) + title = "--> TTI-TEMPO computation:" + with progress(self._backend_instance.num_steps, title) as prog_bar: + while self._backend_instance.compute_step(): + prog_bar.update(self._backend_instance.step) + + def get_process_tensor( + self, + progress_type: Optional[Text] = None) -> BaseProcessTensor: + """ + Returns a the computed process tensor. It performs the computation if + it hasn't been already done. + + Parameters + ---------- + progress_type: str (default = None) + The progress report type during the computation. Types are: + {``silent``, ``simple``, ``bar``}. If `None` then + the default progress type is used. + + Returns + ------- + process_tensor: SimpleProcessTensorInfinite + The computed process tensor. + """ + if self._backend_instance.step is None or \ + self._backend_instance.step < self._backend_instance.num_steps: + self.compute(progress_type=progress_type) + + if len(self._process_tensor) < sum( + self._backend_instance.repeating_cell): + self._backend_instance.update_process_tensor() + + return self._process_tensor + + +def tti_tempo_compute( + bath: Bath, + start_time: float, + parameters: TempoParameters = None, + progress_type: Optional[Text] = None, + process_tensor_file: Optional[Union[Text, bool]] = None, + overwrite: Optional[bool] = False, + backend_config: Optional[Dict] = None, + name: Optional[Text] = None, + description: Optional[Text] = None) -> BaseProcessTensor: + """ + Shortcut for creating a process tensor by performing a TTI-TEMPO + computation. + + Parameters + ---------- + bath: Bath + The Bath (includes the coupling operator to the system). + start_time: float + The start time. + parameters: TempoParameters + The parameters for the TTI-TEMPO computation. + progress_type: str (default = None) + The progress report type during the computation. Types are: + {``'silent'``, ``'simple'``, ``'bar'``}. If `None` then + the default progress type is used. + name: str (default = None) + An optional name for the tempo object. + description: str (default = None) + An optional description of the tempo object. + """ + ptt = TTITempo(bath, + start_time, + parameters, + process_tensor_file, + overwrite, + backend_config, + name, + description) + ptt.compute(progress_type=progress_type) + return ptt.get_process_tensor() diff --git a/oqupy/util.py b/oqupy/util.py index 07d8c91b..011de820 100644 --- a/oqupy/util.py +++ b/oqupy/util.py @@ -56,6 +56,17 @@ def create_delta( return ret_ndarray +def create_delta_lastindex( + tensor: ndarray) -> ndarray: + """ + Creates a delta at the last index. + """ + ret_shape=tensor.shape+(tensor.shape[-1],) + ret_ndarray=np.zeros(ret_shape,dtype=tensor.dtype) + for a in range(ret_shape[-1]): + ret_ndarray[:,:,a,a]=tensor[:,:,a] + return ret_ndarray + def increase_list_of_index( a: List, shape: List, diff --git a/patched-tn_backend_numpy_decompositions.py b/patched-tn_backend_numpy_decompositions.py new file mode 100644 index 00000000..d4f4f176 --- /dev/null +++ b/patched-tn_backend_numpy_decompositions.py @@ -0,0 +1,137 @@ +# Copyright 2019 The TensorNetwork Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +"""Tensor Decomposition Numpy Implementation.""" + +from typing import Optional, Any, Tuple +import warnings +import numpy +import scipy + +Tensor = Any + + +def svd( + np, # TODO: Typing + tensor: Tensor, + pivot_axis: int, + max_singular_values: Optional[int] = None, + max_truncation_error: Optional[float] = None, + relative: Optional[bool] = False) -> Tuple[Tensor, Tensor, Tensor, Tensor]: + """Computes the singular value decomposition (SVD) of a tensor. + + See tensornetwork.backends.tensorflow.decompositions for details. + """ + left_dims = tensor.shape[:pivot_axis] + right_dims = tensor.shape[pivot_axis:] + + tensor = np.reshape(tensor, [numpy.prod(left_dims), numpy.prod(right_dims)]) + #u, s, vh = np.linalg.svd(tensor, full_matrices=False) + + try: + u, s, vh = np.linalg.svd(tensor, full_matrices=False) + except np.linalg.LinAlgError: + warnings.warn("NumPy SVD with the fast 'gesdd' LAPACK routine failed. " \ + + "Matrix might be badly conditioned. Employing the SciPy SVD " \ + + "with more stable 'gesvd' LAPACK routine instead.") + u, s, vh = scipy.linalg.svd( + tensor, full_matrices=False, lapack_driver='gesvd') + + + if max_singular_values is None: + max_singular_values = np.size(s) + + if max_truncation_error is not None: + # Cumulative norms of singular values in ascending order. + trunc_errs = np.sqrt(np.cumsum(np.square(s[::-1]))) + # If relative is true, rescale max_truncation error with the largest + # singular value to yield the absolute maximal truncation error. + if relative: + abs_max_truncation_error = max_truncation_error * s[0] + else: + abs_max_truncation_error = max_truncation_error + # We must keep at least this many singular values to ensure the + # truncation error is <= abs_max_truncation_error. + num_sing_vals_err = np.count_nonzero( + (trunc_errs > abs_max_truncation_error).astype(np.int32)) + else: + num_sing_vals_err = max_singular_values + + num_sing_vals_keep = min(max_singular_values, num_sing_vals_err) + + # tf.svd() always returns the singular values as a vector of float{32,64}. + # since tf.math_ops.real is automatically applied to s. This causes + # s to possibly not be the same dtype as the original tensor, which can cause + # issues for later contractions. To fix it, we recast to the original dtype. + s = s.astype(tensor.dtype) + + s_rest = s[num_sing_vals_keep:] + s = s[:num_sing_vals_keep] + u = u[:, :num_sing_vals_keep] + vh = vh[:num_sing_vals_keep, :] + + dim_s = s.shape[0] + u = np.reshape(u, list(left_dims) + [dim_s]) + vh = np.reshape(vh, [dim_s] + list(right_dims)) + + return u, s, vh, s_rest + + +def qr( + np, # TODO: Typing + tensor: Tensor, + pivot_axis: int, + non_negative_diagonal: bool +) -> Tuple[Tensor, Tensor]: + """Computes the QR decomposition of a tensor. + + See tensornetwork.backends.tensorflow.decompositions for details. + """ + left_dims = tensor.shape[:pivot_axis] + right_dims = tensor.shape[pivot_axis:] + tensor = np.reshape(tensor, [numpy.prod(left_dims), numpy.prod(right_dims)]) + q, r = np.linalg.qr(tensor) + if non_negative_diagonal: + phases = np.sign(np.diagonal(r)) + q = q * phases + r = phases.conj()[:, None] * r + center_dim = q.shape[1] + q = np.reshape(q, list(left_dims) + [center_dim]) + r = np.reshape(r, [center_dim] + list(right_dims)) + return q, r + + +def rq( + np, # TODO: Typing + tensor: Tensor, + pivot_axis: int, + non_negative_diagonal: bool +) -> Tuple[Tensor, Tensor]: + """Computes the RQ (reversed QR) decomposition of a tensor. + + See tensornetwork.backends.tensorflow.decompositions for details. + """ + left_dims = tensor.shape[:pivot_axis] + right_dims = tensor.shape[pivot_axis:] + tensor = np.reshape(tensor, [numpy.prod(left_dims), numpy.prod(right_dims)]) + q, r = np.linalg.qr(np.conj(np.transpose(tensor))) + if non_negative_diagonal: + phases = np.sign(np.diagonal(r)) + q = q * phases + r = phases.conj()[:, None] * r + r, q = np.conj(np.transpose(r)), np.conj( + np.transpose(q)) #M=r*q at this point + center_dim = r.shape[1] + r = np.reshape(r, list(left_dims) + [center_dim]) + q = np.reshape(q, [center_dim] + list(right_dims)) + return r, q diff --git a/plandcalc.ipynb b/plandcalc.ipynb new file mode 100644 index 00000000..8d65ef75 --- /dev/null +++ b/plandcalc.ipynb @@ -0,0 +1,1073 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import oqupy\n", + "import oqupy.operators as op\n", + "import scipy.integrate as spi\n", + "import numpy as np\n", + "from oqupy.iTEBD_TEMPO_useoqupybath import iTEBD_TEMPO_oqupy\n", + "from oqupy.process_tensor import TTInvariantProcessTensor\n", + "from oqupy.tti_tempo import TTITempo\n", + "from oqupy.tti_tempo import TTITempoCounting\n", + "import matplotlib.pyplot as plt\n", + "\n", + "\n", + "from scipy.integrate import solve_ivp\n", + "from scipy.interpolate import interp1d\n", + "from scipy.optimize import minimize,Bounds\n", + "\n", + "pt_parameters = {'epsrel':10**(-7),\n", + " 'alpha':0.1,\n", + " 'omega_cutoff':1, \n", + " 'temp':0.131,\n", + " 'dt':0.2} #0.25\n", + "\n", + "omega_cutoff = pt_parameters['omega_cutoff']\n", + "alpha = pt_parameters['alpha']\n", + "temperature = pt_parameters['temp']\n", + "epsrel = pt_parameters['epsrel']\n", + "# dt = 1./omega_cutoff/np.sqrt(3)\n", + "dt=pt_parameters['dt']\n", + "\n", + "tcut=27\n", + "\n", + "Rho_0=oqupy.operators.spin_dm('x+')\n", + "\n", + "# spectral density (without cutoff)\n", + "def j(w):\n", + " return 2*alpha*w\n" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [], + "source": [ + "\n", + "correlations = oqupy.PowerLawSD(alpha=alpha,\n", + " zeta=1,\n", + " cutoff=omega_cutoff,\n", + " cutoff_type='exponential',\n", + " temperature=temperature)\n", + "bath = oqupy.Bath(op.sigma(\"z\")/2.0, correlations)\n", + "parameters=oqupy.TempoParameters(dt=dt,epsrel=epsrel,dkmax=500)" + ] + }, + { + "cell_type": "code", + "execution_count": 3, + "metadata": {}, + "outputs": [], + "source": [ + "u=0.01\n", + "correlationscf=oqupy.bath_correlations.CustomCountingSD_analytical(j_function=j,cutoff=omega_cutoff,u=u,\n", + " cutoff_type='exponential',temperature=temperature)\n", + "\n", + "bathcf = oqupy.Bath(op.sigma(\"z\")/2.0, correlationscf)" + ] + }, + { + "cell_type": "code", + "execution_count": 4, + "metadata": {}, + "outputs": [ + { + "name": "stderr", + "output_type": "stream", + "text": [ + "building influence functional: 0%| | 0/500 [00:00" + ] + }, + "execution_count": 27, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "fig,ax=plt.subplots(1)\n", + "ax.plot(alphalist,r1li,'x-',label='Numerical')\n", + "ax.plot(alphalist,r2li,'o-',label='Polaron')\n", + "ax.set_ylim(-1.0,-0.9)\n", + "ax.set_xlabel(r'$\\alpha$')\n", + "ax.set_ylabel(r'$\\langle\\sigma_x\\rangle$')\n", + "ax.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [ + "plt.plot()" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[-0.9965721090635934,\n", + " -0.9829776475784173,\n", + " -0.9662450556387991,\n", + " -0.9497972917761037,\n", + " -0.933629507546426]" + ] + }, + "execution_count": 11, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "r2li" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> Compute dynamics:\n", + "100.0% 10000 of 10000 [########################################] 00:00:36\n", + "Elapsed time: 36.7s\n", + "--> Compute dynamics:\n", + "100.0% 10000 of 10000 [########################################] 00:00:38\n", + "Elapsed time: 38.6s\n" + ] + }, + { + "name": "stderr", + "output_type": "stream", + "text": [ + "/var/folders/7j/h_f__xy953v4yjm9p8nw1gn80000gn/T/ipykernel_38434/1639565641.py:51: UserWarning: No artists with labels found to put in legend. Note that artists whose label start with an underscore are ignored when legend() is called with no argument.\n", + " plt.legend()\n" + ] + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "inisplit=1.0\n", + "# choose initial state to be thermal equilibrium given hamiltonian inisplit*(sigmax/2)\n", + "z=2*np.cosh(inisplit/(2*temperature))\n", + "pupx=np.exp(-inisplit/(2*temperature))/z\n", + "pdnx=np.exp(+inisplit/(2*temperature))/z\n", + "\n", + "rhoini=oqupy.operators.spin_dm('x+')*pupx+oqupy.operators.spin_dm('x-')*pdnx\n", + "\n", + "for t_prot in [2000]:\n", + "\n", + " fig,axs=plt.subplots(3)\n", + "\n", + " num_steps=int(t_prot/dt)\n", + "\n", + " def hx(t):\n", + " return inisplit*(1-t/t_prot)\n", + " \n", + " def hamiltonian_t(t):\n", + " return op.sigma('x')*hx(t)/2\n", + "\n", + " system = oqupy.TimeDependentSystem(hamiltonian_t)\n", + "\n", + " # compute dynamics\n", + "\n", + " dynamics=oqupy.compute_dynamics(\n", + " process_tensor=process_tensor_var, \n", + " system=system,\n", + " initial_state=rhoini,\n", + " start_time=0,\n", + " num_steps=num_steps)\n", + " t, s_x = dynamics.expectations(op.sigma('x'), real=True)\n", + "\n", + " # compute heats\n", + "\n", + " dynamicscf = oqupy.compute_dynamics(\n", + " process_tensor=process_tensor_varcf, \n", + " system=system,\n", + " initial_state=rhoini,\n", + " start_time=0,\n", + " num_steps=num_steps)\n", + "\n", + " heats=dynamicscf.states.trace(axis1=1,axis2=2).imag/u\n", + "\n", + " axs[0].plot(t,heats,label=t_prot)\n", + " axs[0].set_xlabel(r'$t$')\n", + " axs[0].set_ylabel(r'$\\langle Q \\rangle$')\n", + " axs[1].plot(t,s_x)\n", + " axs[1].set_xlabel(r'$t$')\n", + " axs[1].set_ylabel(r'$\\langle \\sigma_x \\rangle$')\n", + " axs[2].plot(t,[hx(tme) for tme in t])\n", + " plt.legend()\n", + " plt.show()\n" + ] + }, + { + "cell_type": "code", + "execution_count": 7, + "metadata": {}, + "outputs": [], + "source": [ + "def vneumannentropy(rho):\n", + " probs=np.linalg.eigvalsh(rho)\n", + " return -np.sum(probs*(np.log(probs)))" + ] + }, + { + "cell_type": "code", + "execution_count": 8, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "Landauer limit 0.09033527974899358\n", + "Achieved Q 0.012458040877771914\n", + "Percentage of Landauer achieved 13.790892010727081\n" + ] + } + ], + "source": [ + "# landauer limit\n", + "ll=temperature*(vneumannentropy(dynamics.states[-1])-vneumannentropy(rhoini))\n", + "print('Landauer limit ',ll)\n", + "print('Achieved Q ',-heats[-1])\n", + "print('Percentage of Landauer achieved ',-100*heats[-1]/ll)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> TEMPO computation:\n", + " 2.3% 34 of 1500 [----------------------------------------] 00:00:02\n", + "Elapsed time: 2.1s\n" + ] + }, + { + "ename": "KeyboardInterrupt", + "evalue": "", + "output_type": "error", + "traceback": [ + "\u001b[31m---------------------------------------------------------------------------\u001b[39m", + "\u001b[31mKeyboardInterrupt\u001b[39m Traceback (most recent call last)", + "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[10]\u001b[39m\u001b[32m, line 2\u001b[39m\n\u001b[32m 1\u001b[39m \u001b[38;5;66;03m# now let's try using a normal tempo for comparison in speed\u001b[39;00m\n\u001b[32m----> \u001b[39m\u001b[32m2\u001b[39m tempores=\u001b[43moqupy\u001b[49m\u001b[43m.\u001b[49m\u001b[43mtempo_compute\u001b[49m\u001b[43m(\u001b[49m\u001b[43msystem\u001b[49m\u001b[43m=\u001b[49m\u001b[43msystem\u001b[49m\u001b[43m,\u001b[49m\u001b[43mbath\u001b[49m\u001b[43m=\u001b[49m\u001b[43mbath\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 3\u001b[39m \u001b[43m \u001b[49m\u001b[43minitial_state\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrhoini\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 4\u001b[39m \u001b[43m \u001b[49m\u001b[43mstart_time\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 5\u001b[39m \u001b[43m \u001b[49m\u001b[43mend_time\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m300\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 6\u001b[39m \u001b[43m \u001b[49m\u001b[43mparameters\u001b[49m\u001b[43m=\u001b[49m\u001b[43mparameters\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 7\u001b[39m \u001b[43m \u001b[49m\u001b[43malpha_t\u001b[49m\u001b[43m=\u001b[49m\u001b[43mnp\u001b[49m\u001b[43m.\u001b[49m\u001b[43mones\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnum_steps\u001b[49m\u001b[43m)\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/OPOld/oqupy/tempo.py:1283\u001b[39m, in \u001b[36mtempo_compute\u001b[39m\u001b[34m(system, bath, initial_state, start_time, end_time, alpha_t, parameters, tolerance, unique, backend_config, progress_type, name, description)\u001b[39m\n\u001b[32m 1268\u001b[39m parameters = guess_tempo_parameters(bath=bath,\n\u001b[32m 1269\u001b[39m start_time=start_time,\n\u001b[32m 1270\u001b[39m end_time=end_time,\n\u001b[32m 1271\u001b[39m system=system,\n\u001b[32m 1272\u001b[39m tolerance=tolerance)\n\u001b[32m 1273\u001b[39m tempo = Tempo(system,\n\u001b[32m 1274\u001b[39m bath,\n\u001b[32m 1275\u001b[39m parameters,\n\u001b[32m (...)\u001b[39m\u001b[32m 1281\u001b[39m name,\n\u001b[32m 1282\u001b[39m description)\n\u001b[32m-> \u001b[39m\u001b[32m1283\u001b[39m \u001b[43mtempo\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcompute\u001b[49m\u001b[43m(\u001b[49m\u001b[43mend_time\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mprogress_type\u001b[49m\u001b[43m=\u001b[49m\u001b[43mprogress_type\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1284\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m tempo.get_dynamics()\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/OPOld/oqupy/tempo.py:496\u001b[39m, in \u001b[36mTempo.compute\u001b[39m\u001b[34m(self, end_time, progress_type)\u001b[39m\n\u001b[32m 494\u001b[39m \u001b[38;5;28;01mfor\u001b[39;00m i \u001b[38;5;129;01min\u001b[39;00m \u001b[38;5;28mrange\u001b[39m(num_step):\n\u001b[32m 495\u001b[39m prog_bar.update(i)\n\u001b[32m--> \u001b[39m\u001b[32m496\u001b[39m step, state = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_backend_instance\u001b[49m\u001b[43m.\u001b[49m\u001b[43mcompute_step\u001b[49m\u001b[43m(\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 497\u001b[39m \u001b[38;5;28mself\u001b[39m._dynamics.add(\u001b[38;5;28mself\u001b[39m._time(step), state.reshape(dim, dim))\n\u001b[32m 498\u001b[39m prog_bar.update(num_step)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/OPOld/oqupy/backends/tempo_backend.py:637\u001b[39m, in \u001b[36mTempoBackend.compute_step\u001b[39m\u001b[34m(self)\u001b[39m\n\u001b[32m 635\u001b[39m \u001b[38;5;28mself\u001b[39m._step += \u001b[32m1\u001b[39m\n\u001b[32m 636\u001b[39m prop_1, prop_2 = \u001b[38;5;28mself\u001b[39m._propagators(\u001b[38;5;28mself\u001b[39m._step - \u001b[32m1\u001b[39m)\n\u001b[32m--> \u001b[39m\u001b[32m637\u001b[39m \u001b[38;5;28mself\u001b[39m._state = \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43mcompute_system_step\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_step\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mprop_1\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mprop_2\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 638\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._step, copy(\u001b[38;5;28mself\u001b[39m._state)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/OPOld/oqupy/backends/tempo_backend.py:549\u001b[39m, in \u001b[36mBaseTempoBackend.compute_system_step\u001b[39m\u001b[34m(self, current_step, prop_1, prop_2)\u001b[39m\n\u001b[32m 541\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m \u001b[38;5;28mlen\u001b[39m(\u001b[38;5;28mself\u001b[39m._mps) != \u001b[38;5;28mlen\u001b[39m(mpo):\n\u001b[32m 542\u001b[39m \u001b[38;5;28mself\u001b[39m._mps.contract(\u001b[38;5;28mself\u001b[39m._sum_north_na,\n\u001b[32m 543\u001b[39m axes=[(\u001b[32m0\u001b[39m, \u001b[32m0\u001b[39m)],\n\u001b[32m 544\u001b[39m left_index=\u001b[32m0\u001b[39m,\n\u001b[32m 545\u001b[39m right_index=\u001b[32m0\u001b[39m,\n\u001b[32m 546\u001b[39m direction=\u001b[33m\"\u001b[39m\u001b[33mright\u001b[39m\u001b[33m\"\u001b[39m,\n\u001b[32m 547\u001b[39m copy=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m--> \u001b[39m\u001b[32m549\u001b[39m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_mps\u001b[49m\u001b[43m.\u001b[49m\u001b[43mzip_up\u001b[49m\u001b[43m(\u001b[49m\u001b[43mmpo\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 550\u001b[39m \u001b[43m \u001b[49m\u001b[43maxes\u001b[49m\u001b[43m=\u001b[49m\u001b[43m[\u001b[49m\u001b[43m(\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m)\u001b[49m\u001b[43m]\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 551\u001b[39m \u001b[43m \u001b[49m\u001b[43mleft_index\u001b[49m\u001b[43m=\u001b[49m\u001b[32;43m0\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 552\u001b[39m \u001b[43m \u001b[49m\u001b[43mright_index\u001b[49m\u001b[43m=\u001b[49m\u001b[43m-\u001b[49m\u001b[32;43m1\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 553\u001b[39m \u001b[43m \u001b[49m\u001b[43mdirection\u001b[49m\u001b[43m=\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mright\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m,\u001b[49m\n\u001b[32m 554\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_singular_values\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mNone\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 555\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_truncation_err\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_epsrel\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 556\u001b[39m \u001b[43m \u001b[49m\u001b[43mrelative\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mTrue\u001b[39;49;00m\u001b[43m,\u001b[49m\n\u001b[32m 557\u001b[39m \u001b[43m \u001b[49m\u001b[43mcopy\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[32m 559\u001b[39m \u001b[38;5;28mself\u001b[39m._mps.svd_sweep(from_index=-\u001b[32m1\u001b[39m,\n\u001b[32m 560\u001b[39m to_index=\u001b[32m0\u001b[39m,\n\u001b[32m 561\u001b[39m max_singular_values=\u001b[38;5;28;01mNone\u001b[39;00m,\n\u001b[32m 562\u001b[39m max_truncation_err=\u001b[38;5;28mself\u001b[39m._epsrel,\n\u001b[32m 563\u001b[39m relative=\u001b[38;5;28;01mTrue\u001b[39;00m)\n\u001b[32m 565\u001b[39m \u001b[38;5;28mself\u001b[39m._mps = na.join(\u001b[38;5;28mself\u001b[39m._mps,\n\u001b[32m 566\u001b[39m prop_2_na,\n\u001b[32m 567\u001b[39m copy=\u001b[38;5;28;01mFalse\u001b[39;00m,\n\u001b[32m 568\u001b[39m name=\u001b[33mf\u001b[39m\u001b[33m\"\u001b[39m\u001b[33mThe MPS (\u001b[39m\u001b[38;5;132;01m{\u001b[39;00mcurrent_step\u001b[38;5;132;01m}\u001b[39;00m\u001b[33m)\u001b[39m\u001b[33m\"\u001b[39m)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/OPOld/oqupy/backends/node_array.py:541\u001b[39m, in \u001b[36mNodeArray.zip_up\u001b[39m\u001b[34m(self, array, axes, left_index, right_index, direction, max_singular_values, max_truncation_err, relative, copy)\u001b[39m\n\u001b[32m 537\u001b[39m \u001b[38;5;66;03m# inner_bond (0 / -1)\u001b[39;00m\n\u001b[32m 538\u001b[39m v_edges = [\u001b[38;5;28mself\u001b[39m.bond_edges[ia + inner_bond],\n\u001b[32m 539\u001b[39m b.bond_edges[ib + inner_bond]]\n\u001b[32m--> \u001b[39m\u001b[32m541\u001b[39m u, s, vh, trun_vals = \u001b[43mtn\u001b[49m\u001b[43m.\u001b[49m\u001b[43msplit_node_full_svd\u001b[49m\u001b[43m(\u001b[49m\n\u001b[32m 542\u001b[39m \u001b[43m \u001b[49m\u001b[43mnode\u001b[49m\u001b[43m=\u001b[49m\u001b[43mcontracted_node\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 543\u001b[39m \u001b[43m \u001b[49m\u001b[43mleft_edges\u001b[49m\u001b[43m=\u001b[49m\u001b[43mu_edges\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 544\u001b[39m \u001b[43m \u001b[49m\u001b[43mright_edges\u001b[49m\u001b[43m=\u001b[49m\u001b[43mv_edges\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 545\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_singular_values\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_singular_values\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 546\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_truncation_err\u001b[49m\u001b[43m=\u001b[49m\u001b[43mmax_truncation_err\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 547\u001b[39m \u001b[43m \u001b[49m\u001b[43mrelative\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrelative\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 548\u001b[39m singular_values.append((s.tensor.diagonal(),trun_vals))\n\u001b[32m 549\u001b[39m \u001b[38;5;28mself\u001b[39m.nodes[ia] = u\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/OPOld/.venv/lib/python3.14/site-packages/tensornetwork/network_operations.py:545\u001b[39m, in \u001b[36msplit_node_full_svd\u001b[39m\u001b[34m(node, left_edges, right_edges, max_singular_values, max_truncation_err, relative, left_name, middle_name, right_name, left_edge_name, right_edge_name)\u001b[39m\n\u001b[32m 542\u001b[39m backend = node.backend\n\u001b[32m 543\u001b[39m transp_tensor = node.tensor_from_edge_order(left_edges + right_edges)\n\u001b[32m--> \u001b[39m\u001b[32m545\u001b[39m u, s, vh, trun_vals = \u001b[43mbackend\u001b[49m\u001b[43m.\u001b[49m\u001b[43msvd\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtransp_tensor\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 546\u001b[39m \u001b[43m \u001b[49m\u001b[38;5;28;43mlen\u001b[39;49m\u001b[43m(\u001b[49m\u001b[43mleft_edges\u001b[49m\u001b[43m)\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 547\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_singular_values\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 548\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_truncation_err\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 549\u001b[39m \u001b[43m \u001b[49m\u001b[43mrelative\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrelative\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 550\u001b[39m left_node = Node(u,\n\u001b[32m 551\u001b[39m name=left_name,\n\u001b[32m 552\u001b[39m axis_names=left_axis_names,\n\u001b[32m 553\u001b[39m backend=backend)\n\u001b[32m 554\u001b[39m singular_values_node = Node(backend.diagflat(s),\n\u001b[32m 555\u001b[39m name=middle_name,\n\u001b[32m 556\u001b[39m axis_names=center_axis_names,\n\u001b[32m 557\u001b[39m backend=backend)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/OPOld/.venv/lib/python3.14/site-packages/tensornetwork/backends/numpy/numpy_backend.py:622\u001b[39m, in \u001b[36mNumPyBackend.svd\u001b[39m\u001b[34m(self, tensor, pivot_axis, max_singular_values, max_truncation_error, relative)\u001b[39m\n\u001b[32m 614\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34msvd\u001b[39m(\n\u001b[32m 615\u001b[39m \u001b[38;5;28mself\u001b[39m,\n\u001b[32m 616\u001b[39m tensor: Tensor,\n\u001b[32m (...)\u001b[39m\u001b[32m 620\u001b[39m relative: Optional[\u001b[38;5;28mbool\u001b[39m] = \u001b[38;5;28;01mFalse\u001b[39;00m\n\u001b[32m 621\u001b[39m ) -> Tuple[Tensor, Tensor, Tensor, Tensor]:\n\u001b[32m--> \u001b[39m\u001b[32m622\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mdecompositions\u001b[49m\u001b[43m.\u001b[49m\u001b[43msvd\u001b[49m\u001b[43m(\u001b[49m\u001b[43mnp\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 623\u001b[39m \u001b[43m \u001b[49m\u001b[43mtensor\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 624\u001b[39m \u001b[43m \u001b[49m\u001b[43mpivot_axis\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 625\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_singular_values\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 626\u001b[39m \u001b[43m \u001b[49m\u001b[43mmax_truncation_error\u001b[49m\u001b[43m,\u001b[49m\n\u001b[32m 627\u001b[39m \u001b[43m \u001b[49m\u001b[43mrelative\u001b[49m\u001b[43m=\u001b[49m\u001b[43mrelative\u001b[49m\u001b[43m)\u001b[49m\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/OPOld/.venv/lib/python3.14/site-packages/tensornetwork/backends/numpy/decompositions.py:42\u001b[39m, in \u001b[36msvd\u001b[39m\u001b[34m(np, tensor, pivot_axis, max_singular_values, max_truncation_error, relative)\u001b[39m\n\u001b[32m 39\u001b[39m \u001b[38;5;66;03m#u, s, vh = np.linalg.svd(tensor, full_matrices=False)\u001b[39;00m\n\u001b[32m 41\u001b[39m \u001b[38;5;28;01mtry\u001b[39;00m:\n\u001b[32m---> \u001b[39m\u001b[32m42\u001b[39m u, s, vh = \u001b[43mnp\u001b[49m\u001b[43m.\u001b[49m\u001b[43mlinalg\u001b[49m\u001b[43m.\u001b[49m\u001b[43msvd\u001b[49m\u001b[43m(\u001b[49m\u001b[43mtensor\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mfull_matrices\u001b[49m\u001b[43m=\u001b[49m\u001b[38;5;28;43;01mFalse\u001b[39;49;00m\u001b[43m)\u001b[49m\n\u001b[32m 43\u001b[39m \u001b[38;5;28;01mexcept\u001b[39;00m np.linalg.LinAlgError:\n\u001b[32m 44\u001b[39m warnings.warn(\u001b[33m\"\u001b[39m\u001b[33mNumPy SVD with the fast \u001b[39m\u001b[33m'\u001b[39m\u001b[33mgesdd\u001b[39m\u001b[33m'\u001b[39m\u001b[33m LAPACK routine failed. \u001b[39m\u001b[33m\"\u001b[39m \\\n\u001b[32m 45\u001b[39m + \u001b[33m\"\u001b[39m\u001b[33mMatrix might be badly conditioned. Employing the SciPy SVD \u001b[39m\u001b[33m\"\u001b[39m \\\n\u001b[32m 46\u001b[39m + \u001b[33m\"\u001b[39m\u001b[33mwith more stable \u001b[39m\u001b[33m'\u001b[39m\u001b[33mgesvd\u001b[39m\u001b[33m'\u001b[39m\u001b[33m LAPACK routine instead.\u001b[39m\u001b[33m\"\u001b[39m)\n", + "\u001b[36mFile \u001b[39m\u001b[32m~/OPOld/.venv/lib/python3.14/site-packages/numpy/linalg/linalg.py:1681\u001b[39m, in \u001b[36msvd\u001b[39m\u001b[34m(a, full_matrices, compute_uv, hermitian)\u001b[39m\n\u001b[32m 1678\u001b[39m gufunc = _umath_linalg.svd_n_s\n\u001b[32m 1680\u001b[39m signature = \u001b[33m'\u001b[39m\u001b[33mD->DdD\u001b[39m\u001b[33m'\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m isComplexType(t) \u001b[38;5;28;01melse\u001b[39;00m \u001b[33m'\u001b[39m\u001b[33md->ddd\u001b[39m\u001b[33m'\u001b[39m\n\u001b[32m-> \u001b[39m\u001b[32m1681\u001b[39m u, s, vh = \u001b[43mgufunc\u001b[49m\u001b[43m(\u001b[49m\u001b[43ma\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43msignature\u001b[49m\u001b[43m=\u001b[49m\u001b[43msignature\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mextobj\u001b[49m\u001b[43m=\u001b[49m\u001b[43mextobj\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m 1682\u001b[39m u = u.astype(result_t, copy=\u001b[38;5;28;01mFalse\u001b[39;00m)\n\u001b[32m 1683\u001b[39m s = s.astype(_realType(result_t), copy=\u001b[38;5;28;01mFalse\u001b[39;00m)\n", + "\u001b[31mKeyboardInterrupt\u001b[39m: " + ] + } + ], + "source": [ + "# now let's try using a normal tempo for comparison in speed\n", + "tempores=oqupy.tempo_compute(system=system,bath=bath,\n", + " initial_state=rhoini,\n", + " start_time=0,\n", + " end_time=300,\n", + " parameters=parameters,\n", + " alpha_t=np.ones(num_steps))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 11, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> PT-TEMPO computation:\n", + "100.0% 250 of 250 [########################################] 00:00:12\n", + "Elapsed time: 12.3s\n" + ] + } + ], + "source": [ + "tf=50\n", + "num_steps=int(tf/dt)\n", + "inisplit=1.0\n", + "# choose initial state to be thermal equilibrium given hamiltonian inisplit*(sigmax/2)\n", + "if (temperature>0):\n", + " z=2*np.cosh(inisplit/(2*temperature))\n", + " pupx=np.exp(-inisplit/(2*temperature))/z\n", + " pdnx=np.exp(+inisplit/(2*temperature))/z\n", + "else:\n", + " pupx=0\n", + " pdnx=1\n", + "\n", + "rhoini=oqupy.operators.spin_dm('x+')*pupx+oqupy.operators.spin_dm('x-')*pdnx\n", + "\n", + "system=oqupy.System(inisplit*op.sigma('x')/2)\n", + "\n", + "\n", + "pttempotest=oqupy.pt_tempo_compute(bath=bath,\n", + " start_time=0,\n", + " end_time=50,\n", + " parameters=parameters,\n", + " alpha_t=np.ones(num_steps))" + ] + }, + { + "cell_type": "code", + "execution_count": 12, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> Compute dynamics:\n", + "100.0% 250 of 250 [########################################] 00:00:00\n", + "Elapsed time: 0.1s\n" + ] + } + ], + "source": [ + "\n", + "dynamicspttest=oqupy.compute_dynamics(\n", + " process_tensor=pttempotest, \n", + " system=system,\n", + " initial_state=rhoini,\n", + " start_time=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 13, + "metadata": {}, + "outputs": [], + "source": [ + "# smooth switching function\n", + "lamconst=2\n", + "tf=30\n", + "def smswitch(t):\n", + " if t<=tf:\n", + " return (0.1+0.9*(t**lamconst/(t**(lamconst)+(tf-t)**(lamconst))))\n", + " else:\n", + " return 1.0\n", + "smv=np.vectorize(smswitch)\n", + "alpha_tramp=smv(dynamicspttest._times)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 14, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> PT-TEMPO computation:\n", + "100.0% 250 of 250 [########################################] 00:00:10\n", + "Elapsed time: 10.8s\n" + ] + } + ], + "source": [ + "pttempotestswitch=oqupy.pt_tempo_compute(bath=bath,\n", + " start_time=0,\n", + " end_time=50,\n", + " parameters=parameters,\n", + " alpha_t=alpha_tramp)" + ] + }, + { + "cell_type": "code", + "execution_count": 15, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> Compute dynamics:\n", + "100.0% 250 of 250 [########################################] 00:00:00\n", + "Elapsed time: 0.1s\n" + ] + } + ], + "source": [ + "\n", + "dynamicspttestswitch=oqupy.compute_dynamics(\n", + " process_tensor=pttempotestswitch, \n", + " system=system,\n", + " initial_state=rhoini,\n", + " start_time=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 16, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 16, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjgAAAGdCAYAAAAfTAk2AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjgsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvwVt1zgAAAAlwSFlzAAAPYQAAD2EBqD+naQAAPctJREFUeJzt3Qd8VfX9//F39p4ECIEwIsiyIEMBiwsoIhWUUimVqlgEF9YiVKG01fbfFn+utjiqrRaxUgdtHVCloqAIZQ+VKSAjjCSEkIQkZN//4/sNuSYsAe++r+fjcbzn3nvuvd8cYvLO5ztOiMPhcAgAACCAhHq7AQAAAK5GwAEAAAGHgAMAAAIOAQcAAAQcAg4AAAg4BBwAABBwCDgAACDgEHAAAEDACVcQqq2t1YEDB5SQkKCQkBBvNwcAAJwFszbx0aNHlZGRodDQM9dogjLgmHCTmZnp7WYAAIDzkJ2drVatWp3xmKAMOKZyU3+CEhMTvd0cAABwFoqLi22Bov73+JkEZcCp75Yy4YaAAwCAfzmb4SUMMgYAAAGHgAMAAAIOAQcAAAQcAg4AAAg4BBwAABBwCDgAACDgEHAAAEDAIeAAAICAQ8ABAAABh4ADAAACDgEHAAAEHAIOAAAIOEF5sU0A8ASHw6GjFdUqKKnU4dJKFZRW6khppUoqqlVZU6vK6uNbTa2qaxwKDwtRWGiIwu0Wau9HhYfWbRFhijZb/X54qL0fFRGq6PC658xx9behoV9/MUIgkBFwAOAbhphDJRXalnPUbrsPl2pvwTFlF5Rp/5FjNrx4Q+TxYGRDUUSoDUzmAsyhISEKdd6GKDS0bj/k+ONhxx93Hnv8+YavCzn+vIlQdbfH7x/fV/1xzufrrv5sI1fD40/1+kava3hcXWA7+fHjrznT+x5/4akePzEImn/Pulupbq9+/+THzR2zf/wl9piv9hs/rkaPN36vU76+/pjTfH7d0w0eO80xjgYf3OizGx331WN1x538vid/XSd+lvOTnI91a5mkKdd0lLcQcADgHBSVVWl99hGt31uo9dmF2ri/yFZmziQ2MkypcZFqEheplLhIxUeFHw8gddUWs28qN7W1DlWbzVR07K1DFdU1Kq+qdd6WV9eoosGt8/GqGvuaevXVoaPl1fz7IigRcADgDEyAWLP7iD7Znq9lO/K18UCR86/ZeqYI0DYtTh2bJyiraZxap8Yq02wpsWqaEGWrKJ5gglFFdV3YKa+uVYW5PR6GTHgy+aem1vw1Xrdfa2/r/jo3j9fd10nP261WXx17/Lb+L3vHCdWM+r/m69/r+NONjj+pMuB8z68+56T3PcXrG1Ym6j7vFO97mtfbR45/ncfrS85KUp2GVaPjj9RXqU56/KtK0OmPaVCJavAR9RWl+scbVpmcxzaoQNU91rha1bANp/r8kBMeqz++8df1VTXsnD73eNWuUaVNUvPEaHkTAQcATlBWWa2Ptx3SuxtztGhLrkoraxo93y4tTj0yk9WjTYoubpWsDs3jPRZiziQ8zIzbCVVcFD/aAf4vAABTNah1aMWXhzV37T4t2JijY1VfhRpThbm8fZr6d0hT//Zpaublv0wBfD0CDoCgll9SoVdX7tXra7K178gx5+OZqTG69qIWGnJRuq3SMCsJ8C8EHABB6Yvco3rxk116c8N+OxjXSIgK17CLM3Rjr1a6ODO50bgKAP6FgAMgqHy+r0h/+OALLdqa53yse6sk3XpZW1uxiYn0/lgaAN8cAQdAUDDTuf/4wXZ9sCXXOfPpmq7pGte/nXq1SaFaAwQYAg6AgJZTVK5HF2zVv9fvdwab6y9uqXsHtFdW03hvNw+AmxBwAAQksxbMX5d8qWc/2umcETWse4buG9hB7ZsRbIBAR8ABEHCWfHFI09/6XNkFdbOiTBfUr67rou6Zyd5uGgAPIeAACBjmkgm/nb/Z2R3VIilaU6/tpOHdMxhjAwQZAg6AgPCfzw7ql29vtCHHzO4ee1lbTRnckVV9gSBFwAHg14rLq/Tw25ucVRtzPahHRn5LPVqneLtpALyIgAPAb63aVaBJr2/Q/sJjdnbU3Ve1108GdrBX5wYQ3Ag4APzyulF//ninnnh/m72CtLmswh9GXazebVO93TQAPoKAA8CvFJVV6f43NujD4ysRf69nS/16eFclREd4u2kAfAgBB4Df2HSgSHe+stZO/zbdUP/v+q76wSWtvd0sAD6IgAPALyzYmGPH25hF+0yX1J/H9NJFLZO83SwAPoqAA8CnORwOPffxl/q/BVvt/cs7pOnpH/ZUUixdUgBOj4ADwGdVVtdq+pufa+7affb+Lf3a2BWJw8OYJQXgzAg4AHxSaUW1HW/zyfZ8OwX8oWFddetlbb3dLAB+goADwOeY1Yhve2m1Ps0uVGxkmJ4Z01NXd2zm7WYB8CMEHAA+xSzad/OLK/XloVKlxEbob2MvYVViAOeMgAPAZ+zOL9UP/7pCB4vKlZEUrZfHXar2zRK83SwAfoiAA8An7DLh5i8rlFNcrguaxunv4/ooIznG280C4KcIOAC8buehEhtu8o5W6MLm8Zpze181TYjydrMA+DECDgCv2pFXYrulDh2tsFcCnzO+j9LiCTcAvhkCDgCvyS4o05gX6sJNp/QEzbm9j5oQbgC4gFtXyyooKNCYMWOUmJio5ORkjRs3TiUlJWd8zc6dOzVixAg1bdrUvm7UqFHKzc1tdEzbtm0VEhLSaHvkkUfc+aUAcLG84nL96MWVyi2uUIdm8frH+L6EGwD+EXBMuNm0aZMWLlyo+fPna8mSJZowYcJpjy8tLdXgwYNtYFm0aJGWLVumyspKDRs2TLW1tY2O/c1vfqODBw86t3vvvdedXwoAFyosq9TNL67SnsNlap0aq1du76PUuEjOMQDf76LasmWLFixYoNWrV6t37972saeeekpDhw7V448/royMjJNeYwLN7t27tX79elu9MWbPnq2UlBQbeAYNGuQ8NiEhQenp6e5qPgA3rlB866zV2pZ7VM0To2y3VPPEaM43AP+o4Cxfvtx2S9WHG8MElNDQUK1cufKUr6moqLDVm6iorwYYRkdH29csXbq00bGmS6pJkybq0aOHHnvsMVVXV5+2LeZ9i4uLG20APK+6plYT/7HOrlBsFvF7ZVwfZabG8k8BwH8CTk5Ojpo1a7y0enh4uFJTU+1zp9K3b1/FxcXpwQcfVFlZme2ymjJlimpqamw3VL2f/OQneu2117R48WLdcccd+v3vf68HHnjgtG2ZMWOGkpKSnFtmZqYLv1IAZ3tV8F++vUmLtx1SdESoXaG4Q3MW8QPgIwFn6tSpJw3wPXHbunXreTXGDCyeO3eu5s2bp/j4eBtGCgsL1bNnT1vFqXf//ffrqquuUrdu3XTnnXfqiSeesN1fplJzKtOmTVNRUZFzy87OPq/2ATh/f/54p15dtVchIdLM0T24/AIA3xqDM3nyZI0dO/aMx2RlZdnxMXl5eY0eN91IZmbVmcbOmEHGZiZVfn6+rfiYbi5zvHnP0+nTp499bzN+p2PHjic9b7q8GnZ7AfCstzfs16MLttn9h67rosFdGT8HwMcCjqmymO3r9OvXz1Zf1q5dq169etnHzEBhMxvKBJKvk5aW5nyNCUrDhw8/7bEbNmywFZ4Tu8QAeN+G7EL97J+f2f3b+7fT2G+383aTAAQBt82i6ty5s4YMGaLx48frueeeU1VVlSZOnKjRo0c7Z1Dt379fAwcO1Msvv6xLL73UPjZr1iz7WhOizEDl++67T5MmTXJWZsxjZpDy1VdfbWdSmfvm+R/96Ed2thUA35FbXK4JL69RZXWtBnVurp8P7eztJgEIEm5dyXjOnDk21JgQYyosI0eO1MyZM53Pm9Czbds2O6C4nrlvxsyYriyzoN/06dNtgKlnuprMAOOHH37Yjrlp166dfd6MywHgO8qranTH39fa60uZhfz+8IPuCg0N8XazAASJEIeZ2hBkzDRxM4DZDDiuX28HgOuYHytT5n6mf63bp6SYCL0z8dtq0ySOUwzAY7+/3bqSMYDg9PLyPTbcmILN0zf1INwA8DgCDgCXWr/3iH77n81234y5ubzD109KAABXI+AAcJkjpZWa+I/1qqpx6NqL0jWuPzOmAHgHAQeAS9TWOnT/Gxu0v/CY2jaJ1f99v5td+BMAvIGAA8BlKxWbyzBEhYfq2TG9lBgdwZkF4DUEHADf2JrdBXri/bqVin9zfVd1yWB2IgDvIuAA+EaKy6v009c3qNYh3XBxhkb15mK2ALyPgAPgG/nVWxu178gxZabG6P/dcBHjbgD4BAIOgPP21vr9emvDAYWFhuiPP7hYCYy7AeAjCDgAzkt2QZl++dZGu3/vgPbq1SaVMwnAZxBwAJzXlPDJb3yqoxXV6tUmRROvbs9ZBOBTCDgAztlL/9utVbsLFBsZpj+MuljhYfwoAeBb+KkE4Jx8eahEj/53q/NSDK2bxHIGAfgcAg6As1ZT69DP/vmZyqtq1b99msb0ac3ZA+CTCDgAztrflu7S2j1HFB8VzqUYAPg0Ag6As7LzUIkeO75a8S+v66yWyTGcOQA+i4AD4KxmTU371+eqrK7VFRc2ZbViAD6PgAPga72+Jts5a+r3I1itGIDvI+AAOKO84nL9/t0tdn/y4I5qlcKsKQC+j4AD4IwenrdJR8ur1a1VksZe1pazBcAvEHAAnNbCzbl69/Mce62pR77Xzd4CgD8g4AA4pbLKav3q7bprTY2/PEtdMhI5UwD8BgEHwCk9tWiHDhaVKzM1Rj8d1IGzBMCvEHAAnGRHXole+ORLu//QdV0VHRHGWQLgVwg4ABpxOBx6+J1NqqpxaGCnZhrUpTlnCIDfIeAAaMQMKl66I1+R4aF6aFhXzg4Av0TAAeBUWlGt/zd/s92/+6oLuFI4AL9FwAHgNHPRduUU1w0svvPKCzgzAPwWAQeAtSPvqF78ZJfdf3gYA4sB+DcCDgA7sPihdzaputahQZ2baWBnBhYD8G8EHAB6b2OOlu04bAcW/+o6BhYD8H8EHCDIlVfVOC+meecVWQwsBhAQCDhAkJu1bLf2HTmm5olRuvMqBhYDCAwEHCCIHTpaoWcW77D7D1zTSbGR4d5uEgC4BAEHCGJPLtymkopqdWuVpBE9Wnq7OQDgMgQcIEhtPlCs11dn2/1fXtdFoaEh3m4SALgMAQcI0mnhv/3PZtU6pO92a6FL2qZ6u0kA4FIEHCAIfbAlT//bWTctfOqQTt5uDgC4HAEHCDKV1bXOaeG392+nzNRYbzcJAFyOgAMEmZeX79au/FKlxUfp7qvbe7s5AOAWBBwgiBSVVempRXXTwqcMvlDxUUwLBxCYCDhAEHn24x0qOlalC5vH68bemd5uDgC4DQEHCBIHCo/ZVYuNB4d0UhjTwgEEMAIOECSeXPiFHWB8abtUDejUzNvNAQC3IuAAQWBrTrH+tW6f3Z92bSeFhLCoH4DARsABgsCjC7bJ4ZCGfitdPVqneLs5AOB2BBwgwK348rAWbc2zY25+dg2L+gEIDgQcIMAvyTDjva12/4eXZqpdWpy3mwQAHkHAAQLYu5/n6NPsQsVGhum+gRd6uzkA4DEEHCBAVdXU6rH/1lVvxl+epaYJUd5uEgD4f8ApKCjQmDFjlJiYqOTkZI0bN04lJSVnfM3OnTs1YsQINW3a1L5u1KhRys3NPem4//znP+rTp49iYmKUkpKiG264wV1fBuC3Xl21V7sPlyktPlLjr8jydnMAIDACjgk3mzZt0sKFCzV//nwtWbJEEyZMOO3xpaWlGjx4sJ2+umjRIi1btkyVlZUaNmyYamtrncf961//0s0336zbbrtNn376qT3upptucteXAfilkopq/emD7Xb/voEduCQDgKAT4jCjEF1sy5Yt6tKli1avXq3evXvbxxYsWKChQ4dq3759ysjIOOk177//vq699lodOXLEVm+MoqIiW6Exzw0aNEjV1dVq27atfv3rX9uK0PkqLi5WUlKSff/6zwICbVG/mR9ut4OK3590hSLC6I0G4P/O5fe3W37qLV++3HZL1YcbwwSU0NBQrVy58pSvqaiosNWbqKivxglER0fb1yxdutTeX7dunfbv328f69Gjh1q0aGFD0caNG93xZQB+Kb+kQi988qXd/9k1HQk3AIKSWwJOTk6OmjVrvBR8eHi4UlNT7XOn0rdvX8XFxenBBx9UWVmZ7bKaMmWKampqdPDgQXvMl1/W/dB++OGH9Ytf/MJ2fZkKz1VXXWXH/JyOCU8m9TXcgED17OKdKqusUbdWSbr2onRvNwcAfD/gTJ061VZZzrRt3Vo3a+NcmYHFc+fO1bx58xQfH29LUIWFherZs6et2Bj1Y3GmT5+ukSNHqlevXpo1a5b9XPPa05kxY4Z9v/otM5OrKCMw7S88pldW7HFWb7gkA4BgFX4uB0+ePFljx4494zFZWVlKT09XXl5eo8fN+BlTZTHPnY4ZZGxmUuXn59uKj+nmMseb9zRMl5RhxvfUM11a5vm9e/ee9n2nTZum+++/33nfVHAIOQhET324XZU1terTLlX926d5uzkA4B8Bx1RZzPZ1+vXrZ6sva9eutVUWw8yMMhUYM73766SlpTlfY4LS8OHD7X3zXibQbNu2Tf3797ePVVVVaffu3WrTps1p38+8puHYHiAQ7cov1dy1dRfUpHoDINi5ZQxO586dNWTIEI0fP16rVq2yU7knTpyo0aNHO2dQmcHCnTp1ss/XM91NK1assFWcV155RTfeeKMmTZqkjh072ufNiOk777xTDz30kJ1ZZYLOXXfdZZ8zxwLB7A8Lv1BNrUMDOjVT77ap3m4OAPhPBedczJkzx4aagQMH2jE0ZszMzJkznc+byosJKGZAcT1z33Qnma4sMx3cjLUxAaehxx57zHZfmbVwjh07ZitCptJjBhsDwWrLwWK98+kBuz95MJdkAAC3rIPj61gHB4Hm9tlr9MGWXH23Wws9c1NPbzcHAAJzHRwAnrNu7xEbbkJDpPu/Q/UGAAwCDuDnHv/vNnv7/V6tdEHTeG83BwB8AgEH8GPLduTrfzsPKzIsVD8Z2MHbzQEAn0HAAfyUGT732PHqzU19WqtVSqy3mwQAPoOAA/ipD7bkaUN2oWIiwnT31Rd4uzkA4FMIOIAfqq116In366o3t327rZolRHu7SQDgUwg4gB/6z+cHtTXnqBKiw3XHFVRvAOBEBBzAz5jViv/4wRd2f/zlWUqKjfB2kwDA5xBwAD8z79MD2nmoVEkxEbZ7CgBwMgIO4Eeqa2r1pw+32/0JV2QpIZrqDQCcCgEH8CNvbThgrxqeGhepWy+jegMAp0PAAfxEVU2tZh6v3txxRZbio9x2rVwA8HsEHMBP/HvdPu0tKFNafKRu7tfG280BAJ9GwAH8QGW1qd7ssPt3XnmBYiOp3gDAmRBwAD8wd2229hceU9OEKP2oL9UbAPg6BBzAx1VU1+iZRXXVm3uuukDREWHebhIA+DwCDuDj3lidrQNF5UpPjNboS1t7uzkA4BcIOIAPK6+q0dOLj1dvBrSnegMAZ4mAA/iwV1ftVW5xhVomx2hU71bebg4A+A0CDuCjjlXW6NmPdtr9iQPaKyqcsTcAcLYIOICPmrNyjw4drVBmaoy+34vqDQCcCwIO4IPKKqv15+PVm3uv7qCIMP5XBYBzwU9NwAe9vHyPDpdWqk2TWI3o2dLbzQEAv0PAAXxMSUW1nv+4rnrzkwFUbwDgfBBwAB8z+3+7daSsSllpcbr+4gxvNwcA/BIBB/AhxeVV+suSL+3+fYM6KJyxNwBwXgg4gA+ZtXS3io5VqX2zeF3XjeoNAJwvAg7gI0yweWFpXfXmp4M6KCw0xNtNAgC/RcABfGjszdHyal3YPF5DL2rh7eYAgF8j4AA+4Gh5lV5cusvu3zugg0Kp3gDAN0LAAXxk3Zv6sTdDv0X1BgC+KQIO4APr3vz1k7qxN/cOaM/YGwBwAQIO4GV/X75HhcfXvWHmFAC4BgEH8PI1p+qrN+aK4cycAgDXIOAAXvTKij0qKK1U2yaxGt6ddW8AwFUIOICXHKusca5afM/V7Vm1GABciIADeMmclXuUX1KpzNQY3dCDK4YDgCsRcAAvKK+q0fP11Zur2iuCa04BgEsRcAAveHXVXh06WqGWyTH6Xs9W/BsAgIsRcAAvVG+e+3in3b/76gsUGc7/hgDgavxkBTxs7pps5RZXKCMpWt/vRfUGANyBgAN4UEV1jZ79qK56c9dVFygqPIzzDwBuQMABPOifa/fpYFG50hOjNeqSTM49ALgJAQfwkMrqWj27uK56c+eVWVRvAMCNCDiAh/x73T7tLzympglRGn1pa847ALgRAQfwgKqaWj3z0Q67f+eVFyg6grE3AOBOBBzAA95cv1/ZBceUFh+lm6jeAIDbEXAAN6s21ZvFddWbO67IUkwk1RsAcDcCDuBmb284oD2Hy5QaF6kxfRl7AwCeQMAB3Kim1qGnj1dvxl+epdjIcM43AHgAAQdwo3mfHtCu/FKlxEboln5tONcAEAgBp6CgQGPGjFFiYqKSk5M1btw4lZSUnPE1O3fu1IgRI9S0aVP7ulGjRik3N9f5/EcffaSQkJBTbqtXr3bnlwOcc/XmqUXb7f7tl2cpLorqDQAERMAx4WbTpk1auHCh5s+fryVLlmjChAmnPb60tFSDBw+2YWXRokVatmyZKisrNWzYMNXW1tpjLrvsMh08eLDRdvvtt6tdu3bq3bu3O78c4Jy8+/lB7TxUqqQYqjcA4Glu+5Nyy5YtWrBgga2q1AePp556SkOHDtXjjz+ujIyMk15jAs3u3bu1fv16W70xZs+erZSUFBt4Bg0apMjISKWnpztfU1VVpbffflv33nuvDUaAL6htUL0Z17+dEqIjvN0kAAgqbqvgLF++3HZLNayqmIASGhqqlStXnvI1FRUVNqRERUU5H4uOjravWbp06Slf88477+jw4cO67bbbTtsW877FxcWNNsCdFmzK0Re5JUqIDtetl7XlZANAoAScnJwcNWvWrNFj4eHhSk1Ntc+dSt++fRUXF6cHH3xQZWVltstqypQpqqmpsV1Rp/Liiy/qmmuuUatWrU7blhkzZigpKcm5ZWZykUO4t3oz88O66s2Pv93OdlEBAHw84EydOvW0g3zrt61bt55XY8zA4rlz52revHmKj4+3YaSwsFA9e/a0VZwT7du3T//973/t4OUzmTZtmoqKipxbdnb2ebUPOBvvb87V1pyjSogKtwEHAOAHY3AmT56ssWPHnvGYrKwsO04mLy+v0ePV1dV2ZlXDMTQnMoOMzUyq/Px8W/Ex3VzmePOeJ5o1a5aaNGmi4cOHn7E9psurYbcX4C4Ox1fVG9M1lRRL9QYA/CLgmCqL2b5Ov379bPVl7dq16tWrl33MDBQ2s6H69Onzta9PS0tzvsYEpRNDjPlFYgLOLbfcoogIfonANyzcnKvNB4sVFxlmBxcDAAJsDE7nzp01ZMgQjR8/XqtWrbIzpCZOnKjRo0c7Z1Dt379fnTp1ss/XM6FlxYoVtorzyiuv6MYbb9SkSZPUsWPHRu9vgs+uXbvsFHHAZ6o3i76q3qTERXq7SQAQtNy68ticOXNsqBk4cKAdQzNy5EjNnDmz0RTvbdu22QHF9cx9M2bGdGW1bdtW06dPtwHnVIOLzZo4JiABvmDR1jxt3F+s2Mgwu7AfAMB7Qhzmz84gY6aJmwHMZsBx/Xo7wDdh/je6/pll+mxfke64MkvTru3MCQUAL/7+5lpUgAt89MUhG25iIsLsRTUBAN5FwAFcUL350wd1Y29+1Le10uKZsQcA3kbAAb6hJdvztSG7UFHhoZpwxQWcTwDwAQQc4BtXb76w+2P6tFHTBKo3AOALCDjAN7Bsx2Gt21tXvbnzSsbeAICvIOAA36R682Fd9eaHl7ZWs8RoziUA+AgCDnCeln95WKt3H1FkmKneMPYGAHwJAQc4T/Uzp0Zfmqn0JKo3AOBLCDjAeVjx5WGt3FWgiLAQqjcA4IMIOMB5qL9i+KjemcpIjuEcAoCPIeAA52j17gL9b+dhW725++r2nD8A8EEEHOA8qzff79VKLaneAIBPIuAA52DtniP6ZHu+wkNDdPdVVG8AwFcRcIBz8OTCbfb2ez1bKjM1lnMHAD6KgAOcpeU7D9uVi83Ym3sHdOC8AYAPI+AAZ7lqcX315geXZFK9AQAfR8ABzoIZd2NXLQ4P1cSrqd4AgK8j4ABnUb154v266s3NfduwajEA+AECDvA1PtySp0/3FSkmIkx3XcU1pwDAHxBwgDOorXXoiYV1Vwwf++22SouP4nwBgB8g4ABn8N7GHG05WKyEqHDdcUUW5woA/AQBBziNmlqH/vBBXfXmx/3bKTk2knMFAH6CgAOcxjuf7teOvBIlxURo3OXtOE8A4EcIOMApVFbX6o8f1F1z6o4rs5QYHcF5AgA/QsABTuEfK/doz+EyO6j41n5tOUcA4GcIOMAJjpZXaeaiHXb/p4M6KC4qnHMEAH6GgAOc4C9LvlRBaaWy0uLsZRkAAP6HgAM0kFdcrhc+2WX3HxjSURFh/C8CAP6In95AA3/4YLuOVdWoZ+tkXdM1nXMDAH6KgAMcZ6aEv7Em2+5PG9pZISEhnBsA8FMEHOC4RxdstYv7DercXJe0TeW8AIAfI+AAktbsLtD7m3MVGiI9OKQj5wQA/BwBB0HP4XBoxntb7XkY1TtTHZonBP05AQB/R8BB0FuwMUdr9xxRdESoJn3nwqA/HwAQCAg4CGrlVTX63btb7P6Ey7PUPDHa200CALgAAQdB7cWlu7TvyDGlJ0brzqsu8HZzAAAuQsBB0MopKtczi+suyTBtaCfFRnJJBgAIFAQcBPW08LLKukX9hnfP8HZzAAAuRMBBUFq/94j+vX6/3X9oWFcW9QOAAEPAQdCprXXo4Xmb7f73e7VS98xkbzcJAOBiBBwEnVdX79Wn2YWKjwrXA9ewqB8ABCICDoJKfkmFHl2wze7f/50L1Yxp4QAQkAg4CCoz3t2qomNV6tIiUbf0a+Pt5gAA3ISAg6Cx8svD+te6fTIXCf/tiIsUHsa3PwAEKn7CIyhU1dTql29vtPujL2mtnq1TvN0kAIAbEXAQFP76yZf6IrdEqXGRXC0cAIIAAQcBb+ehEv3xg+12f/rQzkqOjfR2kwAAbkbAQcCvefPgPz9TZXWtrrywqb7Xs6W3mwQA8AACDgLay8t3a82eI4qLDNPvv/ctViwGgCBBwEHAyi4o06P/rVvzZuq1ndQyOcbbTQIAeAgBBwHJ4XDo529+bi+meWm7VI3pw5o3ABBM3BZwCgoKNGbMGCUmJio5OVnjxo1TSUnJGV+zc+dOjRgxQk2bNrWvGzVqlHJzcxsd88UXX+j6669XWlqaPaZ///5avHixu74M+KlXVuzRJ9vzFRUeqv8b2U2hoSHebhIAIBACjgk3mzZt0sKFCzV//nwtWbJEEyZMOO3xpaWlGjx4sB0jsWjRIi1btkyVlZUaNmyYamtrncddd911qq6utsesXbtW3bt3t4/l5OS460uBH86a+t27W5xdU+3S4rzdJACAh4U4TC3fxbZs2aIuXbpo9erV6t27t31swYIFGjp0qPbt26eMjIyTXvP+++/r2muv1ZEjR2xlxigqKlJKSop9btCgQcrPz7fVHROWLr/8cnvM0aNH7fEmSJljzkZxcbGSkpLs+9d/FgJnQb+Rf/6fPttXpP7t0/Tyjy+legMAAeJcfn+7pYKzfPly2y1VH24MEz5CQ0O1cuXKU76moqLCVm+ioqKcj0VHR9vXLF261N5v0qSJOnbsqJdfftlWfEwl5/nnn1ezZs3Uq1ev07bHvLc5KQ03BKanPtxuw01STIQev7E74QYAgpRbAo7pLjKho6Hw8HClpqaetiupb9++iouL04MPPqiysjIbYKZMmaKamhodPHjQHmMC0AcffKD169crISHBBqAnn3zSVodMped0ZsyYYRNf/ZaZmenirxi+YO2eI3p68Q67/7sRFyk9KdrbTQIA+EPAmTp1qg0ZZ9q2bt16Xg0xXU9z587VvHnzFB8fb4NIYWGhevbsaas4hulNu+eee2x4+uSTT7Rq1SrdcMMNdpxOfQg6lWnTptlyVv2WnZ19Xm2E7zJXCL/vtfWqdUg3XJyh67qd3A0KAAge4edy8OTJkzV27NgzHpOVlaX09HTl5eU1etx0J5mZVea50zGDjM1MKjPWxlR8TDeXOd68p2EGFpsByw3H6Tz77LN2/M3s2bNtADsV0+3VsOsLgcUE3wf++an2HTmm1qmx+s0NF3m7SQAAfwo4pspitq/Tr18/W30xs5zqx8aYcGJmQ/Xp0+drX2+mgNe/xgSl4cOH2/um68qor+jUM/cbzrRCcJn9v93676ZcRYSF6OmbeigxOsLbTQIABOIYnM6dO2vIkCEaP3687UYyU74nTpyo0aNHO2dQ7d+/X506dbLP15s1a5ZWrFhhqzivvPKKbrzxRk2aNMkOLK4PTmasza233qpPP/3Uronzs5/9TLt27dJ3v/tdd3wp8HGf7yvS79+t6xb9+dDO6tYq2dtNAgD4WwXnXMyZM8eGmoEDB9oKy8iRIzVz5kzn81VVVdq2bZuzKmOY+2a8jOnKatu2raZPn24DTsPKjhlQbB4fMGCAfY+uXbvq7bfftuvhILgUl1fpnn+sU2VNra7p2lxjL2vr7SYBAAJ5HRxfxzo4gXGV8PEvr9GHW/PsNabe/cnlSoqlawoAAlmxt9fBAdztTx9ut+EmMjxUz/2oF+EGANAIAQd+Z+HmXBtwjN+P+Ja+1SrJ200CAPgYAg787jpT97++we7f2q+Nvt+rlbebBADwQQQc+NVifhNeXqOjFdW6pG2KfnFdF283CQDgowg48JuLaN4zZ512HipVemK0nhnTUxFhfPsCAE6N3xDweWai36/e3qSlO/IVGxmmF8f2VrMErjMFADg9Ag583otLd+nVVXsVEiLNHN1DXTMYVAwAODMCDnza+5ty9Lt3t9j96UM7a1CX5t5uEgDADxBw4LM27i/Sfa9tkFmK8qY+rTWufztvNwkA4CcIOPBJB4uO6fbZa3SsqkaXd0jTr4d3VYjpowIA4CwQcOBzCssqdcuLq5RTXK72zeL19E3MmAIAnBsCDnzKscoaW7nZnlei5olReum2S5QUwzWmAADnhoADn1FdU6t7X12nNXuOKDE6XC//uI9apcR6u1kAAD9EwIHPrHXz8zc/1wdb8hQVHqoXbr1EHdMTvN0sAICfIuDAJzz+/ja9sWafQkOkp37YQ5e2S/V2kwAAfoyAA6/729JdembxTufVwQd3Tfd2kwAAfo6AA696Y3W2fjN/s92f/J0LNfrS1vyLAAC+MQIOvGbepwf04L8/s/u392+niQPa868BAHAJAg684oPNuZr0et0qxT+8tLWmf7czC/kBAFyGgAOPW7YjX3f/Y52qax26/uIM/faGiwg3AACXIuDAo9buOaLxL69RZXWtBndprsdv7K4wM3UKAAAXIuDAoxfPHDtrlcoq664v9dRNPRQRxrcgAMD1+O0Cj9iee1S3/G2VjpZX65K2KfrLzb0VFR7G2QcAuAUBB2735aESjXlhpQpKK/Wtlkl6cewliokk3AAA3Cfcje+Nc3C0vErvfZ6jFbsOq1lCtO65+gIlRPv/RSZ355fqh39dobyjFerYPEEv//hSJQbA1wUA8G0EHB9QUV2jG59brq05RxutEfPH0Rfrkrb+e8mCPYfrwk1ucYU6NIvXnPF9lBIX6e1mAQCCAF1UPuAvH39pw01KbITuvPICtU6N1f7CY7pt1mrtyCuRP8ouKNMP/7JCB4vK1b5ZvP4xvq/S4qO83SwAQJAg4HjZrvxSPbV4h91/eHhXTb22k96773J7scmSimrd+cpae+tv4Wb0X1boQFG5sprG6R/j+6hpAuEGAOA5BBwve+rD7XZNGDNtenj3DPtYXFS4nrmpp5onRtkKzq/f2SR/YSpPplvK3LZLi9Or4/vaMUUAAHgSAceLqmtq9eHWPLt/74AOjVbzNRWPp2/qaffnrt2nNbsL5OsOmHDzlxXad+SY2jaJteGmeSLhBgDgeQQcL1q3t1BFx6qUHBuhnq2TT3reDDD+Qe9Mu/+LtzbaQOTL4eamv67Q3oIyO4bo1Ql9lZ5EuAEAeAcBx4s+3Jprb6+6sKnCT7Oi74PXdrIByAxCfnn5HvnqmJtRzy/X7sNlykyNseGmRVKMt5sFAAhiBBwvWrSlrntqQOfmpz0mNS5SD1zTye4/ufAL5RWXy9cW8TNT3E23lBlz8/qEfmqZTLgBAHgXAcdL9h4u0/a8EnuhySs7ND3jsaMvyVT3zGQ7m+p3726Rr/gi96hGPb9COcXldp2b1yf0VQbhBgDgAwg4XvLx9kP2tlebFCXFnnll39DQEP32+otkxiC/veGA/rczX9626UCRnQqeX1Khzi0S9dqEvmrGgGIAgI8g4HjJpv1F9vbSs1yp+FutkvSjPm3s/kNvb1KVFwccr997xM6WMteW6t4qSa+O76MmLOIHAPAhBBwv2XKw2N6a6sfZmjK4o5rERdqurZeW7XZj605v8bY83fTXlSour1bvNin6++19lBzL5RcAAL6FgOMFNbUObcutu+5U5xYJZ/0605VlZlUZf/jgC+07UiZP+ve6fRo/e42OVdXoigubajYXzgQA+CgCjpcuz1BeVauYiDC1aRJ3Tq/9fs9WuqRtisoqa/TzNzfK4XDI3cxn/HXJl7r/jU9VXevQiB4t9eKtve2KywAA+CICjhe7pzqmJ9hZVOfCDDh+ZGQ3RYaHaskXh+wqx+5kxvpMf2ujc/bW7f3b6YkbuyviNOv2AADgC/gt5QVbc4rPuXuqoQuaxmvSoAvt/m/mbbYVIXc4Ulqpm19cqX+s3GtncE0f2lm/uK6LDVkAAPgyAo4XbDl49JwHGJ9o/OXt7AwsszbOPXPWqbyqxoUtlLbnHtUNzy7Tii8LFBcZphdu6a3xV2S59DMAAHAXAo6fzKA6kbm0w8wf9rCzqjYfLNa0f3+u2lqHS8bbzFm5R8OeXqo9xy+98O+7v62BZ1htGQAAX0PA8bDCskodLKq73EKn9PProqpnLmb5p9E97DieN9fv12//s+UbDTo2XVJ3/H2tpr+50Q6CvrxDmt6+p78dKwQAgD8h4HjYtpy67qlWKTFKiD7zCsZno3+HND32/W52/2/LdunX8zaf81XHTSh67/ODGvKnJXp/c64iwkL0i+921uzbLrXXwgIAwN8wz9fD9hTUrV1jLkzpKt/r2UrFx6r08LzNeul/u7XzUIn+b2S3s7ou1No9R/Tkwm1atuOwvX9B0zhbFbqoZZLL2gcAgKcRcDws+3jAaZ0a69L3HfvtdmqeGG3Xqvlke74GPvGxfty/rb7fK/OkMGUusfDBllz9c+0+rdpVYB8z087vvCJLd13VXjGRYS5tGwAAnkbA8bC9xwNOposDjnHtt1ooq2m8fvnWRq3aXaBnFu+0W8vkGNslZlZQzjta4WyDER4aopE9W+meq9urdRPXtwkAAG8g4ARIBaeeGRD8+h199d7GHL22OlvLduRrf+ExuzU6rnmChl+cYVclPpuuLAAA/AkBx8P2Fhxza8AxQkJCNPRbLexWVFalHYdKbMCJDAtRYkyEurRI5AKZAICARsDxoGOVNcovqbD7mSme6Q4yF+js1SbFbgAABAu3TRMvKCjQmDFjlJiYqOTkZI0bN04lJSVnfM3OnTs1YsQINW3a1L5u1KhRys3NbXTMunXr9J3vfMe+Z5MmTTRhwoSvfV9fkX386t+J0eE2eAAAAD8LOCbcbNq0SQsXLtT8+fO1ZMkSG0ZOp7S0VIMHD7bdK4sWLdKyZctUWVmpYcOGqba2bl2XAwcOaNCgQWrfvr1WrlypBQsW2M8YO3as/Gn8jTsGGAMAADd3UW3ZssWGj9WrV6t37972saeeekpDhw7V448/royMjJNeYwLN7t27tX79elu9MWbPnq2UlBQbeEywMUEpIiJCzzzzjEJD67LZc889p27dumnHjh02+Piy+tlL7hx/AwAA3FTBWb58ue1Cqg83hgkoJpSYysupVFRU2OpNVFSU87Ho6Gj7mqVLlzqPiYyMdIYbIyambgZQ/TGne+/i4uJGmzdke2CAMQAAcFPAycnJUbNmzRo9Fh4ertTUVPvcqfTt21dxcXF68MEHVVZWZruspkyZopqaGh08eNAeM2DAAPv6xx57zHZfHTlyRFOnTrXP1R9zKjNmzFBSUpJzy8zMlDcrOK0IOAAA+E7AMWHCVFnOtG3duvW8GmIGFs+dO1fz5s1TfHy8DSKFhYXq2bOns2LTtWtX2231xBNPKDY2Vunp6WrXrp2aN2/eqKpzomnTpqmoqMi5ZWdnKxDXwAEAAOcxBmfy5MlfO6A3KyvLBo+8vLxGj1dXV9uZVea50zGDjM1Mqvz8fFvxMd1c5njznvVuuukmu5nZVabiY0LVk08+2eiYE5lur4ZdX95gLmhZP4sqM4WF9QAA8JmAY6osZvs6/fr1s9WXtWvXqlevXvYxM1DYzIbq06fP174+LS3N+RoTlIYPH37SMaZqY/ztb3+zY3XM1HFfdqSsSmWVNXa/JQEHAAD/G4PTuXNnDRkyROPHj9eqVavsDKmJEydq9OjRzhlU+/fvV6dOnezz9WbNmqUVK1bYKs4rr7yiG2+8UZMmTVLHjh2dxzz99NN2LZwvvvjCzqYy72vG2Jhqjy87WFQ3wDgtPlJR4VzMEgAAv1zJeM6cOTZ8DBw40I6PGTlypGbOnOl8vqqqStu2bbMDiuuZ+2a8jOnKatu2raZPn24DTkMmED300EN2cT8TkJ5//nndfPPN8nW5xeX2Nj0p2ttNAQAg4IU4zOCQIGOmiZtBzGbAcf2aO+72j5V79fM3P9egzs30wq2XeOQzAQAI1t/fblvJGI3lHO+iap5IBQcAAHcj4HhIzvEuqhZ0UQEA4HYEHA85WFQXcKjgAADgfgQcD2GQMQAAnkPA8ZCc4xUcuqgAAHA/Ao4HlFVWq7i82u7TRQUAgPsRcDxYvYmLDFNCdIQnPhIAgKBGwPHgDCoW+QMAwDMIOB6s4BBwAADwDAKOBys4jL8BAMAzCDgekMsMKgAAPIqA48FF/tK5TAMAAB5BwPHgIn90UQEA4BkEHA9WcFokxXji4wAACHoEHDerrqlVfkmF3W+eFBX033AAAHgCAcfNDpVUqNYhhYeGKC2OgAMAgCcQcDx4FfHQ0BB3fxwAACDgeG6KePNEqjcAAHgKFRw34zINAAB4HgHHU5dpSGQGFQAAnkLA8VgFhy4qAAA8hYDjoQoOi/wBAOA5BBwPVXBY5A8AAM8h4LiRw+FoMAYn2p0fBQAAGiDguFFhWZUqqmvtfjOmiQMA4DEEHA90T6XGRSo6IsydHwUAABog4Hgg4DDAGAAAzyLguNFX42+YIg4AgCcRcDwRcJJY5A8AAE8i4LhRbv0if8ygAgDAowg4brS/8Ji9bZHMFHEAADyJgONGew6X2ds2qbHu/BgAAHACAo6bVNXUOis4bZrEuetjAADAKRBw3ORA4THV1DoUGR6qZgnMogIAwJMIOG6yt6Cue6p1aqxCQ0Pc9TEAAOAUCDhuwvgbAAC8h4Dj7gpOEwYYAwDgaQQcN9lzuNTeMoMKAADPI+C4u4uKGVQAAHgcAccNHA6HsumiAgDAawg4bnC4tFKllTUKCZFapXAdKgAAPI2A48buqYykGEWFh7njIwAAwBkQcNxgb0HdAOPMVKo3AAB4AwHHDT7NLrK37dLi3fH2AADgaxBwXKy6plbzPztg9wd3ae7qtwcAAGeBgONiS3fkK7+kUqlxkerfIc3Vbw8AAM4CAcfF3t5QV70Z1q2FIsI4vQAAeAO/gV2orLJa/92UY/ev79HSlW8NAADOAQHHhRZuzlVZZY3aNIlVj8xkV741AAA4B+HncjDOrHfbVN3/nQuVEhepELPKHwAACLwKzu9+9ztddtllio2NVXJy8llf5uBXv/qVWrRooZiYGA0aNEjbt29vdExBQYHGjBmjxMRE+77jxo1TSUmJvK1lcox+MrCDbu7bxttNAQAgqLk14FRWVurGG2/UXXfdddavefTRRzVz5kw999xzWrlypeLi4nTNNdeovLzceYwJN5s2bdLChQs1f/58LVmyRBMmTHDTVwEAAPxNiMOUTNzspZde0k9/+lMVFhae8TjTlIyMDE2ePFlTpkyxjxUVFal58+b2PUaPHq0tW7aoS5cuWr16tXr37m2PWbBggYYOHap9+/bZ13+d4uJiJSUl2fc2VSAAAOD7zuX3t08NMt61a5dycnJst1Q984X06dNHy5cvt/fNremWqg83hjk+NDTUVnwAAAB8apCxCTeGqdg0ZO7XP2dumzVr1uj58PBwpaamOo85UUVFhd0aJkAAABC4zrmCM3XqVDtD6Ezb1q1b5UtmzJhhK0H1W2ZmprebBAAAfKmCY8bHjB079ozHZGVlnVdj0tPT7W1ubq6dRVXP3L/44oudx+Tl5TV6XXV1tZ1ZVf/6E02bNk33339/owoOIQcAgMB1zgGnadOmdnOHdu3a2ZDy4YcfOgONCSNmbE39TKx+/frZwcpr165Vr1697GOLFi1SbW2tHatzKlFRUXYDAADBwa2DjPfu3asNGzbY25qaGrtvtoZr1nTq1Elvvvmm3TfdW2a21W9/+1u98847+vzzz3XLLbfYmVE33HCDPaZz584aMmSIxo8fr1WrVmnZsmWaOHGinWF1NjOoAABA4HPrIGOzYN/s2bOd93v06GFvFy9erKuuusrub9u2zU73qvfAAw+otLTUrmtjKjX9+/e308Cjo6Odx8yZM8eGmoEDB9rZUyNHjrRr5wAAAHhsHRxfwzo4AAD4H79dBwcAAMAVCDgAACDgEHAAAEDA8amVjD2lftgRKxoDAOA/6n9vn83w4aAMOEePHrW3LPYHAIB//h43g43PJChnUZlFAQ8cOKCEhAS79o4r1a+SnJ2dzZXK3Yjz7BmcZ85zIOH72f/PtYksJtyYde/MMjFnEpQVHHNSWrVq5dbPMP+grvxHBefZm/h+5jwHEr6f/ftcf13lph6DjAEAQMAh4AAAgIBDwHExc1HPhx56iIt7uhnn2TM4z5znQML3c3Cd66AcZAwAAAIbFRwAABBwCDgAACDgEHAAAEDAIeAAAICAQ8BxoWeeeUZt27ZVdHS0+vTpo1WrVrny7YPSkiVLNGzYMLtqpVl1+q233mr0vBkj/6tf/UotWrRQTEyMBg0apO3bt3utvf5oxowZuuSSS+zK3s2aNdMNN9ygbdu2NTqmvLxc99xzj5o0aaL4+HiNHDlSubm5Xmuzv/rzn/+sbt26ORc/69evn9577z3n85xn13vkkUfsz46f/vSnnGcXe/jhh+25bbh16tTJZ76fCTgu8vrrr+v++++30+LWrVun7t2765prrlFeXp6rPiIolZaW2nNpwuOpPProo5o5c6aee+45rVy5UnFxcfa8m/+xcHY+/vhj+0NoxYoVWrhwoaqqqjR48GB77utNmjRJ8+bN09y5c+3x5lIn3/ve9zjF58isoG5+4a5du1Zr1qzRgAEDdP3112vTpk2cZzdYvXq1nn/+eRsqG+L72XW6du2qgwcPOrelS5f6znk208TxzV166aWOe+65x3m/pqbGkZGR4ZgxYwan10XMt+ubb77pvF9bW+tIT093PPbYY87HCgsLHVFRUY5XX32V836e8vLy7Ln++OOPnec0IiLCMXfuXOcxW7ZssccsX76c8/wNpaSkOF544QXOs4sdPXrU0aFDB8fChQsdV155peO+++6zj/P97DoPPfSQo3v37qd8zhfOMxUcF6isrLR/kZnukYbXuzL3ly9f7oqPwCns2rVLOTk5jc67uUaJ6R7kvJ+/oqIie5uammpvzfe2qeo0PM+mDN26dWvO8zdQU1Oj1157zVbKTFcV59m1TFXyu9/9bqPvW4Pz7FpmSIAZQpCVlaUxY8Zo7969PnOeg/Jim66Wn59vf1g1b9680ePm/tatW73WrkBnwo1xqvNe/xzOTW1trR2r8O1vf1sXXXSR8zxHRkYqOTmZ8+wCn3/+uQ00phvVjEt488031aVLF23YsIHz7CImOJqhAqaL6kR8P7uO+WPypZdeUseOHW331K9//Wtdfvnl2rhxo0+cZwIOgEZ/9ZofTg370eFa5peBCTOmUvbPf/5Tt956qx2fANfIzs7WfffdZ8eTmQkfcJ9rr73WuW/GOZnA06ZNG73xxht20oe30UXlAmlpaQoLCztpdLi5n56e7oqPwCnUn1vOu2tMnDhR8+fP1+LFi+1g2Ibn2XTDFhYWNjqe7+/zY/6qbd++vXr16mVnsJlB9H/60584zy5iukbM5I6ePXsqPDzcbiZAmskIZt9UEPh+dg9Trbnwwgu1Y8cOn/h+JuC46AeW+WH14YcfNir1m/umFA33aNeunf0fpeF5Ly4utrOpOO9nz4zfNuHGdJUsWrTInteGzPd2REREo/NsppGbvnbO8zdnflZUVFRwnl1k4MCBthvQVMnqt969e9vxIfX7fD+7R0lJiXbu3GmX7fCJnxseGcocBF577TU7e+ell15ybN682TFhwgRHcnKyIycnx9tN8/uZEOvXr7eb+XZ98skn7f6ePXvs84888og9z2+//bbjs88+c1x//fWOdu3aOY4dO+btpvuNu+66y5GUlOT46KOPHAcPHnRuZWVlzmPuvPNOR+vWrR2LFi1yrFmzxtGvXz+74dxMnTrVzk7btWuX/X4190NCQhzvv/8+59mNGs6iMvh+do3Jkyfbnxvm+3nZsmWOQYMGOdLS0uxMTF84zwQcF3rqqafsP2ZkZKSdNr5ixQpXvn1QWrx4sQ02J2633nqrc6r4L3/5S0fz5s1twBw4cKBj27Zt3m62XznV+TXbrFmznMeYwHj33XfbKc2xsbGOESNG2BCEc/PjH//Y0aZNG/szomnTpvb7tT7ccJ49F3D4fnaNH/zgB44WLVrY7+eWLVva+zt27PCZ8xxi/uOZWhEAAIBnMAYHAAAEHAIOAAAIOAQcAAAQcAg4AAAg4BBwAABAwCHgAACAgEPAAQAAAYeAAwAAAg4BBwAABBwCDgAACDgEHAAAEHAIOAAAQIHm/wNAZrfj+FCKLQAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "t,sx=dynamicspttest.expectations(op.sigma('x'),real=True)\n", + "t2,sx2=dynamicspttestswitch.expectations(op.sigma('x'),real=True)\n", + "\n", + "fig,ax=plt.subplots(1)\n", + "#ax.plot(t,sx,'o')\n", + "ax.plot(t2,sx2)\n", + "#ax2=ax.twinx()\n", + "#ax2.plot(t,alpha_tramp)" + ] + }, + { + "cell_type": "code", + "execution_count": 44, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> TEMPO computation:\n", + "100.0% 250 of 250 [########################################] 00:04:42\n", + "Elapsed time: 282.6s\n" + ] + } + ], + "source": [ + "\n", + "temporesnoramp=oqupy.tempo_compute(system=system,bath=bath,\n", + " initial_state=rhoini,\n", + " start_time=0,\n", + " end_time=50,\n", + " parameters=parameters,\n", + " alpha_t=np.ones(num_steps))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 45, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> TEMPO computation:\n", + "100.0% 250 of 250 [########################################] 00:03:03\n", + "Elapsed time: 183.3s\n" + ] + } + ], + "source": [ + "\n", + "\n", + "temporesramp=oqupy.tempo_compute(system=system,\n", + " bath=bath,\n", + " initial_state=rhoini,\n", + " start_time=0,\n", + " end_time=50,\n", + " alpha_t=alpha_tramp,\n", + " parameters=parameters)" + ] + }, + { + "cell_type": "code", + "execution_count": 47, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "" + ] + }, + "execution_count": 47, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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Sf2gTC4i4xkwYEDZbalrk2CrcePG+P7779UEI3vGYUEDCAwMhJOT01WzIOR+aGioId6C9NCdW553w5BFSZcvX47169erwuvy51mGvjMyMirsz+93/Uh2qnnz5ujcubOaqSkTNj788EOeZwOR4SiZSBQbGwtnZ2d1keBVJr7Ibcls8/tsHJLdbtmyJY4fP27332cGVwb6x1L+oVy7dm2F4RW5L+l/Mo6mTZuq/wOXP+9ZWVlq1iDPe+3JXAEJrGR4at26deq8liffbRcXlwrnWVo1SG0Fz/O1k38rCgoKeJ4NpHfv3mroVbKDukuXLl1UPZDuNr/PxnHp0iXEx8er1jh2/++GuSvqbcXixYvVLLWvv/5aExcXp5k4caLG399fk5KSYu5Ds/oZP7t371YXiQP+7//+T90+ffq0evzNN99U5/mXX37R7Nu3TzN48GBN06ZNNXl5eeY+dKsxadIkjZ+fn+bPP//UJCcnl11yc3PL9nnkkUfUivLr1q3T7NixQ9OzZ091obqZPn26moV58uRJ9X2V+w4ODprff/+d59mIys8WFPw+G8a0adPUvxvyfd60aZOmT58+msDAQDXj2N7PM4MrA/roo4/UF8nV1VW1ZtiyZYshX94urV+/XgVVlS8PPPBAWTuGl156SRMSEqKC2969e2uOHDli7sO2KvrOr1zmz59fto8Eq48++qhqG+Dp6akZOnSoCsCobh588EFN48aN1b8RQUFB6vuqC6x4nk0XXPH7bBgjRozQNGrUSH2fw8PD1f3jx4/zPGs0Ggf5HyNlCImIiIjsDmuuiIiIiAyIwRURERGRATG4IiIiIjIgBldEREREBsTgioiIiMiAGFwRERERGRCDKyIiIiIDYnBFREREZEAMroiIiIgMiMEVERERkQExuCIiIiKC4fw/OPouilH5xREAAAAASUVORK5CYII=", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "t,sx=temporesnoramp.expectations(op.sigma('x'))\n", + "t2,sx2=temporesramp.expectations(op.sigma('x'))\n", + "poldp=spi.quad(lambda x: correlations.spectral_density(x)/(4.0*(x**2+1.0)),0,30)[0] # heat transferred in polaron\n", + "polpred=-np.exp(-2*poldp)\n", + "\n", + "fig,ax=plt.subplots(1)\n", + "ax.plot(t,sx,'o',label='Constant coupling')\n", + "ax.plot(t2,sx2,label='Ramp')\n", + "ax.legend()\n", + "ax.axhline(polpred) \n", + "ax.set_ylim(-1,-0.9)\n", + "ax2=ax.twinx()\n", + "ax2.set_ylim(0,1)\n", + "ax2.plot(t,alpha_tramp,label='Coupling function')\n", + "ax2.legend()" + ] + }, + { + "cell_type": "code", + "execution_count": 48, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> TEMPO computation:\n", + "100.0% 250 of 250 [########################################] 00:04:44\n", + "Elapsed time: 284.1s\n" + ] + } + ], + "source": [ + "\n", + "temporesheatnoramp=oqupy.tempo_compute(system=system,bath=bathcf,\n", + " initial_state=rhoini,\n", + " start_time=0,\n", + " end_time=50,\n", + " parameters=parameters,\n", + " alpha_t=np.ones(num_steps))\n" + ] + }, + { + "cell_type": "code", + "execution_count": 49, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> TEMPO computation:\n", + "100.0% 250 of 250 [########################################] 00:03:13\n", + "Elapsed time: 193.4s\n" + ] + } + ], + "source": [ + "\n", + "temporesheatramp=oqupy.tempo_compute(system=system,bath=bathcf,\n", + " initial_state=rhoini,\n", + " start_time=0,\n", + " end_time=50,\n", + " parameters=parameters,\n", + " alpha_t=alpha_tramp)" + ] + }, + { + "cell_type": "code", + "execution_count": 51, + "metadata": {}, + "outputs": [ + { + "data": { + "image/png": "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I7AAAICoR2ABAABRj8ACAEAE2WzHr7/+eo3NpdS0eF6imnyNcBBYAAC11r59+/TLX/5SHTt2VFJSkpvnx+b8sRmWa9oDDzygfv36KZqMHj26zEzT0XiM5Ymv6QMAACBc3/3ud5WXl6cXXnhBXbt2dbMo24zI+/fv56QGYTNT21IbUcICADiezYubl10zSwXn5D148KA++ugj/e53v9P555+vTp06adCgQZo0aZKuvPLKMlUwTz75pK644go1bNhQp59+uhYvXqyNGze62ZdTUlI0bNgwbdq0qczrP/HEE27W5sTERJ122mn6y1/+UuZxm+34qquuUqNGjdzEfddcc40LTP5qkwcffFCfffaZe39bbJtfRkaGrr76anc83bt31xtvvHHCz/qnP/3J7WcTB7Zq1Urf+9733PZ58+a56pnCwkJ3f/Xq1e69Jk6cWPLcn/70p/rRj350XHXOiY7Rzu3Pf/5z9172nr1793bvFejtt99259I+/yWXXKJdu3apOlHCAgA4Xv4R6Tdta+bM3LtTSkw56W52obTF2oMMGTLEVQmV56GHHtIjjzzilnvuuUc/+MEPXImMhRurTvrJT36iW265Rf/617/c/q+99prGjx+v6dOna8SIEe5iPW7cOLVv396Fo6KiopKw8sEHH6igoEA333yzq3J5//333Xrt2rV666239M4777jXtFmJ/Swo/P73v9fDDz+sxx9/XD/84Q+1detWNW/e/LhjX758uW677TYXmCxYHThwwAU1c8455+jQoUNatWqVBgwY4I4lPT3dHYOfbbPPfKzyjtE+26WXXupe969//asLbV988YXi4uJKnnvkyBH94Q9/cMcUGxvrAtFdd92lF198UdWFwAIAqJXi4+NdicCNN96oWbNm6cwzz9Tw4cN17bXX6owzziizr4UNKwExdvEeOnSo7r//ftfexVg4sX387GJ8/fXX66abbnL3J0yYoCVLlrjtFlis2unzzz/X5s2b1aFDB7fP//3f/6lXr15atmyZBg4c6MKMHaO1qzmWvfaYMWPc7d/85jf64x//qKVLl7qSimNZSU5KSoorIWrcuLErSfrWt75VEjCsDYoFFAsstr7jjjtcIDp8+LAyMzNdSZKdl2NZ1VCwY/z3v//tjuXLL7/Uqaee6rZZuAuUn5/vzrmFGWNh71e/+pWqE4EFAHC8hIZe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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "\n", + "heats=temporesheatnoramp.states.trace(axis1=1,axis2=2).imag/u\n", + "heatsramp=temporesheatramp.states.trace(axis1=1,axis2=2).imag/u\n", + "\n", + "fig,ax=plt.subplots(1)\n", + "polht=spi.quad(lambda x: correlations.spectral_density(x)*x/(4.0*(x**2+1.0)),0,10)[0] # heat transferred in polaron\n", + "ax.plot(temporesheatnoramp._times,heats,label='Instant switch')\n", + "ax.plot(temporesheatramp._times,heatsramp,label='Smooth switch')\n", + "ax.axhline(polht)\n", + "#ax.axhline(2*polht)\n", + "ax.set_ylim(0,0.05)\n", + "ax.legend()\n", + "plt.show()\n", + "\n" + ] + }, + { + "cell_type": "code", + "execution_count": 28, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> PT-TEMPO computation:\n", + "100.0% 250 of 250 [########################################] 00:00:09\n", + "Elapsed time: 9.1s\n" + ] + } + ], + "source": [ + "pttempotestswitch=oqupy.pt_tempo_compute(bath=bath,\n", + " start_time=0,\n", + " end_time=50,\n", + " parameters=parameters,\n", + " alpha_t=alpha_tramp)" + ] + }, + { + "cell_type": "code", + "execution_count": 29, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "--> Compute dynamics:\n", + "100.0% 250 of 250 [########################################] 00:00:00\n", + "Elapsed time: 0.1s\n" + ] + } + ], + "source": [ + "dynamicspttestswitch=oqupy.compute_dynamics(\n", + " process_tensor=pttempotestswitch, \n", + " system=system,\n", + " initial_state=rhoini,\n", + " start_time=0)" + ] + }, + { + "cell_type": "code", + "execution_count": 31, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 31, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "t,sx2=dynamicspttestswitch.expectations(op.sigma('x'),real=True)\n", + "\n", + "fig,ax=plt.subplots(1)\n", + "ax.plot(t,sx2)\n" + ] + }, + { + "cell_type": "code", + "execution_count": 129, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "-1.0677375185866498e-07" + ] + }, + "execution_count": 129, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "dynamicspttestswitch.states[-1].trace().imag/u" + ] + }, + { + "cell_type": "code", + "execution_count": 130, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "[]" + ] + }, + "execution_count": 130, + "metadata": {}, + "output_type": "execute_result" + }, + { + "data": { + "image/png": "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", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.plot(pttempoheats)" + ] + } + ], + "metadata": { + "kernelspec": { + "display_name": ".venv", + "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.14.3" + } + }, + "nbformat": 4, + "nbformat_minor": 2 +} diff --git a/plandcalc.py b/plandcalc.py new file mode 100644 index 00000000..b93f534d --- /dev/null +++ b/plandcalc.py @@ -0,0 +1,312 @@ +# %% +import oqupy +import oqupy.operators as op +import scipy.integrate as spi +import numpy as np + +from oqupy.tti_tempo import TTITempo +import matplotlib.pyplot as plt + +from scipy.integrate import solve_ivp +from scipy.interpolate import interp1d +from scipy.optimize import minimize,Bounds + +pt_parameters = {'epsrel':10**(-7), + 'alpha':0.1, + 'omega_cutoff':1, + 'temp':0.131, + 'dt':0.2} #0.25 + +omega_cutoff = pt_parameters['omega_cutoff'] +alpha = pt_parameters['alpha'] +temperature = pt_parameters['temp'] +epsrel = pt_parameters['epsrel'] +dt=pt_parameters['dt'] + +# spectral density (without cutoff) +def j(w): + return 2*alpha*w + +# %% + +correlations = oqupy.PowerLawSD(alpha=alpha, + zeta=1, + cutoff=omega_cutoff, + cutoff_type='exponential', + temperature=temperature) +bath = oqupy.Bath(op.sigma("z")/2.0, correlations) +parameters=oqupy.TempoParameters(dt=dt,epsrel=epsrel,dkmax=500) + +# %% +u=0.01 +correlationscf=oqupy.counting_bath_correlations.CustomCountingSD_analytical(j_function=j,cutoff=omega_cutoff,u=u, + cutoff_type='exponential',temperature=temperature) + +bathcf = oqupy.Bath(op.sigma("z")/2.0, correlationscf) + +# %% +# Demonstration of TTI-TEMPO with heat markerss +# Calculates the heat absorption by a qubit, initially in equilibrium with the bath at splitting inisplit, +# as that splitting is reduced to zero over a time t_prot + +pt_var=TTITempo(bath,start_time=0.0,parameters=parameters) +process_tensor_var = pt_var.get_process_tensor() + +pt_varcf=TTITempo(bathcf,start_time=0.0,parameters=parameters) + +process_tensor_varcf = pt_varcf.get_process_tensor() + +# %% +# set up a linear ramp starting in thermal equilibrium at splitting inisplit +inisplit=1.0 +# choose initial state to be thermal equilibrium given hamiltonian inisplit*(sigmax/2) +z=2*np.cosh(inisplit/(2*temperature)) +pupx=np.exp(-inisplit/(2*temperature))/z +pdnx=np.exp(+inisplit/(2*temperature))/z + +rhoini=oqupy.operators.spin_dm('x+')*pupx+oqupy.operators.spin_dm('x-')*pdnx + +for t_prot in [300]: + + fig,axs=plt.subplots(3) + + num_steps=int(t_prot/dt) + + def hx(t): + return inisplit*(1-t/t_prot) + + def hamiltonian_t(t): + return op.sigma('x')*hx(t)/2 + + system = oqupy.TimeDependentSystem(hamiltonian_t) + + # compute dynamics + + dynamics=oqupy.compute_dynamics( + process_tensor=[process_tensor_var], + system=system, + initial_state=rhoini, + start_time=0, + num_steps=num_steps) + t, s_x = dynamics.expectations(op.sigma('x'), real=True) + + # compute heats + + dynamicscf = oqupy.compute_dynamics( + process_tensor=[process_tensor_varcf], + system=system, + initial_state=rhoini, + start_time=0, + num_steps=num_steps) + + heats=dynamicscf.states.trace(axis1=1,axis2=2).imag/u + + axs[0].plot(t,heats,label=t_prot) + axs[0].set_xlabel(r'$t$') + axs[0].set_ylabel(r'$\langle Q \rangle$') + axs[1].plot(t,s_x) + axs[1].set_xlabel(r'$t$') + axs[1].set_ylabel(r'$\langle \sigma_x \rangle$') + axs[2].plot(t,[hx(tme) for tme in t]) + plt.legend() + plt.show() + + +# %% +def vneumannentropy(rho): + probs=np.linalg.eigvalsh(rho) + return -np.sum(probs*(np.log(probs))) + +# %% +# landauer limit +ll=temperature*(vneumannentropy(dynamics.states[-1])-vneumannentropy(rhoini)) +print('Landauer limit ',ll) +print('Achieved Q ',-heats[-1]) +print('Percentage of Landauer achieved ',-100*heats[-1]/ll) +# dynamics using a switched coupling using a PT +# with a constant Hamiltonian +# in comparison to a constant coupling +# %% +tf=50 +num_steps=int(tf/dt) +inisplit=1.0 +# choose initial state to be thermal equilibrium given hamiltonian inisplit*(sigmax/2) +if (temperature>0): + z=2*np.cosh(inisplit/(2*temperature)) + pupx=np.exp(-inisplit/(2*temperature))/z + pdnx=np.exp(+inisplit/(2*temperature))/z +else: + pupx=0 + pdnx=1 + +# time-dependent system-environment coupling +# compute the dynamics of a qubit with constant splitting, +# for (i)time-independent system-environment coupling, and (ii)a smooth switch on +# of the system-environment coupling + +rhoini=oqupy.operators.spin_dm('x+')*pupx+oqupy.operators.spin_dm('x-')*pdnx + +system=oqupy.System(inisplit*op.sigma('x')/2) + +# %% +# smooth switching function +lamconst=2 +def smswitch(t): + if t<=tf: + return (0.1+0.9*(t**lamconst/(t**(lamconst)+(tf-t)**(lamconst)))) + else: + return 1.0 +smv=np.vectorize(smswitch) +alpha_tramp=smv(np.arange(num_steps)*dt) + +# %% +pttempotest=oqupy.pt_tempo_compute(bath=bath, + start_time=0, + end_time=50, + parameters=parameters, + alpha_t=np.ones(num_steps)) +pttempotestswitch=oqupy.pt_tempo_compute(bath=bath, + start_time=0, + end_time=50, + parameters=parameters, + alpha_t=alpha_tramp) + +dynamicspttest=oqupy.compute_dynamics( + process_tensor=pttempotest, + system=system, + initial_state=rhoini, + start_time=0) + +dynamicspttestswitch=oqupy.compute_dynamics( + process_tensor=pttempotestswitch, + system=system, + initial_state=rhoini, + start_time=0) + +t,sx=dynamicspttest.expectations(op.sigma('x'),real=True) +t2,sx2=dynamicspttestswitch.expectations(op.sigma('x'),real=True) + +poldp=spi.quad(lambda x: correlations.spectral_density(x)/(4.0*(x+inisplit)**2),0,30)[0] +polpred=-np.exp(-2*poldp) + +fig,ax=plt.subplots(1) +ax.plot(t,sx,'o',label='Constant coupling') +ax.plot(t2,sx2,label='Smooth switch') +ax.axhline(polpred,label='Polaron result') +ax.legend() +plt.show() + +# %% +# Comparison of the heat transfers at the final time +# in the two cases above + +pttempotestheat=oqupy.pt_tempo_compute(bath=bathcf, + start_time=0, + end_time=tf, + parameters=parameters, + alpha_t=np.ones(num_steps)) + +pttempotestheatswitch=oqupy.pt_tempo_compute(bath=bathcf, + start_time=0, + end_time=tf, + parameters=parameters, + alpha_t=alpha_tramp) + +heatdynamicspttest=oqupy.compute_dynamics( + process_tensor=pttempotestheat, + system=system, + initial_state=rhoini, + start_time=0) + +heatdynamicspttestswitch=oqupy.compute_dynamics( + process_tensor=pttempotestheatswitch, + system=system, + initial_state=rhoini, + start_time=0) +# %% +finalheatnoswit=heatdynamicspttest._states[-1].trace().imag/u +finalheatswit=heatdynamicspttestswitch._states[-1].trace().imag/u + +polht=spi.quad(lambda x: correlations.spectral_density(x)*x/(4.0*(x+1.0)**2),0,30)[0] + +print("Final heats: constant coupling = ", finalheatnoswit, " smooth switch = ", finalheatswit) +print("Polaron = ",polht) + +# %% +# Tempo version of the dynamics with the constant/smooth switch couplings +# Should produce the same results as above but much slower +runtempo=False +if runtempo: + temporesnoramp=oqupy.tempo_compute(system=system,bath=bath, + initial_state=rhoini, + start_time=0, + end_time=50, + parameters=parameters, + alpha_t=np.ones(num_steps)) + + # %% + + temporesramp=oqupy.tempo_compute(system=system, + bath=bath, + initial_state=rhoini, + start_time=0, + end_time=50, + alpha_t=alpha_tramp, + parameters=parameters) + + # %% + t,sx=temporesnoramp.expectations(op.sigma('x')) + t2,sx2=temporesramp.expectations(op.sigma('x')) + + fig,ax=plt.subplots(1) + ax.plot(t,sx,'o',label='Constant coupling') + ax.plot(t2,sx2,label='Ramp') + ax.legend() + ax.set_ylim(-1,-0.9) + ax2=ax.twinx() + ax2.set_ylim(0,1) + #ax2.plot(t,alpha_tramp,label='Coupling function') + ax2.legend() + + plt.show() + +# %% +# tempo version of the heats with the constant/smooth switch +# this allows the heat to be computed at any time, not just the final one + +runtempoheats=False +if runtempoheats: + temporesheatnoramp=oqupy.tempo_compute(system=system,bath=bathcf, + initial_state=rhoini, + start_time=0, + end_time=tf, + parameters=parameters, + alpha_t=np.ones(num_steps)) + + # %% + + temporesheatramp=oqupy.tempo_compute(system=system,bath=bathcf, + initial_state=rhoini, + start_time=0, + end_time=tf, + parameters=parameters, + alpha_t=alpha_tramp) + + # %% + + heats=temporesheatnoramp.states.trace(axis1=1,axis2=2).imag/u + heatsramp=temporesheatramp.states.trace(axis1=1,axis2=2).imag/u + + fig,ax=plt.subplots(1) + polht=spi.quad(lambda x: correlations.spectral_density(x)*x/(4.0*(x+1.0)**2),0,30)[0] # heat transferred in polaron + ax.plot(temporesheatnoramp._times,heats,label='Instant switch') + ax.plot(temporesheatramp._times,heatsramp,label='Smooth switch') + ax.axhline(polht) + #ax.axhline(2*polht) + ax.set_ylim(0,0.05) + ax.legend() + plt.show() + + + +# %% diff --git a/pttimedependencedegeneracy.py b/pttimedependencedegeneracy.py new file mode 100644 index 00000000..de70f729 --- /dev/null +++ b/pttimedependencedegeneracy.py @@ -0,0 +1,164 @@ +import numpy as np +import matplotlib.pyplot as plt +import oqupy +from oqupy import process_tensor + +# ----------------------------------------------------------------------------- +# -- Test C: Collective Ising Chain with different bath coupling operator + +testtempo=True +testpttempo=True + +# Initial state: +initial_state_C = np.array([[1.0,0.0,0.0], + [0.0,0.0,0.0], + [0.0,0.0,0.0]]) + +# System operator +j_value = -1.0 +h = 1.0 +s_z = np.array([[1.0,0.0,0.0], + [0.0,0.0,0.0], + [0.0,0.0,-1.0]]) +s_x = np.array([[0.0,1.0,0.0], + [1.0,0.0,1.0], + [0.0,1.0,0.0]]) +h_sys_C = (j_value/2) * s_z @ s_z + h * s_x + +# Ohmic spectral density with exponential cutoff +coupling_operator_C = np.diag([1,1,2]) +alpha_C = 0.3 +cutoff_C = 5.0 +temperature_C = 0.2 + +# end time +t_end_C = 5.0 +dt=0.05 + +numsteps=int(t_end_C/dt) +times=np.arange(numsteps)*dt +lamconst=2 +def smswitch(t): + if t<=t_end_C: + return (0.1+0.9*(t**lamconst/(t**(lamconst)+(t_end_C-t)**(lamconst)))) + else: + return 1.0 +smv=np.vectorize(smswitch) +alpharamp=smv(times) +#alpharamp=np.ones(len(times)) + +correlations_C = oqupy.PowerLawSD(alpha=alpha_C, + zeta=1.0, + cutoff=cutoff_C, + cutoff_type="exponential", + temperature=temperature_C, + name="ohmic") +bath_C = oqupy.Bath(coupling_operator_C, + correlations_C, + name="bath with north degeneracies") +system_C = oqupy.System(h_sys_C) + +tempo_params_C = oqupy.TempoParameters( + dt=0.05, + tcut=None, + epsrel=10**(-7)) + + +if testtempo: + + tempo_unique = oqupy.Tempo( + system_C, + bath_C, + tempo_params_C, + initial_state_C, + start_time=0.0, + unique=True, + alpha_t=alpharamp) + + tempo_non_unique = oqupy.Tempo( + system_C, + bath_C, + tempo_params_C, + initial_state_C, + start_time=0.0, + unique=False, + alpha_t=alpharamp) + + tempo_unique.compute(end_time=t_end_C) + tempo_non_unique.compute(end_time=t_end_C) + dyn_unique = tempo_unique.get_dynamics() + dyn_non_unique = tempo_non_unique.get_dynamics() + + t,usz=dyn_unique.expectations(s_z,real=True) + t,nusz=dyn_non_unique.expectations(s_z,real=True) + t,usx=dyn_unique.expectations(s_x,real=True) + t,nusx=dyn_non_unique.expectations(s_x,real=True) + + fig,ax=plt.subplots(1) + ax.plot(t,usz,label='sz, Unique') + ax.plot(t,nusz,'o',label='sz, Non-unique') + + ax.plot(t,usx,label='sx, Unique') + ax.plot(t,nusx,'x',label='sx, Non-unique') + + ax.legend() + plt.show() + +if testpttempo: + pttempo_unique = oqupy.PtTempo( + bath_C, + parameters=tempo_params_C, + start_time=0.0, + end_time=t_end_C, + unique=True, + alpha_t=alpharamp) + pttempo_non_unique = oqupy.PtTempo( + bath_C, + parameters=tempo_params_C, + start_time=0.0, + end_time=t_end_C, + unique=False, + alpha_t=alpharamp) + + + pttempo_unique.compute() + pttempo_non_unique.compute() + + + pttuni=pttempo_unique.get_process_tensor() + pttnuni=pttempo_non_unique.get_process_tensor() + + + + dynuni=oqupy.compute_dynamics( + process_tensor=pttuni, + system=system_C, + initial_state=initial_state_C, + start_time=0) + + dynnuni=oqupy.compute_dynamics( + process_tensor=pttnuni, + system=system_C, + initial_state=initial_state_C, + start_time=0) + + + + t,usz=dynuni.expectations(s_z,real=True) + t,nusz=dynnuni.expectations(s_z,real=True) + + t,usx=dynuni.expectations(s_x,real=True) + t,nusx=dynnuni.expectations(s_x,real=True) + + + fig,ax=plt.subplots(1) + ax.plot(t,usz,label='sz, Unique') + ax.plot(t,nusz,'o',label='sz, Non-unique') + + ax.plot(t,usx,label='sx, Unique') + ax.plot(t,nusx,'x',label='sx, Non-unique') + + ax.legend() + plt.show() + + diff --git a/pylintrc b/pylintrc index 2a2ec1ee..2c5ce4ae 100644 --- a/pylintrc +++ b/pylintrc @@ -1,5 +1,4 @@ [MASTER] - # A comma-separated list of package or module names from where C extensions may # be loaded. Extensions are loading into the active Python interpreter and may # run arbitrary code @@ -11,7 +10,7 @@ ignore=CVS # Add files or directories matching the regex patterns to the blacklist. The # regex matches against base names, not paths. -ignore-patterns= +ignore-patterns=iTEBD_TEMPO_fromlink.py,iTEBD_TEMPO_useoqupybath.py # Python code to execute, usually for sys.path manipulation such as # pygtk.require(). @@ -32,7 +31,7 @@ persistent=yes # When enabled, pylint would attempt to guess common misconfiguration and emit # user-friendly hints instead of false-positive error messages -suggestion-mode=yes +# suggestion-mode=yes # Allow loading of arbitrary C extensions. Extensions are imported into the # active Python interpreter and may run arbitrary code. @@ -80,7 +79,8 @@ disable=raw-checker-failed, too-many-arguments, # piperfw: added for development too-many-positional-arguments, # piperfw: added 2024-09-27 possibly-used-before-assignment, # GEFux: added by hand - unnecessary-lambda-assignment # GEFux: added by hand + unnecessary-lambda-assignment, # GEFux: added by hand + invalid-name # GEFux: added by hand # Enable the message, report, category or checker with the given id(s). You can # either give multiple identifier separated by comma (,) or put this option diff --git a/requirements.txt b/requirements.txt index fc7aca66..d3e0bbdd 100644 --- a/requirements.txt +++ b/requirements.txt @@ -4,4 +4,3 @@ tensornetwork==0.4.3 matplotlib>=3.0.0 h5py>=3.1.0 numdifftools>=0.9.41 - diff --git a/requirements_ci.txt b/requirements_ci.txt index 5d73b0a0..b00336be 100644 --- a/requirements_ci.txt +++ b/requirements_ci.txt @@ -1,10 +1,10 @@ pytest>=8.1.0 pytest-cov -pylint>=3.1.0 +pylint>=4.0.0 sphinx sphinx_rtd_theme ipython -setuptools +setuptools>=81.0 wheel docutils==0.16 numpy>=1.18,<2.0 diff --git a/setup.py b/setup.py index 708236b6..71ef536e 100644 --- a/setup.py +++ b/setup.py @@ -18,7 +18,6 @@ from setuptools import find_packages from setuptools import setup -import pkg_resources here = os.path.abspath(os.path.dirname(__file__)) sys.path.insert(0, here) diff --git a/tests/coverage/pt_tebd_test.py b/tests/coverage/pt_tebd_test.py index e05901ca..25389ead 100644 --- a/tests/coverage/pt_tebd_test.py +++ b/tests/coverage/pt_tebd_test.py @@ -18,12 +18,14 @@ import numpy as np import oqupy -up_dm = oqupy.operators.spin_dm("z+") -system_chain = oqupy.SystemChain(hilbert_space_dimensions=[2,3]) -initial_augmented_mps = oqupy.AugmentedMPS([up_dm, np.diag([1,0,0])]) -pt_tebd_params = oqupy.PtTebdParameters(dt=0.2, order=2, epsrel=1.0e-4) -def test_get_augmented_mps(): + +def test_get_augmented_mps_A(): + up_dm = oqupy.operators.spin_dm("z+") + system_chain = oqupy.SystemChain(hilbert_space_dimensions=[2,3]) + initial_augmented_mps = oqupy.AugmentedMPS([up_dm, np.diag([1,0,0])]) + pt_tebd_params = oqupy.PtTebdParameters(dt=0.2, order=2, epsrel=1.0e-4) + pt_tebd = oqupy.PtTebd( initial_augmented_mps=initial_augmented_mps, system_chain=system_chain, @@ -38,3 +40,73 @@ def test_get_augmented_mps(): augmented_mps = pt_tebd.get_augmented_mps() assert augmented_mps.gammas[0].shape == (1,4,1,1) assert augmented_mps.gammas[1].shape == (1,9,1,1) + + +def test_get_augmented_mps_B(): + + dt = 0.2 + epsrel = 1.0e-4 + num_steps = 4 + + + sx = 0.5 * oqupy.operators.sigma("x") + sy = 0.5 * oqupy.operators.sigma("y") + sz = 0.5 * oqupy.operators.sigma("z") + up_dm = oqupy.operators.spin_dm("z+") + down_dm = oqupy.operators.spin_dm("z-") + mixed_dm = oqupy.operators.spin_dm("mixed") + + #System + N = 3 # >=3 + epsilon = 1 + J_gamma = [1.3, 0.7, 1.2] + system_chain = oqupy.SystemChain([2]*N) + + for n in range(N): + system_chain.add_site_hamiltonian(site = n, hamiltonian= epsilon*sz) + + for n in range(N-1): + for J, S in zip (J_gamma ,[sx,sy,sz]): + system_chain.add_nn_hamiltonian(site = n, + hamiltonian_l = J*S, + hamiltonian_r = S) + + #parameters + pt_tebd_params = oqupy.PtTebdParameters(dt = dt, + order = 2, + epsrel = epsrel) + + dynamics_sites = list(range(0, N)) + initial_augmented_mps = oqupy.AugmentedMPS([up_dm]*N) + + + correlations = oqupy.PowerLawSD(alpha=0.05, + zeta=1, + cutoff=1.0, + cutoff_type='exponential', + temperature=0.0) + bath = oqupy.Bath(0.5 * sy, correlations) + pt_tempo_parameters = oqupy.TempoParameters(dt=dt, + epsrel=1.0e-4, + dkmax=10) + + pt = oqupy.pt_tempo_compute(bath=bath, + start_time=0.0, + end_time=num_steps * dt, + parameters=pt_tempo_parameters, + progress_type='bar') + + + pt_tebd = oqupy.PtTebd(initial_augmented_mps = initial_augmented_mps, + system_chain = system_chain, + process_tensors = [None]+[pt]+[None]*(N-2), + parameters = pt_tebd_params, + dynamics_sites = dynamics_sites, + chain_control=None + ) + + end_step = 2 + pt_tebd.compute(end_step = 2, progress_type = 'bar') + + new_augmented_mps = pt_tebd.get_augmented_mps() + assert new_augmented_mps.gammas[1].shape[2] == pt.get_bond_dimensions()[end_step] diff --git a/timedependenceptbug.py b/timedependenceptbug.py new file mode 100644 index 00000000..516c9d30 --- /dev/null +++ b/timedependenceptbug.py @@ -0,0 +1,131 @@ +# %% +import oqupy +import oqupy.operators as op +import scipy.integrate as spi +import numpy as np +from oqupy.iTEBD_TEMPO_useoqupybath import iTEBD_TEMPO_oqupy +from oqupy.process_tensor import TTInvariantProcessTensor +from oqupy.tti_tempo import TTITempo +from oqupy.tti_tempo import TTITempoCounting +import matplotlib.pyplot as plt + + +from scipy.integrate import solve_ivp +from scipy.interpolate import interp1d +from scipy.optimize import minimize,Bounds + +pt_parameters = {'epsrel':10**(-7), + 'alpha':0.1, + 'omega_cutoff':1, + 'temp':0.131, + 'dt':0.2} #0.25 + +omega_cutoff = pt_parameters['omega_cutoff'] +alpha = pt_parameters['alpha'] +temperature = pt_parameters['temp'] +epsrel = pt_parameters['epsrel'] +# dt = 1./omega_cutoff/np.sqrt(3) +dt=pt_parameters['dt'] + +splitting=1.0 +rhoini=op.spin_dm('x-') +system=oqupy.System(splitting*op.sigma('x')/2) + +# spectral density (without cutoff) +def j(w): + return 2*alpha*w + + +# %% + +correlations = oqupy.PowerLawSD(alpha=alpha, + zeta=1, + cutoff=omega_cutoff, + cutoff_type='exponential', + temperature=temperature) +bath = oqupy.Bath(op.sigma("z")/2.0, correlations) +parameters=oqupy.TempoParameters(dt=dt,epsrel=epsrel) + +# %% +# smooth switching function +lamconst=2 +tf=10 +numsteps=int(tf/dt) +times=np.arange(numsteps)*dt +def smswitch(t): + if t<=tf: + return (0.1+1.3*(t**lamconst/(t**(lamconst)+(tf-t)**(lamconst)))) + else: + return 1.0 +smv=np.vectorize(smswitch) +alpharamp=smv(times) + +# %% +# alpharamp=0.3*np.ones(len(times)) + +pttempotestswitch=oqupy.pt_tempo_compute(bath=bath, + start_time=0, + end_time=tf, + parameters=parameters, + alpha_t=alpharamp) + +pttempostandard=oqupy.pt_tempo_compute(bath=bath, + start_time=0, + end_time=tf, + parameters=parameters) + +# %% + +dynamicspttestswitch=oqupy.compute_dynamics( + process_tensor=pttempotestswitch, + system=system, + initial_state=rhoini, + start_time=0) + +dynamicsstandard=oqupy.compute_dynamics( + process_tensor=pttempostandard, + system=system, + initial_state=rhoini, + start_time=0) + + +# %% + +states=dynamicspttestswitch.states +rescale=False +if rescale: + states=states/(states[0].trace()) +dynamicspttestswitch._states=states + +t1,sx1=dynamicsstandard.expectations(op.sigma('x'),real=True) +t2,sx2=dynamicspttestswitch.expectations(op.sigma('x'),real=True) +#t3,sx3=dynamicspttestswitch2.expectations(op.sigma('x'),real=True) + +# %% +runtempo=True +if runtempo: + tempores=oqupy.tempo_compute(system=system, + bath=bath, + initial_state=rhoini, + start_time=0.0, + end_time=tf, + alpha_t=alpharamp, + parameters=parameters) + + t3,sx3=tempores.expectations(op.sigma('x'),real=True) +#%% +fig,ax=plt.subplots(1) +#ax.plot(t,sx,'o') +ax.plot(t1,sx1,label='PT-TEMPO (standard)') +ax.plot(t2,sx2,label='PT-TEMPO (smooth switch)') +if runtempo: + ax.plot(t3,sx3,label='TEMPO (smooth switch)') +#ax2=ax.twinx() +#ax2.plot(t,alpha_tramp) +ax.set_ylim(-1,-0.9) +ax.legend() +plt.show() + + + +# %% diff --git a/tutorials/pt_gradient.ipynb b/tutorials/pt_gradient.ipynb index 3d9a3d19..a34d4122 100644 --- a/tutorials/pt_gradient.ipynb +++ b/tutorials/pt_gradient.ipynb @@ -405,7 +405,7 @@ ], "metadata": { "kernelspec": { - "display_name": "Python 3 (ipykernel)", + "display_name": ".venv", "language": "python", "name": "python3" }, @@ -419,7 +419,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.14" + "version": "3.11.5" } }, "nbformat": 4, diff --git a/tutorials/pt_tempo.ipynb b/tutorials/pt_tempo.ipynb index e742c89d..97e5dcaf 100644 --- a/tutorials/pt_tempo.ipynb +++ b/tutorials/pt_tempo.ipynb @@ -187,7 +187,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 6, @@ -196,7 +196,7 @@ }, { "data": { - "image/png": "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", + "image/png": "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", "text/plain": [ "
" ] @@ -269,8 +269,8 @@ "output_type": "stream", "text": [ "--> TEMPO computation:\n", - "100.0% 50 of 50 [########################################] 00:00:00\n", - "Elapsed time: 0.7s\n" + "100.0% 50 of 50 [########################################] 00:00:02\n", + "Elapsed time: 2.7s\n" ] } ], @@ -300,7 +300,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 9, @@ -309,7 +309,7 @@ }, { "data": { - "image/png": "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azR9+nSjSzG1iooKpaen66233tIll1xidDmm169fPz300EO64YYbQvq8tOgYoLq6Wv369TO6DOCU3G63Nm/erLy8vMAxq9WqvLw8FRUVGVgZ0HPV1dWSxPtxL/N4PFq9erVcLpchWzSF1crI0WDXrl1asmSJfve73xldCnBKlZWV8ng8gdXJ/TIyMrRjxw6DqgJ6zuv16vbbb9eFF14YFqvpm9HWrVuVm5urxsZGJSQkaM2aNRo+fHjI66BFp5vmzZsni8Vy0tvXPwj279+vqVOn6uqrr9aNN95oUOWRpzuvNQCczM0336xt27Zp9erVRpdiWmeffbaKi4v1/vvv66abbtKsWbO0ffv2kNdBi043/e///q/+67/+66TnnH766YGvDxw4oEmTJmnixIlsOtpFXX2tETxpaWmy2WwqKytrc7ysrEyZmZkGVQX0zM9//nO98sorevvttzV48GCjyzEtu92uM888U5I0duxYffDBB/r973+vJ554IqR1EHS6qX///urfv3+nzt2/f78mTZqksWPH6umnn26zMSlOrSuvNYLLbrdr7NixKiwsDAyM9Xq9Kiws1M9//nNjiwO6yOfz6ZZbbtGaNWu0fv16DR061OiSoorX61VTU1PIn5eg08v279+vb33rWzrttNP0u9/9ThUVFYHv8T/i4CspKVFVVZVKSkrk8XhUXFwsSTrzzDOVkJBgbHERKj8/X7NmzdK4ceM0YcIELV68WC6XS7Nnzza6NFOpq6vTrl27Avf37Nmj4uJi9evXT0OGDDGwMvO4+eabtWrVKr300ktKTExUaWmpJCk5OVlxcXEGV2cu8+fP1+WXX64hQ4aotrZWq1at0vr16/Xaa6+FvhgfetXTTz/tk9ThDcE3a9asDl/rN9980+jSItqSJUt8Q4YM8dntdt+ECRN8GzZsMLok03nzzTc7/Lc7a9Yso0szjRO9Fz/99NNGl2Y6P/nJT3ynnXaaz263+/r37++79NJLff/6178MqYV1dAAAgGkxWAQAAJgWQQcAAJgWQQcAAJgWQQcAAJgWQQcAAJgWQQcAAJgWQQcAAJgWQQcAAJgWQQdAxJs7d66uuuqqDr/38ccf66qrrlJqaqqcTqfOO+88PfTQQ2ppaQlxlQCMQNABEPE2btyocePGtTv+9ttv64ILLlBcXJxeeuklffTRR7rrrrv0yCOP6KqrrpLX6zWgWgChxBYQACKW2+1Wnz592rTO5OTkaMOGDfJ4PBo2bJhyc3P13HPPtblux44dGjlypB5//HHdcMMNoS4bQAgRdABELK/Xq02bNiknJ0fFxcXKyMiQ0+lUSkqKioqKNHHiRBUXF2vUqFHtrv3+978vl8ulf/3rXwZUDiBU6LoCELGsVqsOHDig1NRUjRo1SpmZmUpJSZEk7dmzR5J01llndXjtWWedpS+//DJUpQIwCEEHQET78MMPO2yxSUpKkiRVVVV1eN3hw4cD5wAwL4IOgIh2oq6p3NxcxcbG6uWXX273PY/Ho9dee00XXXRRKEoEYCCCDoCItnXrVo0ePbrd8dTUVN1666369a9/rQMHDrT53qOPPqqqqirNnTs3RFUCMApBB0BE83q92rlzpw4cOKDq6urA8bq6Ot16663Kzs7WpEmTtGXLFknSQw89pLvvvltLliyR3W6Xx+MxqnQAIcCsKwAR7bnnntNdd92lAwcO6I477tBDDz0kSbrvvvt0//33B86bNWuWVq5cKYvF0ub6PXv2KDs7O5QlAwghgg4AADAtuq4AAIBpEXQAAIBpEXQAAIBpEXQAAIBpEXQAAIBpEXQAAIBpEXQAAIBpEXQAAIBpEXQAAIBpEXQAAIBpEXQAAIBpEXQAAIBp/T+575jgy7PwgQAAAABJRU5ErkJggg==", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjoAAAG2CAYAAAB20iz+AAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAObhJREFUeJzt3Xt8k/X9//9nkjZJS0/Q0pZDsXhAReQwDrV42JgVcI7J/M0xdcKHOT/Dj/NAP94UnILuIH7mVPYDFOdQnA7pNodOcThXRacWEbAKIigCFoGeKPSQHtIm+f5REqgt0EOaK7nyuN9uudFcva7k1UCTJ++jxefz+QQAAGBCVqMLAAAA6C0EHQAAYFoEHQAAYFoEHQAAYFoEHQAAYFoEHQAAYFoEHQAAYFoEHQAAYFoEHQAAYFoEHQAAYFphE3TefvttTZs2TQMHDpTFYtGLL754ymvWr1+vb3zjG3I4HDrzzDO1cuXKXq8TAABEjrAJOi6XS6NGjdKyZcs6df6ePXt0xRVXaNKkSSouLtbtt9+un/70p3rttdd6uVIAABApLOG4qafFYtGaNWs0ffr0E55z1113ae3atdq2bVvg2I9+9CMdOXJE69atC0GVAAAg3MUYXUB3FRUVKS8vr82xKVOm6Pbbbz/pdU1NTWpqagrc93q9qqqqUmpqqiwWS2+UCgAAgszn86m2tlYDBw6U1XriDqqIDTqlpaXKyMhocywjI0M1NTVqaGhQXFxch9ctWrRI999/fyhKBAAAvWzfvn0aPHjwCb8fsUGnu+bPn6/8/PzA/erqag0ZMkT79u1TUlKSgZUBAIDOqqmpUVZWlhITE096XsQGnczMTJWVlbU5VlZWpqSkpBO25kiSw+GQw+FodzwpKYmgAwBAhDnVsJOwmXXVVbm5uSosLGxz7PXXX1dubq5BFQEAgHATNkGnrq5OxcXFKi4ultQ6fby4uFglJSWSWrucZs6cGTh/zpw52r17t+68807t2LFDjz32mP7yl79o7ty5RpQPAADCUNgEnU2bNmnMmDEaM2aMJCk/P19jxozRggULJEkHDx4MhB5JGjp0qNauXavXX39do0aN0sMPP6w//vGPmjJliiH1AwCA8BOW6+iEUk1NjZKTk1VdXc0YHQAAIkRnP7/DpkUHAAAg2Ag6AADAtAg6AADAtAg6AADAtAg6AADAtAg6AADAtAg6AADAtAg6AADAtAg6AADAtAg6AADAtAg6AADAtAg6AADAtGKMLgBA9PD5fNp7qF72GKtS+9jljLUZXRIAkyPoAAiZ5zZ8qXtf+iRwP9ERo9QEu1ITHErz/9nHroxkp757/kAlx8caWC0AMyDoAAgJn8+np97dK0myWiSvT6ptalFtU4v2Hqpvd/5jb36hx677hkZlpYS2UACmQtABEBIb91RpT6VLfew2vf+LPHm8PlXWNelQnVuH6ppUWdekyjq3Drma9NZnFdpX1aCrlxfp3u+eqx9fcJosFovRPwKACETQARASBR/skyRNGzVQCY7Wt57kuFid0b/9uTWNzbrjLx/pX9vLdO9Ln2jTl4f1wPfPVx8Hb1kAuoZZVwB6XXVDs9ZuPShJ+tGEIac8P8kZqyeuH6tffOdc2awWvVR8QNOXvatd5bW9XSoAkyHoAOh1/yjer6YWr87JTNSowcmdusZisejGS07X8zdeoPREhz4vr9P3lr6rf3x0oJerBWAmBB0Avcrn8+n5ja3dVjPGZ3V5rM2Eof30yq0X6YLT+6ne7dGtz3+ohS9tU1OLpzfKBWAyBB0AvWrb/hptP1gje4xV3x8zqFuPkZ7o1HM35Oh/vnWGJOmZoi/1wyc2aP+RhmCWCsCECDoAetXqD0okSVPPy1RKvL3bjxNjs+rOqedoxaxxSnLG6KN9RzRtyTsq+uJQsEoFYEIEHQC9pt7don8Ut46p+dH4rKA85qXnZmjtrRdr+IAkVbnc+vGK9/XUO3vk8/mC8vgAzIWgA6DXvLq1VLVNLTotNV4XnJ4atMfN6hevF26aqOmjB8rj9emXr2xX/l8+UoObcTsA2iLoAOg1BUe7rX44LktWa3AX/Iuz2/TojNG697vDZbNatObD/frB8ve0r6r9KssAohdBB0Cv2FVeqw/2HpbNatEPxg7uleewWCy64aKhevaGCerXx65PDtToe0vf0bu7Knvl+QBEHoIOgF7hXwl50tnpykhy9upzTTwjTS/fcpHOH5Ssw/XNun7F+3ry7d2M2wFA0AEQfO4Wr17Ysl9S8AYhn8qglDj9dU6urvrGIHl90m9e/VS3ri5WvbslJM8PIDwRdAAE3b8/LVOVy62MJIe+dXYHm1n1EmesTQ9fPUr3f+88xVgtevmjA/rO7/+jjXuqQlYDgPBC0AEQdKuPdltdPTZLMbbQvs1YLBbNmpitP/80RwOSndp7qF4z/lCk+/7xCa07QBQi6AAIqq8O1+s/n1dIap1tZZSc01P12txLNGNclnw+aeV7e3X57/+j93ezwCAQTWKMLgCAufx101fy+aQLz0zVkNR4Q2tJcsbq/34wUt8ZOUDzXvhYXx6q14w/bNCs3NN059Rz1MfBWyAgSS0erxpbvGps9hy9tX7d1NL6dYPbo8aWY8e/fp7/ew3NHjUdd7zh6Hkv33KR4u3G/L7xWw4gaDxen/66yb+B5xCDqznmm8P667W5l2jRq5/q+Y379EzRl3pjZ7l++/+NUu4ZwVvIEAgWj9d3LEx0EEC+HjIa3B41fe28huO+bg0s/uDhPXb86PXNnt6dodjg9hB0AES+tz+v0IHqRqXEx2ry8Ayjy2kjyRmrRVeN1OUjBmj+37dqX1WDrnlyg66/4DTdOfVsJTpjjS4RYezEwaNtcDi+daPjlo8Tt4g0uEMXPE7GHmOVM8YqZ6xNcXabnDE2OWOtcsTaWo/Ftn7Pf9wZOKf1flzssa8dR89LcBoXNwg6AIKmYGNra85VYwbLGWszuJqOXTKsv9bdfrEe/OcO/fn9Ej274Uu9VLxfsy8cqtkXZvdo41EYp8XjlavJo9qmZtU1tcjV1NrKUe9uUUOzR/Xu1luDu6X1z6NBo8H99daPY60e/mNNzV65PV7Dfja7zdoaKI4LEMe+tgVCif94XKztaCixyhlzNKwc/doZa5PjuPOcsV/7Xow16KuYG83ii/IVtWpqapScnKzq6molJSUZXQ4QsSpqm5S7qFAtXp9eu/0SnZ2ZaHRJp/TurkoteGmbvqhwSZISHDG6Pvc03XDRUKUlOAyuLro0e7w6XO9WdX2zqhuO3WoamlXd0HLsfmOzahuPhZnaxhbVNTWrsTl0QeT4Fo82wSPGdrR1w9o+kMS0tm7EtQsrx5/z9RBjlSPGJpvJgkewdPbzmxYdAEHxUvF+tXh9GjMkJSJCjiRdeGaa/jX3m1q3rVRL3vhcO0pr9fj6L/T0u3t07YTT9LNvnt7rqzqblc/nU01Di8prG1Ve26Ty2kYdqnPrkMutqjq3qurdqnK13g7VNammMThT/+0xViU4YtTHYVN8bIzi7DbFH73F2WMUf7Q7Jt7eGjri7LbjAsjx3S4d3yd4RB6CDoCg+PRgrSTp0nPSDa6ka2xWi64YOUCXj8hU4Y5yLXnjc338VbWeenePntvwpX44frDmfPMMDe5r7AyycNLs8aq0ulEHjjToYHWjDlQ3qLymSWU1x0JNeU2Tmlq61spisUjJcbFKjotVkjP22Ndxx75OjotVojNGCc4YJTja3vo4YmSPYdUUtEXQARAU/l3Dh6T2MbiS7rFaLbpseIbyzk3X259Xaknh59r05WE9t6FEqzfu0yXD+ivv3Axdem7v791ltNrGZn11uEFfHW7Qvqr6QKDZf6RBB6sbVF7bpM4Oekh0xigjyan0RIdSExxK7WNXv6M3/9epCXb1jbcrJd5OawmCjqADIChK/EGnX2S3fFgsFn1zWH9dclaa3t9TpSVvfK53dx3SGzvK9caOcmmNNGpwsvLOzVDe8Aydk5koiyWyPpzr3S3af7hB+w7XB8LMV8fdP1LffMrHsNusykx2amCKUwOT45SR3Bpm0hOdykhq/TM9yRG2g9IRPQg6AHqssdmjstpGSZEfdPwsFosuOD1VF5yeqs/KavX69jL9+9MyFe87oo++qtZHX1Xr4dc/06CUOF02vLWlZ+SgFCXHGz9Nvd7dooPVjUdbZeq1r+ron4cbtP9wvSrr3Kd8jL7xsRrcN16D+8ZpUEqcBqTEaVCKUwOS4zQwJU6pfeymm50DcyLoAOix/Uca5PNJfew29Q2DD/pgG5aRqGEZibp50pkqr23UmzvK9fr2cr2zq0L7jzRo5Xt7tfK9vZKkfn3syk6NV3ZaH52e1kfZaX00NK2PslP79GglZo/Xp7rGFtU0ts4+qqht0sHqRpXWNKq0urVrqaymUQerG1XbiYG9ic4YDe4br6y+ccrq1xpoBveNV1a/1mDDukIwC4IOgB7zd1tl9YuPuG6crkpPdGrG+CGaMX6IGtwevburUv/+tExvfVahg9WNgZlEW0qOtLu2f6JDic4Y2W1WxdqsirVZFGuzyh5z7H6M1ap6d4tqj4aa2sYW1TQ0y+X2dKnOPnabBvWNU9bRVpm2YSZeyXEEGUQHgg6AHvvquKATTeLsNuUNbx2rI0muphbtPeTSnkqX9la6tKeyXnsq67T3UL2qXG5V1DaporapR8/pjLUq0Rmr/gkODUh2KiPZqQFJR/9MdiozyanMZCctMsBRBB0APWaWgcg91ccRo/MGJuu8gcntvldd36ySqnrVu1vU7PGp2dO62m5z4NZ6rLnFq3h7jBKdMUo6OpU60RmrpKN/Mn0a6BqCDoAeI+icWnJ8rM6Pbx+AAPQu/msAoMf2VTVIkrL6xRlcCQC0RdAB0CM+n+/YYoG06AAIMwQdAD1S3dCs2qbW6cxskwAg3BB0APSIf3xOeiKr4AIIPwQdAD3CQGQA4YygA6BH/AORCToAwhFBB0CP+Ft0BhN0AIQhgg6AHmHGFYBwRtAB0CP7Dh/d/qEva+gACD8EHQDd1uLxav/ho2N0UmnRARB+CDoAuu1gdaNavD7ZbVZlJDqNLgcA2iHoAOg2f7fV4L5xslotBlcDAO0RdAB0m38gchYDkQGEKYIOgG5jsUAA4Y6gA6Db2LUcQLgj6ADoNlp0AIQ7gg6AbvvqMGN0AIS3sAs6y5YtU3Z2tpxOp3JycrRx48aTnr948WKdffbZiouLU1ZWlubOnavGxsYQVQtEL1dTiyrr3JIIOgDCV1gFnYKCAuXn52vhwoXasmWLRo0apSlTpqi8vLzD81etWqV58+Zp4cKF+vTTT7VixQoVFBTo7rvvDnHlQPTxTy1PiY9VkjPW4GoAoGNhFXQeeeQR3XjjjZo9e7aGDx+u5cuXKz4+Xk899VSH57/33nu68MILde211yo7O1uTJ0/WNddcc8pWIAA9FxiI3JfWHADhK2yCjtvt1ubNm5WXlxc4ZrValZeXp6Kiog6vmThxojZv3hwINrt379arr76q73znOyd8nqamJtXU1LS5Aeg6BiIDiAQxRhfgV1lZKY/Ho4yMjDbHMzIytGPHjg6vufbaa1VZWamLLrpIPp9PLS0tmjNnzkm7rhYtWqT7778/qLUD0YjFAgFEgrBp0emO9evX64EHHtBjjz2mLVu26O9//7vWrl2rX/3qVye8Zv78+aqurg7c9u3bF8KKAfM4FnRYQwdA+AqbFp20tDTZbDaVlZW1OV5WVqbMzMwOr7n33nt1/fXX66c//akk6fzzz5fL5dJ///d/6xe/+IWs1vY5zuFwyOFwBP8HAKIMXVcAIkHYtOjY7XaNHTtWhYWFgWNer1eFhYXKzc3t8Jr6+vp2YcZms0mSfD5f7xULRDmfzxeYdUXQARDOwqZFR5Ly8/M1a9YsjRs3ThMmTNDixYvlcrk0e/ZsSdLMmTM1aNAgLVq0SJI0bdo0PfLIIxozZoxycnK0a9cu3XvvvZo2bVog8AAIvoq6JjU2e2W1SANT6LoCEL7CKujMmDFDFRUVWrBggUpLSzV69GitW7cuMEC5pKSkTQvOPffcI4vFonvuuUf79+9X//79NW3aNP3mN78x6kcAooJ/fM6A5DjF2sKmYRgA2rH4oryPp6amRsnJyaqurlZSUpLR5QARYc2HX2luwUfKPT1Vz//3BUaXAyAKdfbzm/+KAegydi0HECkIOgC6jBlXACIFQQdAl7FYIIBIQdAB0GUEHQCRgqADoEuaWjw6WNMoia4rAOGPoAOgSw4caZTPJ8XF2pTax250OQBwUgQdAF1y/EBki8VicDUAcHIEHQBdUsL4HAARhKADoEu+YtdyABGEoAOgS1hDB0AkIegA6BKCDoBIQtAB0CWsoQMgkhB0AHRadX2zahpbJElZfQk6AMIfQQdAp/m7rfonOhRntxlcDQCcGkEHQKftO3y026ovM64ARAaCDoBOYyAygEhD0AHQaQxEBhBpCDoAOo1VkQFEGoIOgE7bR9cVgAhD0AHQKR6vT/uPNEiiRQdA5CDoAOiU0ppGNXt8irVZlJnkNLocAOgUgg6ATik51NptNbhvvGxWi8HVAEDnEHQAdIp/DZ3BrKEDIIIQdAB0CgORAUQigg6ATmGxQACRiKADoFNYLBBAJCLoAOiUkqrWqeW06ACIJAQdAKdU725RZV2TJCmrL0EHQOQg6AA4pa8Ot7bmJDljlBwfa3A1ANB5BB0Ap+RfQ2dIKq05ACILQQfAKfnX0KHbCkCkIegAOCV/1xUzrgBEGoIOgFOqqG0diJye6DC4EgDoGoIOgFPyz7hKSyDoAIgsBB0Ap0TQARCpCDoATqmyzi1JSku0G1wJAHQNQQfASbV4vDpcfzTo0KIDIMIQdACcVJXLLZ9PslqkvvG06ACILAQdACdVcXR8Tr8+DtmsFoOrAYCuIegAOKnA+JwEWnMARB6CDoCTqjy6hk5/1tABEIEIOgBOiqnlACIZQQfASR0LOnRdAYg8BB0AJ3VsjA4tOgAiD0EHwEnRdQUgkhF0AJyUf0PPNAYjA4hABB0AJ+XvukrtwxgdAJGHoAPghDxen6pcTC8HELkIOgBO6HC9W15f69f9aNEBEIEIOgBOyD8QuW98rGJtvF0AiDy8cwE4oUNMLQcQ4Qg6AE6IqeUAIh1BB8AJMbUcQKQj6AA4IXYuBxDpCDoAToiuKwCRjqAD4IT8Qac/QQdAhCLoADihQItOIl1XACITQQfACVXWMr0cQGQj6ADokM/n0yEXY3QARDaCDoAOVTc0q9nTuv9DKrOuAEQogg6ADvnH5yQ5Y+SIsRlcDQB0D0EHQIcq/ONzWCwQQAQj6ADoEGvoADCDsAs6y5YtU3Z2tpxOp3JycrRx48aTnn/kyBHdfPPNGjBggBwOh4YNG6ZXX301RNUC5sUaOgDMIMboAo5XUFCg/Px8LV++XDk5OVq8eLGmTJminTt3Kj09vd35brdbl112mdLT0/W3v/1NgwYN0pdffqmUlJTQFw+YzLEWHQYiA4hcYRV0HnnkEd14442aPXu2JGn58uVau3atnnrqKc2bN6/d+U899ZSqqqr03nvvKTY2VpKUnZ0dypIB02INHQBmEDZdV263W5s3b1ZeXl7gmNVqVV5enoqKijq85h//+Idyc3N18803KyMjQyNGjNADDzwgj8dzwudpampSTU1NmxuA9o6tikzQARC5wiboVFZWyuPxKCMjo83xjIwMlZaWdnjN7t279be//U0ej0evvvqq7r33Xj388MP69a9/fcLnWbRokZKTkwO3rKysoP4cgFkwGBmAGYRN0OkOr9er9PR0/eEPf9DYsWM1Y8YM/eIXv9Dy5ctPeM38+fNVXV0duO3bty+EFQORo7LO33XFGB0AkStsxuikpaXJZrOprKyszfGysjJlZmZ2eM2AAQMUGxsrm+3YYmbnnnuuSktL5Xa7Zbe3f4N2OBxyOPgfKnAyPp9PFbToADCBsGnRsdvtGjt2rAoLCwPHvF6vCgsLlZub2+E1F154oXbt2iWv1xs49tlnn2nAgAEdhhwAnVPb1CJ3S+vvVX/G6ACIYGETdCQpPz9fTz75pJ555hl9+umnuummm+RyuQKzsGbOnKn58+cHzr/ppptUVVWl2267TZ999pnWrl2rBx54QDfffLNRPwJgCpW1ra05CY4YOWPZ/gFA5AqbritJmjFjhioqKrRgwQKVlpZq9OjRWrduXWCAcklJiazWY9ksKytLr732mubOnauRI0dq0KBBuu2223TXXXcZ9SMApsD4HABmYfH5fD6jizBSTU2NkpOTVV1draSkJKPLAcLCP7ce1E1/3qKxp/XVCzdNNLocAGins5/fYdV1BSA8sCoyALMg6ABop6KOVZEBmANBB0A7LBYIwCwIOgDa8c+6YvsHAJGOoAOgHX+LTn/G6ACIcAQdAO1UMkYHgEl0K+h4PB59/PHHamlpCXY9AMIAY3QAmEW3gs7LL7+sMWPGqKCgINj1ADBYvbtF9W6PJMboAIh83Qo6zzzzjPr376+VK1cGuRwARqusbe22csZa1cfO9g8AIluXg05lZaX++c9/auXKlXrrrbf01Vdf9UZdAAxy/K7lFovF4GoAoGe6HHSef/55jRgxQlOnTtXFF1+sZ599tjfqAmAQxucAMJMuB52VK1dq5syZkqQf//jH+tOf/hT0ogAYh6ADwEy6FHS2bdumbdu26dprr5UkXX311SopKdH777/fK8UBCD3/GJ3+iayhAyDydSnoPPPMM5o8ebLS0tIkSQkJCZo+fTqDkgEToUUHgJl0Ouh4PB4999xzgW4rvx//+McqKCiQ2+0OenEAQo+gA8BMOh10ysvLddNNN+nKK69sc3zKlCnKz89XaWlp0IsDEHoEHQBmEtPZEwcMGKAFCxa0O261WnXPPfcEtSgAxjm2/QNjdABEPva6AtAGO5cDMBOCDoCAxmaPapta97Cj6wqAGRB0AAT4x+fYbVYlOTvdsw0AYatHQWfOnDkqLy8PVi0ADHb8+By2fwBgBj0KOpdffrm+853v6L777pPL5QpWTQAMwvgcAGbTo6Bz5ZVX6v3331dGRoYmTpyo5cuXy+v1Bqs2ACF2yMXUcgDm0uMxOjabTVdccYXmzp2re+65R8OHD9fLL78cjNoAhBhTywGYTY9GG06dOlWffvqpsrKyNGHCBC1ZskTDhg3TY489psLCQi1evDhIZQIIhYpaWnQAmEuPgs6DDz6o888/Xzabrc3xFStW6JxzzulRYQBCj1WRAZhNj7qu3nrrrXYhx+/VV1/tyUMDMIA/6KTSdQXAJHoUdLZu3aqf/exn8ng8kqTt27frmmuukSSdfvrpPa8OQEj5x+j0p0UHgEn0qOvqj3/8ox599FFNnTpVycnJ2rt3r+bNmxes2gCEWKDriunlAEyiR0Hngw8+0H/+8x8dPnxYu3fv1htvvKHTTjstWLUBCKFmj1dH6pslMUYHgHl0qeuqrq6uzf25c+dqzpw52rRpk1avXq3p06fr3XffDWqBAELj0NFuK5vVopS4WIOrAYDg6FLQSU5O1gsvvBC4/84772jy5MmSpPHjx+uVV17RnXfeGdwKAYREYCByH7usVrZ/AGAOXQo6Pp9PTzzxhC688EJddNFFmjt3rj744IPA9wcNGqTCwsKgFwmg91UwtRyACXV51tWHH36ob3zjG7rooou0bds2XXzxxbrjjjsC33c6nUEtEEBosM8VADPq8mDkVatW6bLLLgvc//jjj3XllVdq0KBBmjt3blCLAxA6bP8AwIy61KLTr18/ZWVltTk2cuRILV26VI8//nhQCwMQWv4xOqyhA8BMuhR0Ro8eraeffrrd8TPPPFMlJSVBKwpA6LH9AwAz6lLX1a9//WtNmjRJBw4c0P/8z/9o5MiRcrlceuCBBzR06NDeqhFACBxbLJCuKwDm0aWgc8EFF2jDhg267bbbdPHFF8vn80lqHYD817/+tVcKBBAalbX+MTq06AAwjy4PRh41apTWr1+v8vJybd68WV6vVzk5OUpLS+uN+gCECF1XAMyo21tApKen6/LLLw9mLQAM0uLxqqqeFh0A5tOj3csBmENVvVs+n2S1SP36MEYHgHkQdAAExuf062OXje0fAJgIQQcA43MAmFang47L5dLWrVs7/N4nn3zSbmdzAJGDoAPArDoddJqbm5WTk6ONGze2Ob59+3aNGTOGoANEsENs/wDApDoddFJSUvTd735Xf/rTn9ocf/bZZ3XppZcqMzMz6MUBCA1adACYVZfG6MyaNUsFBQVqaWmRJPl8Pv35z3/W7Nmze6U4AKFRUcfO5QDMqUtBZ+rUqYqJidHatWslSevXr1ddXZ2mT5/eG7UBCJFjO5cTdACYS5eCjs1m03XXXRfovnr22Wc1Y8YM2e306wORrLLW33XF7zIAc+nyysizZs3ShAkTtH//fr3wwgt67bXXeqMuACHEGB0AZtXldXTOP/98DR8+XNddd50GDBigCy64oDfqAhAiXq9Ph1ytXVf9GaMDwGS6tWDgzJkz9fbbb2vmzJnBrgdAiB1paJbH65PE9g8AzKdbm3pef/31OnLkiH7yk58Eux4AIebvtkqJj1WsjcXSAZhLt4JOv379tHDhwmDXAsAAxwYi020FwHz47xsQ5QJr6DDjCoAJEXSAKMcaOgDMjKADRDmmlgMwM4IOEOXKa1qDTnoSQQeA+RB0gChXVtMoScpMchpcCQAEH0EHiHKlR4NOBkEHgAkRdIAoV1ZN0AFgXgQdIIq5mlpU29QiScpMJugAMJ+wCzrLli1Tdna2nE6ncnJytHHjxk5dt3r1alksFk2fPr13CwRMxN9tleCIUYKjW+uHAkBYC6ugU1BQoPz8fC1cuFBbtmzRqFGjNGXKFJWXl5/0ur179+qOO+7QxRdfHKJKAXM41m3FjCsA5hRWQeeRRx7RjTfeqNmzZ2v48OFavny54uPj9dRTT53wGo/Ho+uuu07333+/Tj/99BBWC0Q+f4sO3VYAzCpsgo7b7dbmzZuVl5cXOGa1WpWXl6eioqITXvfLX/5S6enpuuGGGzr1PE1NTaqpqWlzA6IVM64AmF3YBJ3Kykp5PB5lZGS0OZ6RkaHS0tIOr3nnnXe0YsUKPfnkk51+nkWLFik5OTlwy8rK6lHdQCTzd12xhg4AswqboNNVtbW1uv766/Xkk08qLS2t09fNnz9f1dXVgdu+fft6sUogvNF1BcDswmaaRVpammw2m8rKytocLysrU2ZmZrvzv/jiC+3du1fTpk0LHPN6vZKkmJgY7dy5U2eccUa76xwOhxwOBl4CklR6dPsHuq4AmFXYtOjY7XaNHTtWhYWFgWNer1eFhYXKzc1td/4555yjrVu3qri4OHD73ve+p0mTJqm4uJguKaAT6LoCYHZh06IjSfn5+Zo1a5bGjRunCRMmaPHixXK5XJo9e7YkaebMmRo0aJAWLVokp9OpESNGtLk+JSVFktodB9Cex+tTxdGdy+m6AmBWYRV0ZsyYoYqKCi1YsEClpaUaPXq01q1bFxigXFJSIqs1bBqhgIhWWdckj9cnm9WitAS6cwGYk8Xn8/mMLsJINTU1Sk5OVnV1tZKSkowuBwiZj/Yd0ZXL3lVmklMb7r7U6HIAoEs6+/lN8wgQpQJr6NBtBcDECDpAlCrzTy1n+wcAJkbQAaJUKTOuAEQBgg4Qpei6AhANCDpAlDrWdUXQAWBeBB0gStF1BSAaEHSAKFXm3/6BrisAJkbQAaJQXVOL6ppaJNGiA8DcCDpAFPJ3WyU6YtTHEVYLpANAUBF0gChUxowrAFGCoANEIQYiA4gWBB0gCgXW0CHoADA5gg4QhQJr6CSz/QMAcyPoAFGIrisA0YKgA0ShMrquAEQJgg4QhUoDXVcEHQDmRtABokyLx6uK2tZVkem6AmB2BB0gyhxyueX1STarRakJDEYGYG4EHSDK+Acipyc6ZLNaDK4GAHoXQQeIMqyhAyCaEHSAKBNYQ4egAyAKEHSAKBNYQ4cZVwCiAEEHiDJ0XQGIJgQdIMqw/QOAaELQAaKMv+uKFh0A0YCgA0SZsprWxQIJOgCiAUEHiCJ1TS2qa2qRxKwrANGBoANEEX+3VaIjRn0cMQZXAwC9j6ADRJHAruVMLQcQJQg6QBQJrKFDtxWAKEHQAaIIa+gAiDYEHSCKsIYOgGhD0AGiCF1XAKINQQeIImV0XQGIMgQdIIqU1rChJ4DoQtABokSLx6uK2tZVkem6AhAtCDpAlKisc8vrk2xWi1ITGIwMIDoQdIAo4e+2Sk90yGa1GFwNAIQGQQeIEuxaDiAaEXSAKBFYQ4egAyCKEHSAKMGMKwDRiKADRIkyuq4ARCGCDhAlStn+AUAUIugAUYINPQFEI4IOECXK2OcKQBQi6ABRoLaxWS63RxKDkQFEF4IOEAX8U8sTnTGKt8cYXA0AhA5BB4gCpdXscQUgOhF0gCjAGjoAohVBB4gCZcy4AhClCDpAFChlxhWAKEXQAaJAYA0duq4ARBmCDhAF2NATQLQi6ABRgK4rANGKoAOYXIvHq8q61unlGexzBSDKEHQAk6uoa5LXJ8VYLUrrQ9ABEF0IOoDJ+but0hMdslotBlcDAKFF0AFMrowZVwCiGEEHMDkGIgOIZgQdwORKa44ORCboAIhCBB3A5MrY5wpAFCPoACZH1xWAaEbQAUyODT0BRLOwCzrLli1Tdna2nE6ncnJytHHjxhOe++STT+riiy9W37591bdvX+Xl5Z30fCDa+Hy+wD5XdF0BiEZhFXQKCgqUn5+vhQsXasuWLRo1apSmTJmi8vLyDs9fv369rrnmGr355psqKipSVlaWJk+erP3794e4ciA81Ta1qN7tkSRlJLFYIIDoY/H5fD6ji/DLycnR+PHjtXTpUkmS1+tVVlaWbrnlFs2bN++U13s8HvXt21dLly7VzJkzO/WcNTU1Sk5OVnV1tZKSknpUPxBuPi+r1WWPvq1EZ4y23jfF6HIAIGg6+/kdNi06brdbmzdvVl5eXuCY1WpVXl6eioqKOvUY9fX1am5uVr9+/U54TlNTk2pqatrcALMqZddyAFEubIJOZWWlPB6PMjIy2hzPyMhQaWlppx7jrrvu0sCBA9uEpa9btGiRkpOTA7esrKwe1Q2Es8CMK8bnAIhSYRN0eurBBx/U6tWrtWbNGjmdJ35Tnz9/vqqrqwO3ffv2hbBKILSYcQUg2sUYXYBfWlqabDabysrK2hwvKytTZmbmSa/93e9+pwcffFD//ve/NXLkyJOe63A45HAwKBPR4QBr6ACIcmHTomO32zV27FgVFhYGjnm9XhUWFio3N/eE1/32t7/Vr371K61bt07jxo0LRalAxNhxsHUM2lkZCQZXAgDGCJsWHUnKz8/XrFmzNG7cOE2YMEGLFy+Wy+XS7NmzJUkzZ87UoEGDtGjRIknS//3f/2nBggVatWqVsrOzA2N5EhISlJDAGzuim8fr06cHayVJ5w1kRiGA6BRWQWfGjBmqqKjQggULVFpaqtGjR2vdunWBAcolJSWyWo81Qj3++ONyu936wQ9+0OZxFi5cqPvuuy+UpQNhZ09lnRqaPYqLtWloGsEfQHQKq3V0jMA6OjCrl4r367bVxRozJEVr/udCo8sBgKCKuHV0AATXJwdax+eMGJhscCUAYByCDmBSnxyolsT4HADRjaADmJDP5wu06JxHiw6AKEbQAUzoQHWjjtQ3K8Zq0bBMBiIDiF4EHcCEPtnf2m11ZnqCHDE2g6sBAOMQdAATotsKAFoRdAATOhZ0GIgMILoRdAAT2s6MKwCQRNABTOewyx3YzHM4QQdAlCPoACbj77Y6LTVeic5Yg6sBAGMRdACTYaFAADiGoAOYDDOuAOAYgg5gMv4WHcbnAABBBzCVeneLdle6JNF1BQASQQcwlU8P1srnk/onOpSe6DS6HAAwHEEHMBHWzwGAtgg6gImwIjIAtEXQAUyEGVcA0BZBBzCJZo9XO0trJdGiAwB+BB3AJHaV18nt8SrREaOsvvFGlwMAYYGgA5iEv9vq3IFJslotBlcDAOGBoAOYBFs/AEB7BB3AJD7Zz0BkAPg6gg5gAl6vT9sPMrUcAL6OoAOYQElVveqaWmSPserM9ASjywGAsEHQAUzAPxD57IxExdr4tQYAP94RARPwD0QeMYhuKwA4HkEHMAF/i85wBiIDQBsEHcAE2OMKADpG0AEiXHlNoyrrmmS1SOdmEnQA4HgEHSDC+VtzTu+foDi7zeBqACC8EHSACMeKyABwYgQdIMIxPgcAToygA0S4Y0GHGVcA8HUxRhcAoPtqGptVUlUviRYdIJh8Pp9aWlrk8XiMLiVq2Ww2xcTEyGKx9OhxCDpABNt+tDVnUEqcUuLtBlcDmIPb7dbBgwdVX19vdClRLz4+XgMGDJDd3v33N4IOEMGOLRRIaw4QDF6vV3v27JHNZtPAgQNlt9t73KKArvP5fHK73aqoqNCePXt01llnyWrt3mgbgg4QwZhxBQSX2+2W1+tVVlaW4uPjjS4nqsXFxSk2NlZffvml3G63nE5ntx6HwchABNvOQGSgV3S39QDBFYy/B/4mgQjV2OzR5+V1kmjRAYATIegAEeqzslp5vD71jY/VgOTuNekCgNkRdIAIdfz6OQyWBICOEXSACLVh9yFJdFsBaK+oqEgWi0VXXHFFrz3HsmXLlJ2dLafTqZycHG3cuLFXrukpgg4QgfZWuvTKxwclSZefP8DgagCEmxUrVuiaa65RYWGhDhw4EPTHLygoUH5+vhYuXKgtW7Zo1KhRmjJlisrLy4N6TTAQdIAItPTNXfJ4fZp0dn+NzkoxuhzA1Hw+n+rdLSG/+Xy+btVbV1engoIC3X777Zo0aZJWrlwZ3BdE0iOPPKIbb7xRs2fP1vDhw7V8+XLFx8frqaeeCuo1wcA6OkCE2Vvp0poP90uSbssbZnA1gPk1NHs0fMFrIX/e7b+conh71z+m//KXvygzM1MTJkzQddddp/vuu0/z58/vcCzfAw88oAceeODkdWzfriFDhgTuu91ubd68WfPnzw8cs1qtysvLU1FRUYeP0Z1rgoWgA0SYJW+0tuZ8+5x0WnMAtLNixQpdd911kqTp06frZz/7md566y1961vfanfunDlz9MMf/vCkjzdw4MA29ysrK+XxeJSRkdHmeEZGhnbs2NHhY3TnmmAh6AARZE+lS2s+/EqSdNulZxlcDRAd4mJt2v7LKYY8b1ft3LlT7733XqC7KiEhQVdeeaVWrFjRYdDp16+f+vXr18NKwxtBB4ggS974XF6f9O1z0jWK1hwgJCwWS7e6kIywYsUKjR8/Xmeddew/Qtddd52uvvpqLV26VMnJbVdR707XVVpammw2m8rKytqcV1ZWpszMzA4fozvXBAuDkYEIsafSpRePjs25PY/WHABttbS06E9/+pOuvfbaNscnT56s+Ph4Pf/88+2umTNnjoqLi096+3rXld1u19ixY1VYWBg45vV6VVhYqNzc3A5r6841wRIZERWAlhS2tuZcek66Rg5OMbocAGHmlVdeUVlZmUaMGKFt27a1+d4ll1yiFStWaM6cOW2Od7frKj8/X7NmzdK4ceM0YcIELV68WC6XS7Nnzw6cs3TpUq1ZsyYQbjpzTW8g6AARYHdFnV4s9s+0ojUHQHsrVqyQJF122WUnPOfjjz/WyJEje/xcM2bMUEVFhRYsWKDS0lKNHj1a69atazPYuLKyUl988UWXrukNFl93J+qbRE1NjZKTk1VdXa2kJFaYRXjKLyjW3z/cr7xz0/XHWeONLgcwrcbGRu3Zs0dDhw6V08keckY72d9HZz+/GaMDhLkvjm/NuZR1cwCgKwg6QJhb+sYueX1S3rnpOn9w8qkvAAAEEHSAMPZFRZ1eKvbPtKI1BwC6iqADhDH/TKu8czM0YhCtOQDQVQQdIEztKq/TPz5q3XWYdXOA0IryeTphIxh/DwQdIEz5V0G+bDitOUCoxMbGSpLq6+sNrgTSsb8H/99Ld7CODhCGjm/NYU8rIHRsNptSUlJUXl4uSYqPj+9w12/0Lp/Pp/r6epWXlyslJUU2W9f3/fIj6ABhxN3i1Z/f/1L/f+Hn8vmkybTmACHn33vJH3ZgnJSUlB7vhUXQAcKAz+fT2q0H9dt1O1VS1dpUe0b/PrrniuEGVwZEH4vFogEDBig9PV3Nzc1GlxO1YmNje9SS40fQAQy2YfchLfrnDn2074gkqX+iQ3PzhumH4wYrxsYwOsAoNpstKB+0MFbYvYsuW7ZM2dnZcjqdysnJ0caNG096/l//+ledc845cjqdOv/88/Xqq6+GqFKgZz4vq9VPn/lAP/rDBn2074ji7TbNzRum9Xd8S9fmDCHkAEAQhFWLTkFBgfLz87V8+XLl5ORo8eLFmjJlinbu3Kn09PR257/33nu65pprtGjRIn33u9/VqlWrNH36dG3ZskUjRoww4CcAOtbi8aqirkllNU0qq2nUmzvK9ZdN++T1STarRddMyNJtlw5T/0SH0aUCgKmE1aaeOTk5Gj9+vJYuXSpJ8nq9ysrK0i233KJ58+a1O3/GjBlyuVx65ZVXAscuuOACjR49WsuXL+/Uc/bWpp6Fn5ap2eMN2uOh9/l/E3xfu996zBc45vH61OL1yeP1yuOVPF7v0futxxubPSqvbVJ5TaNKaxpVVtOkyromdfSbNuW8DN059Ryd0T+hd384ADCZzn5+h02Ljtvt1ubNmzV//vzAMavVqry8PBUVFXV4TVFRkfLz89scmzJlil588cUTPk9TU5OampoC96urqyW1vmDBlP9ckQ7XM4gNx8RYLUpLsKt/olODUpy6NmeIvnFaP0neoP/7AwCz879vnqq9JmyCTmVlpTwejzIyMtocz8jI0I4dOzq8prS0tMPzS0tLT/g8ixYt0v3339/ueFZWVjeqBrpmz3FfP2lYFQBgHrW1tUpOPvEyHGETdEJl/vz5bVqBvF6vqqqqlJqaGtRFoWpqapSVlaV9+/YFtUsMbfE6hwavc+jwWocGr3No9Obr7PP5VFtbq4EDB570vLAJOmlpabLZbCorK2tzvKys7ISLBWVmZnbpfElyOBxyONoO+ExJSele0Z2QlJTEL1EI8DqHBq9z6PBahwavc2j01ut8spYcv7CZv2q32zV27FgVFhYGjnm9XhUWFio3N7fDa3Jzc9ucL0mvv/76Cc8HAADRJWxadCQpPz9fs2bN0rhx4zRhwgQtXrxYLpdLs2fPliTNnDlTgwYN0qJFiyRJt912m775zW/q4Ycf1hVXXKHVq1dr06ZN+sMf/mDkjwEAAMJEWAWdGTNmqKKiQgsWLFBpaalGjx6tdevWBQYcl5SUyGo91gg1ceJErVq1Svfcc4/uvvtunXXWWXrxxRfDYg0dh8OhhQsXtusmQ3DxOocGr3Po8FqHBq9zaITD6xxW6+gAAAAEU9iM0QEAAAg2gg4AADAtgg4AADAtgg4AADAtgk4v27t3r2644QYNHTpUcXFxOuOMM7Rw4UK53W6jSzOl3/zmN5o4caLi4+N7dSHIaLNs2TJlZ2fL6XQqJydHGzduNLok03n77bc1bdo0DRw4UBaL5aR79qF7Fi1apPHjxysxMVHp6emaPn26du7caXRZpvT4449r5MiRgYUCc3Nz9c9//tOQWgg6vWzHjh3yer164okn9Mknn+jRRx/V8uXLdffddxtdmim53W5dffXVuummm4wuxTQKCgqUn5+vhQsXasuWLRo1apSmTJmi8vJyo0szFZfLpVGjRmnZsmVGl2Jab731lm6++WZt2LBBr7/+upqbmzV58mS5XC6jSzOdwYMH68EHH9TmzZu1adMmffvb39aVV16pTz75JOS1ML3cAA899JAef/xx7d692+hSTGvlypW6/fbbdeTIEaNLiXg5OTkaP368li5dKql1xfKsrCzdcsstmjdvnsHVmZPFYtGaNWs0ffp0o0sxtYqKCqWnp+utt97SJZdcYnQ5ptevXz899NBDuuGGG0L6vLToGKC6ulr9+vUzugzglNxutzZv3qy8vLzAMavVqry8PBUVFRlYGdBz1dXVksT7cS/zeDxavXq1XC6XIVs0hdXKyNFg165dWrJkiX73u98ZXQpwSpWVlfJ4PIHVyf0yMjK0Y8cOg6oCes7r9er222/XhRdeGBar6ZvR1q1blZubq8bGRiUkJGjNmjUaPnx4yOugRaeb5s2bJ4vFctLb1z8I9u/fr6lTp+rqq6/WjTfeaFDlkac7rzUAnMzNN9+sbdu2afXq1UaXYlpnn322iouL9f777+umm27SrFmztH379pDXQYtON/3v//6v/uu//uuk55x++umBrw8cOKBJkyZp4sSJbDraRV19rRE8aWlpstlsKisra3O8rKxMmZmZBlUF9MzPf/5zvfLKK3r77bc1ePBgo8sxLbvdrjPPPFOSNHbsWH3wwQf6/e9/ryeeeCKkdRB0uql///7q379/p87dv3+/Jk2apLFjx+rpp59uszEpTq0rrzWCy263a+zYsSosLAwMjPV6vSosLNTPf/5zY4sDusjn8+mWW27RmjVrtH79eg0dOtTokqKK1+tVU1NTyJ+XoNPL9u/fr29961s67bTT9Lvf/U4VFRWB7/E/4uArKSlRVVWVSkpK5PF4VFxcLEk688wzlZCQYGxxESo/P1+zZs3SuHHjNGHCBC1evFgul0uzZ882ujRTqaur065duwL39+zZo+LiYvXr109DhgwxsDLzuPnmm7Vq1Sq99NJLSkxMVGlpqSQpOTlZcXFxBldnLvPnz9fll1+uIUOGqLa2VqtWrdL69ev12muvhb4YH3rV008/7ZPU4Q3BN2vWrA5f6zfffNPo0iLakiVLfEOGDPHZ7XbfhAkTfBs2bDC6JNN58803O/y3O2vWLKNLM40TvRc//fTTRpdmOj/5yU98p512ms9ut/v69+/vu/TSS33/+te/DKmFdXQAAIBpMVgEAACYFkEHAACYFkEHAACYFkEHAACYFkEHAACYFkEHAACYFkEHAACYFkEHAACYFkEHQMSbO3eurrrqqg6/9/HHH+uqq65SamqqnE6nzjvvPD300ENqaWkJcZUAjEDQARDxNm7cqHHjxrU7/vbbb+uCCy5QXFycXnrpJX300Ue666679Mgjj+iqq66S1+s1oFoAocQWEAAiltvtVp8+fdq0zuTk5GjDhg3yeDwaNmyYcnNz9dxzz7W5bseOHRo5cqQef/xx3XDDDaEuG0AIEXQARCyv16tNmzYpJydHxcXFysjIkNPpVEpKioqKijRx4kQVFxdr1KhR7a79/ve/L5fLpX/9618GVA4gVOi6AhCxrFarDhw4oNTUVI0aNUqZmZlKSUmRJO3Zs0eSdNZZZ3V47VlnnaUvv/wyVKUCMAhBB0BE+/DDDztssUlKSpIkVVVVdXjd4cOHA+cAMC+CDoCIdqKuqdzcXMXGxurll19u9z2Px6PXXntNF110UShKBGAggg6AiLZ161aNHj263fHU1FTdeuut+vWvf60DBw60+d6jjz6qqqoqzZ07N0RVAjAKQQdARPN6vdq5c6cOHDig6urqwPG6ujrdeuutys7O1qRJk7RlyxZJ0kMPPaS7775bS5Yskd1ul8fjMap0ACHArCsAEe25557TXXfdpQMHDuiOO+7QQw89JEm67777dP/99wfOmzVrllauXCmLxdLm+j179ig7OzuUJQMIIYIOAAAwLbquAACAaRF0AACAaRF0AACAaRF0AACAaRF0AACAaRF0AACAaRF0AACAaRF0AACAaRF0AACAaRF0AACAaRF0AACAaRF0AACAaf0/ue+Y4Muz8IEAAAAASUVORK5CYII=", "text/plain": [ "
" ] @@ -347,8 +347,9 @@ "output_type": "stream", "text": [ "--> PT-TEMPO computation:\n", - "100.0% 50 of 50 [########################################] 00:00:00\n", - "Elapsed time: 0.3s\n" + "100.0% 50 of 50 [########################################] 00:00:01\n", + "Elapsed time: 1.1s\n", + "(1, 3, 4, 4)\n" ] } ], @@ -358,7 +359,9 @@ "process_tensor = oqupy.pt_tempo_compute(bath=bath,\n", " start_time=-2.0,\n", " end_time=3.0,\n", - " parameters=tempo_parameters)" + " parameters=tempo_parameters)\n", + "\n", + "print(process_tensor.get_mpo_tensor(0).shape)" ] }, { @@ -443,7 +446,7 @@ { "data": { "text/plain": [ - "" + "" ] }, "execution_count": 13, @@ -452,7 +455,7 @@ }, { "data": { - "image/png": "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smnTJqZOnerfZ7FYmDp1KuvXrw9gZSLnrrKyEkC/j7uZ2+3m+eefp7a2NiBLNAXVzMh9wZ49e3jyySf51a9+FehSRM6ovLwct9vtn53cJy0tjR07dgSoKpFz5/F4uPfee7nsssuCYjb9UPTpp58yadIkGhoaiI6OZvXq1YwcObLH61CLzll64IEHMAyj3e3kvwiOHDnCNddcw80338ydd94ZoMp7n7P5WYuItOeee+5h69atPP/884EuJWSNGDGCLVu28OGHH3L33Xczd+5ctm3b1uN1qEXnLH33u9/l9ttvb/eYwYMH+58XFhZy5ZVXcumll2rR0U7q7M9auk5ycjJWq5WSkpJW+0tKSkhPTw9QVSLnZsGCBbz22mu899579OvXL9DlhCyHw8HQoUMBGDduHB999BH/93//x+9+97serUNB5yylpKSQkpLSoWOPHDnClVdeybhx4/jTn/7UamFSObPO/KylazkcDsaNG0d+fr5/YKzH4yE/P58FCxYEtjiRTjJNk29/+9usXr2atWvXMmjQoECX1Kd4PB4aGxt7/LoKOt3syJEjTJkyhQEDBvCrX/2KsrIy/3v6F3HXKygo4OjRoxQUFOB2u9myZQsAQ4cOJTo6OrDF9VK5ubnMnTuX8ePHM3HiRBYvXkxtbS3z5s0LdGkhpaamhj179vhf79+/ny1btpCYmEj//v0DWFnouOeee3j22Wd55ZVXiImJobi4GIC4uDgiIiICXF1oefDBB5kxYwb9+/enurqaZ599lrVr1/LWW2/1fDGmdKs//elPJtDmJl1v7ty5bf6s33nnnUCX1qs9+eSTZv/+/U2Hw2FOnDjR/OCDDwJdUsh555132vz/7ty5cwNdWsg43e/iP/3pT4EuLeR8/etfNwcMGGA6HA4zJSXFvOqqq8x//OMfAalF8+iIiIhIyNJgEREREQlZCjoiIiISshR0REREJGQp6IiIiEjIUtARERGRkKWgIyIiIiFLQUdERERCloKOiIiIhCwFHREREQlZCjoi0uvcd9993HTTTafsnzdvHg899FAAKhKRYKWgIyK9zoYNGxg/fnyrfW63m9dee43rr78+QFWJSDBS0BGRXsPpdGK321m3bh0//OEPMQyDSy65BIB169Zht9uZMGECAFOmTGHBggUsWLCAuLg4kpOT+dGPfoRveb8XX3yRiy66iIiICJKSkpg6dSq1tbUB+24i0j1sgS5ARKSjbDYb//nPf8jJyWHLli2kpaURHh4OwKuvvsp1112HYRj+4//85z9zxx13sGHDBjZu3Mg3v/lN+vfvzxe/+EVmz57NL37xC2688Uaqq6v597//jdY4Fgk9Cjoi0mtYLBYKCwtJSkpi9OjRrd575ZVX+PWvf91qX3Z2Nr/+9a8xDIMRI0bw6aef8utf/5px48bhcrm46aabGDBgAAAXXXRRj30PEek56roSkV7l448/PiXkbN++ncLCQq666qpW+y+55JJWLTyTJk1i9+7djB49mquuuoqLLrqIm2++mT/84Q8cO3asR+oXkZ6loCMivcqWLVtOCTqvvvoqV199tb8bqyPefvtt3njjDUaOHMmTTz7JiBEj2L9/f1eXKyIBpqAjIr3Kp59+ypgxY1rte+WVV7jhhhtOOfbDDz9s9fqDDz5g2LBhWK1WDMPgsssu45FHHuHjjz/G4XCwevXq7ixdRAJAY3REpFfxeDzs3LmTwsJCoqKiaGxsZOPGjbz66qunHFtQUEBubi533XUXmzdv5sknn+Txxx/nww8/JD8/n2nTppGamsqHH35IWVkZ559/fgC+kYh0JwUdEelVfvazn/H973+fRYsWcf/993PeeecxceJEkpOTTzn2tttuo76+nokTJ2K1WvnOd77DN7/5TXbs2MF7773H4sWLqaqqYsCAATz++OPMmDEjAN9IRLqTYep+ShHpxa6//nouv/xyvve977XaP2XKFMaMGcPixYsDU5iIBAWN0RGRXu3yyy9n9uzZgS5DRIKUuq5EpFc7uSVHRKQldV2JiIhIyFLXlYiIiIQsBR0REREJWQo6IiIiErIUdERERCRkKeiIiIhIyFLQERERkZCloCMiIiIhS0FHREREQpaCjoiIiIQsBR0REREJWQo6IiIiErL+PxZDVNKjSrZSAAAAAElFTkSuQmCC", + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAjoAAAG5CAYAAACHhJ4rAAAAOnRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjEwLjMsIGh0dHBzOi8vbWF0cGxvdGxpYi5vcmcvZiW1igAAAAlwSFlzAAAPYQAAD2EBqD+naQAAcsZJREFUeJzt3Xl8VNX9//HXnS37vieEfVFUFlkiKhYrgtSqaKsUaUVqrVjpr5r6bbW1Urug37ZavhUqXUKprQtoRa241KaitaAISBXZ1wDZA2RPJjNzf39MZkgghASSzGTyfvZxHzNz5965n4klvDnn3HMM0zRNREREREKQJdAFiIiIiHQXBR0REREJWQo6IiIiErIUdERERCRkKeiIiIhIyFLQERERkZCloCMiIiIhS0FHREREQpaCjoiIiIQsBR0REREJWUETdN577z2uu+46MjMzMQyDl19++YznrF27losvvpiwsDCGDh3KihUrur1OERER6T2CJujU1tYyevRoli5d2qHj9+/fz7XXXsuVV17Jli1buPfee/nGN77BW2+91c2VioiISG9hBOOinoZhsHr1ambOnHnaY77//e+zZs0atm7d6t/3la98hePHj/Pmm2/2QJUiIiIS7GyBLuBsrV+/nqlTp7baN336dO699952z2tsbKSxsdH/2uPxcPToUZKSkjAMoztKFRERkS5mmibV1dVkZmZisZy+g6rXBp3i4mLS0tJa7UtLS6Oqqor6+noiIiLaPO/RRx/lkUce6YkSRUREpJsdOnSIfv36nfb9Xht0ztaDDz5Ibm6u/3VlZSX9+/fn0KFDxMbGBrAyERER6aiqqiqys7OJiYlp97heG3TS09MpKSlpta+kpITY2NjTtuYAhIWFERYWdsr+2NhYBR0REZFe5kzDToLmrqvOmjRpEvn5+a32vf3220yaNClAFYmIiEiwCZqgU1NTw5YtW9iyZQvgvX18y5YtFBQUAN4up9tuu81//Pz589m3bx/f+9732LFjB7/97W9ZtWoV9913XyDKFxERkSAUNEFn48aNjB07lrFjxwKQm5vL2LFjefjhhwEoKiryhx6AQYMGsWbNGt5++21Gjx7N448/zh//+EemT58ekPpFREQk+ATlPDo9qaqqiri4OCorK087Rsfj8eB0Onu4MjlXdrsdq9Ua6DJERKQbdOTvb+jFg5F7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", "text/plain": [ "
" ] @@ -479,13 +482,10 @@ } ], "metadata": { - "interpreter": { - "hash": "3306e98808c0871e8a1685f50cc307ae5b4a4a013844b10634a4efe89132c3fe" - }, "kernelspec": { - "display_name": "oqupyPR", + "display_name": ".venv", "language": "python", - "name": "oqupypr" + "name": "python3" }, "language_info": { "codemirror_mode": { @@ -497,7 +497,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.6.15" + "version": "3.11.5" }, "widgets": { "application/vnd.jupyter.widget-state+json": {