From 8ee4eb4d6c0c1e6755a5b9ced11fe528467888a5 Mon Sep 17 00:00:00 2001 From: meandmytram Date: Mon, 21 Aug 2023 14:44:48 +0200 Subject: [PATCH] add failing svd example --- examples/decoding/failing_svd.ipynb | 183 ++++++++++++++++++++++++++++ 1 file changed, 183 insertions(+) create mode 100644 examples/decoding/failing_svd.ipynb diff --git a/examples/decoding/failing_svd.ipynb b/examples/decoding/failing_svd.ipynb new file mode 100644 index 00000000..ef72e984 --- /dev/null +++ b/examples/decoding/failing_svd.ipynb @@ -0,0 +1,183 @@ +{ + "cells": [ + { + "cell_type": "code", + "execution_count": 1, + "metadata": {}, + "outputs": [], + "source": [ + "import numpy as np\n", + "import qecstruct as qec\n", + "import matplotlib.pyplot as plt\n", + "from mdopt.optimiser.utils import (\n", + " ConstraintString,\n", + " IDENTITY,\n", + " SWAP,\n", + " XOR_BULK,\n", + " XOR_LEFT,\n", + " XOR_RIGHT,\n", + ")\n", + "from examples.decoding.decoding import (\n", + " linear_code_constraint_sites,\n", + " linear_code_prepare_message,\n", + " linear_code_codewords,\n", + ")\n", + "from examples.decoding.decoding import (\n", + " apply_bitflip_bias,\n", + " apply_constraints,\n", + " decode_linear,\n", + ")\n", + "from mdopt.mps.utils import (\n", + " create_simple_product_state,\n", + " create_custom_product_state,\n", + ")\n", + "from mdopt.utils.utils import mpo_to_matrix" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "metadata": {}, + "outputs": [ + { + "name": "stdout", + "output_type": "stream", + "text": [ + "** On entry to DLASCL, parameter number 4 had an illegal value\n", + "** On entry to DLASCL, parameter number 4 had an illegal value\n", + "** On entry to DLASCL, parameter number 5 had an illegal value\n" + ] + }, + { + "ename": "ValueError", + "evalue": "array must not contain infs or NaNs", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mLinAlgError\u001b[0m Traceback (most recent call last)", + "File \u001b[0;32m~/mdopt/mdopt/utils/utils.py:50\u001b[0m, in \u001b[0;36msvd\u001b[0;34m(mat, cut, chi_max, renormalise)\u001b[0m\n\u001b[1;32m 49\u001b[0m \u001b[39mtry\u001b[39;00m:\n\u001b[0;32m---> 50\u001b[0m u_l, singular_values, v_r \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39;49mlinalg\u001b[39m.\u001b[39;49msvd(\n\u001b[1;32m 51\u001b[0m mat, full_matrices\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m, compute_uv\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m, hermitian\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m\n\u001b[1;32m 52\u001b[0m )\n\u001b[1;32m 53\u001b[0m \u001b[39mexcept\u001b[39;00m np\u001b[39m.\u001b[39mlinalg\u001b[39m.\u001b[39mLinAlgError:\n", + "File \u001b[0;32m<__array_function__ internals>:180\u001b[0m, in \u001b[0;36msvd\u001b[0;34m(*args, **kwargs)\u001b[0m\n", + "File \u001b[0;32m~/Library/Caches/pypoetry/virtualenvs/mdopt-ZdbamFdU-py3.11/lib/python3.11/site-packages/numpy/linalg/linalg.py:1657\u001b[0m, in \u001b[0;36msvd\u001b[0;34m(a, full_matrices, compute_uv, hermitian)\u001b[0m\n\u001b[1;32m 1656\u001b[0m signature \u001b[39m=\u001b[39m \u001b[39m'\u001b[39m\u001b[39mD->DdD\u001b[39m\u001b[39m'\u001b[39m \u001b[39mif\u001b[39;00m isComplexType(t) \u001b[39melse\u001b[39;00m \u001b[39m'\u001b[39m\u001b[39md->ddd\u001b[39m\u001b[39m'\u001b[39m\n\u001b[0;32m-> 1657\u001b[0m u, s, vh \u001b[39m=\u001b[39m gufunc(a, signature\u001b[39m=\u001b[39;49msignature, extobj\u001b[39m=\u001b[39;49mextobj)\n\u001b[1;32m 1658\u001b[0m u \u001b[39m=\u001b[39m u\u001b[39m.\u001b[39mastype(result_t, copy\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m)\n", + "File \u001b[0;32m~/Library/Caches/pypoetry/virtualenvs/mdopt-ZdbamFdU-py3.11/lib/python3.11/site-packages/numpy/linalg/linalg.py:98\u001b[0m, in \u001b[0;36m_raise_linalgerror_svd_nonconvergence\u001b[0;34m(err, flag)\u001b[0m\n\u001b[1;32m 97\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m_raise_linalgerror_svd_nonconvergence\u001b[39m(err, flag):\n\u001b[0;32m---> 98\u001b[0m \u001b[39mraise\u001b[39;00m LinAlgError(\u001b[39m\"\u001b[39m\u001b[39mSVD did not converge\u001b[39m\u001b[39m\"\u001b[39m)\n", + "\u001b[0;31mLinAlgError\u001b[0m: SVD did not converge", + "\nDuring handling of the above exception, another exception occurred:\n", + "\u001b[0;31mValueError\u001b[0m Traceback (most recent call last)", + "Cell \u001b[0;32mIn[2], line 44\u001b[0m\n\u001b[1;32m 35\u001b[0m perturbed_codeword_state \u001b[39m=\u001b[39m apply_bitflip_bias(\n\u001b[1;32m 36\u001b[0m mps\u001b[39m=\u001b[39mperturbed_codeword_state,\n\u001b[1;32m 37\u001b[0m sites_to_bias\u001b[39m=\u001b[39m\u001b[39m\"\u001b[39m\u001b[39mAll\u001b[39m\u001b[39m\"\u001b[39m,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 40\u001b[0m result_to_explicit\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m,\n\u001b[1;32m 41\u001b[0m )\n\u001b[1;32m 43\u001b[0m \u001b[39m#try:\u001b[39;00m\n\u001b[0;32m---> 44\u001b[0m perturbed_codeword_state \u001b[39m=\u001b[39m apply_constraints(\n\u001b[1;32m 45\u001b[0m perturbed_codeword_state,\n\u001b[1;32m 46\u001b[0m code_constraint_sites,\n\u001b[1;32m 47\u001b[0m tensors,\n\u001b[1;32m 48\u001b[0m chi_max\u001b[39m=\u001b[39;49mCHI_MAX_CONTRACTOR,\n\u001b[1;32m 49\u001b[0m renormalise\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m,\n\u001b[1;32m 50\u001b[0m result_to_explicit\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m,\n\u001b[1;32m 51\u001b[0m strategy\u001b[39m=\u001b[39;49m\u001b[39m\"\u001b[39;49m\u001b[39mNaive\u001b[39;49m\u001b[39m\"\u001b[39;49m,\n\u001b[1;32m 52\u001b[0m silent\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m,\n\u001b[1;32m 53\u001b[0m )\n\u001b[1;32m 54\u001b[0m \u001b[39m#except:\u001b[39;00m\n\u001b[1;32m 55\u001b[0m \u001b[39m# print(SEED, PROB_ERROR, l)\u001b[39;00m\n\u001b[1;32m 56\u001b[0m \u001b[39m# pass\u001b[39;00m\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 72\u001b[0m \n\u001b[1;32m 73\u001b[0m \u001b[39m#failures_statistics[NUM_BITS, PROB_ERROR] = failures\u001b[39;00m\n", + "File \u001b[0;32m~/mdopt/examples/decoding/decoding.py:728\u001b[0m, in \u001b[0;36mapply_constraints\u001b[0;34m(mps, strings, logical_tensors, chi_max, renormalise, result_to_explicit, strategy, silent)\u001b[0m\n\u001b[1;32m 723\u001b[0m \u001b[39melif\u001b[39;00m \u001b[39mall\u001b[39m(flags_left):\n\u001b[1;32m 724\u001b[0m mps\u001b[39m.\u001b[39morth_centre \u001b[39m=\u001b[39m mps\u001b[39m.\u001b[39mnum_sites \u001b[39m-\u001b[39m \u001b[39m1\u001b[39m\n\u001b[1;32m 726\u001b[0m mps \u001b[39m=\u001b[39m cast(\n\u001b[1;32m 727\u001b[0m Union[ExplicitMPS, CanonicalMPS],\n\u001b[0;32m--> 728\u001b[0m mps\u001b[39m.\u001b[39;49mmove_orth_centre(final_pos\u001b[39m=\u001b[39;49mstart_site, renormalise\u001b[39m=\u001b[39;49mrenormalise),\n\u001b[1;32m 729\u001b[0m )\n\u001b[1;32m 731\u001b[0m \u001b[39m# Doing the contraction.\u001b[39;00m\n\u001b[1;32m 732\u001b[0m mps \u001b[39m=\u001b[39m mps_mpo_contract(\n\u001b[1;32m 733\u001b[0m mps,\n\u001b[1;32m 734\u001b[0m mpo,\n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 739\u001b[0m result_to_explicit\u001b[39m=\u001b[39mresult_to_explicit,\n\u001b[1;32m 740\u001b[0m )\n", + "File \u001b[0;32m~/mdopt/mdopt/mps/canonical.py:416\u001b[0m, in \u001b[0;36mCanonicalMPS.move_orth_centre\u001b[0;34m(self, final_pos, return_singular_values, renormalise)\u001b[0m\n\u001b[1;32m 414\u001b[0m \u001b[39mfor\u001b[39;00m i \u001b[39min\u001b[39;00m \u001b[39mrange\u001b[39m(begin, final):\n\u001b[1;32m 415\u001b[0m two_site_tensor \u001b[39m=\u001b[39m mps\u001b[39m.\u001b[39mtwo_site_tensor_next(i)\n\u001b[0;32m--> 416\u001b[0m u_l, singular_values_bond, v_r \u001b[39m=\u001b[39m split_two_site_tensor(\n\u001b[1;32m 417\u001b[0m two_site_tensor,\n\u001b[1;32m 418\u001b[0m chi_max\u001b[39m=\u001b[39;49m\u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mchi_max,\n\u001b[1;32m 419\u001b[0m renormalise\u001b[39m=\u001b[39;49mrenormalise,\n\u001b[1;32m 420\u001b[0m strategy\u001b[39m=\u001b[39;49m\u001b[39m\"\u001b[39;49m\u001b[39msvd\u001b[39;49m\u001b[39m\"\u001b[39;49m,\n\u001b[1;32m 421\u001b[0m )\n\u001b[1;32m 422\u001b[0m singular_values\u001b[39m.\u001b[39mappend(singular_values_bond)\n\u001b[1;32m 423\u001b[0m mps\u001b[39m.\u001b[39mtensors[i] \u001b[39m=\u001b[39m u_l\n", + "File \u001b[0;32m~/mdopt/mdopt/utils/utils.py:206\u001b[0m, in \u001b[0;36msplit_two_site_tensor\u001b[0;34m(tensor, chi_max, cut, renormalise, strategy)\u001b[0m\n\u001b[1;32m 203\u001b[0m tensor \u001b[39m=\u001b[39m tensor\u001b[39m.\u001b[39mreshape((chi_v_l \u001b[39m*\u001b[39m phys_l, phys_r \u001b[39m*\u001b[39m chi_v_r))\n\u001b[1;32m 205\u001b[0m \u001b[39mif\u001b[39;00m strategy \u001b[39m==\u001b[39m \u001b[39m\"\u001b[39m\u001b[39msvd\u001b[39m\u001b[39m\"\u001b[39m:\n\u001b[0;32m--> 206\u001b[0m u_l, singular_values, v_r \u001b[39m=\u001b[39m svd(\n\u001b[1;32m 207\u001b[0m tensor, cut\u001b[39m=\u001b[39;49mcut, chi_max\u001b[39m=\u001b[39;49mchi_max, renormalise\u001b[39m=\u001b[39;49mrenormalise\n\u001b[1;32m 208\u001b[0m )\n\u001b[1;32m 209\u001b[0m chi_v_cut \u001b[39m=\u001b[39m \u001b[39mlen\u001b[39m(singular_values)\n\u001b[1;32m 210\u001b[0m u_l \u001b[39m=\u001b[39m u_l\u001b[39m.\u001b[39mreshape((chi_v_l, phys_l, chi_v_cut))\n", + "File \u001b[0;32m~/mdopt/mdopt/utils/utils.py:54\u001b[0m, in \u001b[0;36msvd\u001b[0;34m(mat, cut, chi_max, renormalise)\u001b[0m\n\u001b[1;32m 50\u001b[0m u_l, singular_values, v_r \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39mlinalg\u001b[39m.\u001b[39msvd(\n\u001b[1;32m 51\u001b[0m mat, full_matrices\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m, compute_uv\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m, hermitian\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m\n\u001b[1;32m 52\u001b[0m )\n\u001b[1;32m 53\u001b[0m \u001b[39mexcept\u001b[39;00m np\u001b[39m.\u001b[39mlinalg\u001b[39m.\u001b[39mLinAlgError:\n\u001b[0;32m---> 54\u001b[0m u_l, singular_values, v_r \u001b[39m=\u001b[39m scipy\u001b[39m.\u001b[39;49mlinalg\u001b[39m.\u001b[39;49msvd(\n\u001b[1;32m 55\u001b[0m mat, full_matrices\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m, compute_uv\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m, lapack_driver\u001b[39m=\u001b[39;49m\u001b[39m\"\u001b[39;49m\u001b[39mgesvd\u001b[39;49m\u001b[39m\"\u001b[39;49m\n\u001b[1;32m 56\u001b[0m )\n\u001b[1;32m 58\u001b[0m max_num \u001b[39m=\u001b[39m \u001b[39mmin\u001b[39m(chi_max, np\u001b[39m.\u001b[39msum(singular_values \u001b[39m>\u001b[39m cut))\n\u001b[1;32m 59\u001b[0m ind \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39margsort(singular_values)[::\u001b[39m-\u001b[39m\u001b[39m1\u001b[39m][:max_num]\n", + "File \u001b[0;32m~/Library/Caches/pypoetry/virtualenvs/mdopt-ZdbamFdU-py3.11/lib/python3.11/site-packages/scipy/linalg/_decomp_svd.py:108\u001b[0m, in \u001b[0;36msvd\u001b[0;34m(a, full_matrices, compute_uv, overwrite_a, check_finite, lapack_driver)\u001b[0m\n\u001b[1;32m 13\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39msvd\u001b[39m(a, full_matrices\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m, compute_uv\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m, overwrite_a\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m,\n\u001b[1;32m 14\u001b[0m check_finite\u001b[39m=\u001b[39m\u001b[39mTrue\u001b[39;00m, lapack_driver\u001b[39m=\u001b[39m\u001b[39m'\u001b[39m\u001b[39mgesdd\u001b[39m\u001b[39m'\u001b[39m):\n\u001b[1;32m 15\u001b[0m \u001b[39m \u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 16\u001b[0m \u001b[39m Singular Value Decomposition.\u001b[39;00m\n\u001b[1;32m 17\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 106\u001b[0m \n\u001b[1;32m 107\u001b[0m \u001b[39m \"\"\"\u001b[39;00m\n\u001b[0;32m--> 108\u001b[0m a1 \u001b[39m=\u001b[39m _asarray_validated(a, check_finite\u001b[39m=\u001b[39;49mcheck_finite)\n\u001b[1;32m 109\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mlen\u001b[39m(a1\u001b[39m.\u001b[39mshape) \u001b[39m!=\u001b[39m \u001b[39m2\u001b[39m:\n\u001b[1;32m 110\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mValueError\u001b[39;00m(\u001b[39m'\u001b[39m\u001b[39mexpected matrix\u001b[39m\u001b[39m'\u001b[39m)\n", + "File \u001b[0;32m~/Library/Caches/pypoetry/virtualenvs/mdopt-ZdbamFdU-py3.11/lib/python3.11/site-packages/scipy/_lib/_util.py:287\u001b[0m, in \u001b[0;36m_asarray_validated\u001b[0;34m(a, check_finite, sparse_ok, objects_ok, mask_ok, as_inexact)\u001b[0m\n\u001b[1;32m 285\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mValueError\u001b[39;00m(\u001b[39m'\u001b[39m\u001b[39mmasked arrays are not supported\u001b[39m\u001b[39m'\u001b[39m)\n\u001b[1;32m 286\u001b[0m toarray \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39masarray_chkfinite \u001b[39mif\u001b[39;00m check_finite \u001b[39melse\u001b[39;00m np\u001b[39m.\u001b[39masarray\n\u001b[0;32m--> 287\u001b[0m a \u001b[39m=\u001b[39m toarray(a)\n\u001b[1;32m 288\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39mnot\u001b[39;00m objects_ok:\n\u001b[1;32m 289\u001b[0m \u001b[39mif\u001b[39;00m a\u001b[39m.\u001b[39mdtype \u001b[39mis\u001b[39;00m np\u001b[39m.\u001b[39mdtype(\u001b[39m'\u001b[39m\u001b[39mO\u001b[39m\u001b[39m'\u001b[39m):\n", + "File \u001b[0;32m~/Library/Caches/pypoetry/virtualenvs/mdopt-ZdbamFdU-py3.11/lib/python3.11/site-packages/numpy/lib/function_base.py:627\u001b[0m, in \u001b[0;36masarray_chkfinite\u001b[0;34m(a, dtype, order)\u001b[0m\n\u001b[1;32m 625\u001b[0m a \u001b[39m=\u001b[39m asarray(a, dtype\u001b[39m=\u001b[39mdtype, order\u001b[39m=\u001b[39morder)\n\u001b[1;32m 626\u001b[0m \u001b[39mif\u001b[39;00m a\u001b[39m.\u001b[39mdtype\u001b[39m.\u001b[39mchar \u001b[39min\u001b[39;00m typecodes[\u001b[39m'\u001b[39m\u001b[39mAllFloat\u001b[39m\u001b[39m'\u001b[39m] \u001b[39mand\u001b[39;00m \u001b[39mnot\u001b[39;00m np\u001b[39m.\u001b[39misfinite(a)\u001b[39m.\u001b[39mall():\n\u001b[0;32m--> 627\u001b[0m \u001b[39mraise\u001b[39;00m \u001b[39mValueError\u001b[39;00m(\n\u001b[1;32m 628\u001b[0m \u001b[39m\"\u001b[39m\u001b[39marray must not contain infs or NaNs\u001b[39m\u001b[39m\"\u001b[39m)\n\u001b[1;32m 629\u001b[0m \u001b[39mreturn\u001b[39;00m a\n", + "\u001b[0;31mValueError\u001b[0m: array must not contain infs or NaNs" + ] + } + ], + "source": [ + "failures_statistics = {}\n", + "failures = []\n", + "\n", + "SEED = 6\n", + "NUM_BITS = 32\n", + "PROB_ERROR = 0.1\n", + "CHECK_DEGREE, BIT_DEGREE = 4, 3\n", + "NUM_CHECKS = int(BIT_DEGREE * NUM_BITS / CHECK_DEGREE)\n", + "if NUM_BITS / NUM_CHECKS != CHECK_DEGREE / BIT_DEGREE:\n", + " raise ValueError(\"The Tanner graph of the code must be bipartite.\")\n", + "\n", + "PROB_BIAS = PROB_ERROR\n", + "\n", + "CHI_MAX_CONTRACTOR = 64\n", + "CHI_MAX_DMRG = 64\n", + "CUT = 1e-12\n", + "NUM_RUNS = 1\n", + "\n", + "code = qec.random_regular_code(\n", + " NUM_BITS, NUM_CHECKS, BIT_DEGREE, CHECK_DEGREE, qec.Rng(SEED)\n", + ")\n", + "code_constraint_sites = linear_code_constraint_sites(code)\n", + "INITIAL_CODEWORD, PERTURBED_CODEWORD = linear_code_prepare_message(\n", + " code, PROB_ERROR, error_model=qec.BinarySymmetricChannel, seed=SEED\n", + ")\n", + "tensors = [XOR_LEFT, XOR_BULK, SWAP, XOR_RIGHT]\n", + "\n", + "initial_codeword_state = create_custom_product_state(\n", + " INITIAL_CODEWORD, form=\"Right-canonical\"\n", + ")\n", + "perturbed_codeword_state = create_custom_product_state(\n", + " PERTURBED_CODEWORD, form=\"Right-canonical\"\n", + ")\n", + "\n", + "perturbed_codeword_state = apply_bitflip_bias(\n", + " mps=perturbed_codeword_state,\n", + " sites_to_bias=\"All\",\n", + " prob_bias_list=PROB_BIAS,\n", + " renormalise=True,\n", + " result_to_explicit=False,\n", + ")\n", + "\n", + "#try:\n", + "perturbed_codeword_state = apply_constraints(\n", + " perturbed_codeword_state,\n", + " code_constraint_sites,\n", + " tensors,\n", + " chi_max=CHI_MAX_CONTRACTOR,\n", + " renormalise=True,\n", + " result_to_explicit=False,\n", + " strategy=\"Naive\",\n", + " silent=True,\n", + ")\n", + "#except:\n", + "# print(SEED, PROB_ERROR, l)\n", + "# pass\n", + "\n", + "#try:\n", + " #dmrg_container, success = decode_linear(\n", + " # message=perturbed_codeword_state,\n", + " # codeword=initial_codeword_state,\n", + " # code=code,\n", + " # num_runs=NUM_RUNS,\n", + " # chi_max_dmrg=CHI_MAX_DMRG,\n", + " # cut=CUT,\n", + " # silent=True,\n", + " #)\n", + "#except:\n", + "# success = 0\n", + "\n", + "#failures.append(1-success)\n", + "\n", + "#failures_statistics[NUM_BITS, PROB_ERROR] = failures" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "metadata": {}, + "outputs": [], + "source": [] + } + ], + "metadata": { + "kernelspec": { + "display_name": "mdopt-ZdbamFdU-py3.11", + "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.11.3" + }, + "orig_nbformat": 4 + }, + "nbformat": 4, + "nbformat_minor": 2 +}