diff --git a/Chapter06/03_graph_similarity.ipynb b/Chapter06/03_graph_similarity.ipynb new file mode 100644 index 0000000..e579160 --- /dev/null +++ b/Chapter06/03_graph_similarity.ipynb @@ -0,0 +1,4105 @@ +{ + "nbformat": 4, + "nbformat_minor": 0, + "metadata": { + "colab": { + "provenance": [] + }, + "kernelspec": { + "name": "python3", + "display_name": "Python 3" + }, + "language_info": { + "name": "python" + }, + "widgets": { + "application/vnd.jupyter.widget-state+json": { + "947a2ce0171c4582843c5afb590471fb": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_f43faf84d7f041b08bcbec1aeeb5297a", + "IPY_MODEL_d3fda1a8024c4f308dc36d2216006a46", + "IPY_MODEL_ebd67e8c91f94cda8c314ff8c387a7d4" + ], + "layout": "IPY_MODEL_4a1994565cd541389bacb618bfb889cc" + } + }, + "f43faf84d7f041b08bcbec1aeeb5297a": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_9b6d7a51282e46409eedb05fa786e629", + "placeholder": "​", + "style": "IPY_MODEL_0a0a68b09ba54987b47fd441d23c8870", + "value": "Computing transition probabilities: 100%" + } + }, + "d3fda1a8024c4f308dc36d2216006a46": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_28ce9bcc08504d7eb458d15b955005a9", + "max": 10, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_a17cd8706d5a4961858297899f996a86", + "value": 10 + } + }, + "ebd67e8c91f94cda8c314ff8c387a7d4": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_93995324744e414b8b88453ea975245f", + "placeholder": "​", + "style": "IPY_MODEL_66779461ba7f42a796d5cced4dbde20d", + "value": " 10/10 [00:00<00:00, 374.66it/s]" + } + }, + "4a1994565cd541389bacb618bfb889cc": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "9b6d7a51282e46409eedb05fa786e629": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "0a0a68b09ba54987b47fd441d23c8870": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "28ce9bcc08504d7eb458d15b955005a9": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "a17cd8706d5a4961858297899f996a86": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "93995324744e414b8b88453ea975245f": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "66779461ba7f42a796d5cced4dbde20d": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "fb23e41eee404e1681c922bfda1f0c68": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_1dbae508a6c44c8380c809c5acb13ddd", + "IPY_MODEL_d57001a6ba65463fb4e2bd4621f34f33", + "IPY_MODEL_d66f73a1b19540448d470371576bca83" + ], + "layout": "IPY_MODEL_51c89c0f6e0e47d18921a58d801b2f63" + } + }, + "1dbae508a6c44c8380c809c5acb13ddd": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_75d57c5cbf274d0ba193c3174436ba59", + "placeholder": "​", + "style": "IPY_MODEL_9b8b3255b71343c9bdc4c9bbf1fec334", + "value": "Computing transition probabilities: 100%" + } + }, + "d57001a6ba65463fb4e2bd4621f34f33": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_23d54b49aeb8431f952e5a4684d306d9", + "max": 10, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_7e69d1332106437d85b83b5eddc77ec5", + "value": 10 + } + }, + "d66f73a1b19540448d470371576bca83": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_8a02cb6a232f49179af3fa323fd7a454", + "placeholder": "​", + "style": "IPY_MODEL_95d14bda117042398d9af86a756a3152", + "value": " 10/10 [00:00<00:00, 176.63it/s]" + } + }, + "51c89c0f6e0e47d18921a58d801b2f63": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "75d57c5cbf274d0ba193c3174436ba59": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "9b8b3255b71343c9bdc4c9bbf1fec334": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "23d54b49aeb8431f952e5a4684d306d9": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7e69d1332106437d85b83b5eddc77ec5": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "8a02cb6a232f49179af3fa323fd7a454": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "95d14bda117042398d9af86a756a3152": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "bd63c7b0c5c040ba9541bd2fcef51758": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_bad3cb7ac7994943a3a582b42278a1f8", + "IPY_MODEL_6dcc66d8f2a445c49350bf22b5ff0294", + "IPY_MODEL_4041adbf739847fd8e94d4b68c82955c" + ], + "layout": "IPY_MODEL_0ec4eb7a45d045bda9ddab55c34b8a32" + } + }, + "bad3cb7ac7994943a3a582b42278a1f8": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_eb3f54e018714fff9354e26b74f1323f", + "placeholder": "​", + "style": "IPY_MODEL_e9a3b4516afb4d8a93cf2a273acf5250", + "value": "Computing transition probabilities: 100%" + } + }, + "6dcc66d8f2a445c49350bf22b5ff0294": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_8b7bde7d326348ada0df55190cb19f40", + "max": 10, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_61fdf65c194e4a109b348f2b06868422", + "value": 10 + } + }, + "4041adbf739847fd8e94d4b68c82955c": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_6e8f4eef4c1240dc988e901039379cc9", + "placeholder": "​", + "style": "IPY_MODEL_a3822e2c9a144b6ba3862242a7d45c11", + "value": " 10/10 [00:00<00:00, 416.03it/s]" + } + }, + "0ec4eb7a45d045bda9ddab55c34b8a32": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "eb3f54e018714fff9354e26b74f1323f": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "e9a3b4516afb4d8a93cf2a273acf5250": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "8b7bde7d326348ada0df55190cb19f40": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "61fdf65c194e4a109b348f2b06868422": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "6e8f4eef4c1240dc988e901039379cc9": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "a3822e2c9a144b6ba3862242a7d45c11": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "e31117d627db40b1a2614fb8d93ea9ff": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_3ad70def5d9a4d4586fb2e68632c67d2", + "IPY_MODEL_679e128edd4d4c649ee0e652349539eb", + "IPY_MODEL_d95a076be82c4ddd9f73b003e5fb2cf3" + ], + "layout": "IPY_MODEL_ab1d862212a0499fa73bdf7dd52113ec" + } + }, + "3ad70def5d9a4d4586fb2e68632c67d2": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_7235a60e23cb4f91aa79997515024da2", + "placeholder": "​", + "style": "IPY_MODEL_884e184fd62d4d2bb599c42c12071d7c", + "value": "Computing transition probabilities: 100%" + } + }, + "679e128edd4d4c649ee0e652349539eb": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_a4009f909cd14d45b383c54bdb0f8b1c", + "max": 10, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_7e4d5719ff144f7bba6ee64fd2da1705", + "value": 10 + } + }, + "d95a076be82c4ddd9f73b003e5fb2cf3": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_07d05bdabf13439e801368d8d71669f4", + "placeholder": "​", + "style": "IPY_MODEL_1ab67407ab29460db2847ad7f406a6ae", + "value": " 10/10 [00:00<00:00, 334.33it/s]" + } + }, + "ab1d862212a0499fa73bdf7dd52113ec": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7235a60e23cb4f91aa79997515024da2": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "884e184fd62d4d2bb599c42c12071d7c": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "a4009f909cd14d45b383c54bdb0f8b1c": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "7e4d5719ff144f7bba6ee64fd2da1705": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "07d05bdabf13439e801368d8d71669f4": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "1ab67407ab29460db2847ad7f406a6ae": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "28827ff18f394b4f96afef0cb2657061": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_5ce2477ccab74444b23e667e050f80d8", + "IPY_MODEL_0d7b0d9bab3841a385a985b631738310", + "IPY_MODEL_1b0cc9b414ec49acaa29a350537eb501" + ], + "layout": "IPY_MODEL_11e55760c4bf4ca7bbbd6c76aed0a639" + } + }, + "5ce2477ccab74444b23e667e050f80d8": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_605dec3cb9e34c6facf1e950c7502f0a", + "placeholder": "​", + "style": "IPY_MODEL_246986c6101148c8ba5f5dbb5d005b27", + "value": "Computing transition probabilities: 100%" + } + }, + "0d7b0d9bab3841a385a985b631738310": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_a49e73b3bdc6400da3903f982bc6d04b", + "max": 10, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_4e875ca7b1d6463a9cac747767578deb", + "value": 10 + } + }, + "1b0cc9b414ec49acaa29a350537eb501": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_21f1ed46aaa141a5bb3b18ffa2c3ec8a", + "placeholder": "​", + "style": "IPY_MODEL_8f85b000d9b047ccb087df6613a300aa", + "value": " 10/10 [00:00<00:00, 309.62it/s]" + } + }, + "11e55760c4bf4ca7bbbd6c76aed0a639": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "605dec3cb9e34c6facf1e950c7502f0a": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "246986c6101148c8ba5f5dbb5d005b27": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "a49e73b3bdc6400da3903f982bc6d04b": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "4e875ca7b1d6463a9cac747767578deb": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "21f1ed46aaa141a5bb3b18ffa2c3ec8a": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "8f85b000d9b047ccb087df6613a300aa": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "1d74ff82049e414187206135c4d343fc": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_2f1f7a3164b6495290f3713e7f16bad3", + "IPY_MODEL_d00413a5520942e9b3781157c8963241", + "IPY_MODEL_aee093ae1ca54185a96300136c291eca" + ], + "layout": "IPY_MODEL_088b6089e6dd4d6981e6725e995b08e6" + } + }, + "2f1f7a3164b6495290f3713e7f16bad3": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_a40370ec8cac44e9b504e76a0b4400ae", + "placeholder": "​", + "style": "IPY_MODEL_62d80c02b0cc4f7a8d9132d7009b5956", + "value": "Computing transition probabilities: 100%" + } + }, + "d00413a5520942e9b3781157c8963241": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_637687ffca774e9aa04b569cb783e868", + "max": 10, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_df3b12fff35a47f396c20810ad255b03", + "value": 10 + } + }, + "aee093ae1ca54185a96300136c291eca": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_716d1e2329654e2890512b5c3fee4b72", + "placeholder": "​", + "style": "IPY_MODEL_600f6222fded403d8774aafda306df9d", + "value": " 10/10 [00:00<00:00, 273.24it/s]" + } + }, + "088b6089e6dd4d6981e6725e995b08e6": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "a40370ec8cac44e9b504e76a0b4400ae": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "62d80c02b0cc4f7a8d9132d7009b5956": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "637687ffca774e9aa04b569cb783e868": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "df3b12fff35a47f396c20810ad255b03": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "716d1e2329654e2890512b5c3fee4b72": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "600f6222fded403d8774aafda306df9d": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "0e6effb2c0bb4b2684885a3fea92a4cf": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_8f47ee7259e347d59e014380683efe82", + "IPY_MODEL_8579f1a93aae40358563cf973b94fdcb", + "IPY_MODEL_5eeeb0ad6ee840f58ea2788a61b23b12" + ], + "layout": "IPY_MODEL_4914e6a968374755ae8f3f33adb0f234" + } + }, + "8f47ee7259e347d59e014380683efe82": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_a59961195bb54dc9aff4361c02bc8de1", + "placeholder": "​", + "style": "IPY_MODEL_d4d97096bd6740e29dc8eb433df5431c", + "value": "Computing transition probabilities: 100%" + } + }, + "8579f1a93aae40358563cf973b94fdcb": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_a9c2475224694ff3bfb80fbe57a1fb28", + "max": 10, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_4018af520be648a5a270a0d87bb16065", + "value": 10 + } + }, + "5eeeb0ad6ee840f58ea2788a61b23b12": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_20458297119b4d80bb0d8792b4e53cb3", + "placeholder": "​", + "style": "IPY_MODEL_25385bed8021400f9719895ee82ab0dd", + "value": " 10/10 [00:00<00:00, 300.49it/s]" + } + }, + "4914e6a968374755ae8f3f33adb0f234": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "a59961195bb54dc9aff4361c02bc8de1": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "d4d97096bd6740e29dc8eb433df5431c": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "a9c2475224694ff3bfb80fbe57a1fb28": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "4018af520be648a5a270a0d87bb16065": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "20458297119b4d80bb0d8792b4e53cb3": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "25385bed8021400f9719895ee82ab0dd": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "2b43715603bd456182172b2fbf76cdd7": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_52bb5e354ffd4c9187a6db8abb000b6a", + "IPY_MODEL_c0203eaa5aa3411386ca3fcd7928cb0e", + "IPY_MODEL_4b77514afd0a4c7793b2669080c4d536" + ], + "layout": "IPY_MODEL_473123bbd1ab4876b12afb4949a95502" + } + }, + "52bb5e354ffd4c9187a6db8abb000b6a": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_5dadb931453647159eda4a23ccfb48ff", + "placeholder": "​", + "style": "IPY_MODEL_3dc24387c3f04141a3eabc46c05182a0", + "value": "Computing transition probabilities: 100%" + } + }, + "c0203eaa5aa3411386ca3fcd7928cb0e": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_4752f3e2381d4cedaaaa84b5398fd8fc", + "max": 10, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_73ea01915aed40679bc760f21050398f", + "value": 10 + } + }, + "4b77514afd0a4c7793b2669080c4d536": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_45212dc9ec004f3386d619affb7a9fd3", + "placeholder": "​", + "style": "IPY_MODEL_a125c58f4ded4590abb54d38f7e43f61", + "value": " 10/10 [00:00<00:00, 330.65it/s]" + } + }, + "473123bbd1ab4876b12afb4949a95502": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "5dadb931453647159eda4a23ccfb48ff": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "3dc24387c3f04141a3eabc46c05182a0": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "4752f3e2381d4cedaaaa84b5398fd8fc": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "73ea01915aed40679bc760f21050398f": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "45212dc9ec004f3386d619affb7a9fd3": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "a125c58f4ded4590abb54d38f7e43f61": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "cc1306eca0264b13a51fbe2cf7e4892e": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_f158f5017b6e4d0eb810687dd261d674", + "IPY_MODEL_6b60df7692be4c3483739ffd44ea9330", + "IPY_MODEL_a615098947e44dea94da81b8e6e713d2" + ], + "layout": "IPY_MODEL_406b57f23f7148f5aa613ad9bf6583e2" + } + }, + "f158f5017b6e4d0eb810687dd261d674": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_4de9ab2c41e241c7a7f6727ab4a5da82", + "placeholder": "​", + "style": "IPY_MODEL_ffd2871c1de341d1a06bd376cc984506", + "value": "Computing transition probabilities: 100%" + } + }, + "6b60df7692be4c3483739ffd44ea9330": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_04e18937beda476e9fb939e3fc3e908d", + "max": 10, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_5a00cc7519634a35911849774d063cfe", + "value": 10 + } + }, + "a615098947e44dea94da81b8e6e713d2": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_9d5919e531dd41b2a39fde1d852f6315", + "placeholder": "​", + "style": "IPY_MODEL_078cfe33751445ca9b4386f9d1c60985", + "value": " 10/10 [00:00<00:00, 283.02it/s]" + } + }, + "406b57f23f7148f5aa613ad9bf6583e2": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "4de9ab2c41e241c7a7f6727ab4a5da82": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "ffd2871c1de341d1a06bd376cc984506": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "04e18937beda476e9fb939e3fc3e908d": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "5a00cc7519634a35911849774d063cfe": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "9d5919e531dd41b2a39fde1d852f6315": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "078cfe33751445ca9b4386f9d1c60985": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "303291d220a948e2a61bcfed9b793b41": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HBoxModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HBoxModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HBoxView", + "box_style": "", + "children": [ + "IPY_MODEL_5a94a608304c479a972772c72096abf0", + "IPY_MODEL_22f2b4423b2748b8ba2c5dbde91edb1d", + "IPY_MODEL_598ed931496c4cf4bcfcb036424aa54a" + ], + "layout": "IPY_MODEL_c3e6a0769acb4f04942dbf041f6630d6" + } + }, + "5a94a608304c479a972772c72096abf0": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_978825cc0ef54d0da29e1d7984c42e1a", + "placeholder": "​", + "style": "IPY_MODEL_72e1f1437f984212a3a24e28efb657ef", + "value": "Computing transition probabilities: 100%" + } + }, + "22f2b4423b2748b8ba2c5dbde91edb1d": { + "model_module": "@jupyter-widgets/controls", + "model_name": "FloatProgressModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "FloatProgressModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "ProgressView", + "bar_style": "success", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_90b65155158649888da232b24cb1cf2e", + "max": 10, + "min": 0, + "orientation": "horizontal", + "style": "IPY_MODEL_1766dd5e4f7747d2af886ea4d8bf461b", + "value": 10 + } + }, + "598ed931496c4cf4bcfcb036424aa54a": { + "model_module": "@jupyter-widgets/controls", + "model_name": "HTMLModel", + "model_module_version": "1.5.0", + "state": { + "_dom_classes": [], + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "HTMLModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/controls", + "_view_module_version": "1.5.0", + "_view_name": "HTMLView", + "description": "", + "description_tooltip": null, + "layout": "IPY_MODEL_5c7eb0f86cde44feb6d76ab2dbff30cd", + "placeholder": "​", + "style": "IPY_MODEL_b2605b2db94b4b929a9f7c927fdf88f5", + "value": " 10/10 [00:00<00:00, 339.73it/s]" + } + }, + "c3e6a0769acb4f04942dbf041f6630d6": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "978825cc0ef54d0da29e1d7984c42e1a": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "72e1f1437f984212a3a24e28efb657ef": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + }, + "90b65155158649888da232b24cb1cf2e": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "1766dd5e4f7747d2af886ea4d8bf461b": { + "model_module": "@jupyter-widgets/controls", + "model_name": "ProgressStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "ProgressStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "bar_color": null, + "description_width": "" + } + }, + "5c7eb0f86cde44feb6d76ab2dbff30cd": { + "model_module": "@jupyter-widgets/base", + "model_name": "LayoutModel", + "model_module_version": "1.2.0", + "state": { + "_model_module": "@jupyter-widgets/base", + "_model_module_version": "1.2.0", + "_model_name": "LayoutModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "LayoutView", + "align_content": null, + "align_items": null, + "align_self": null, + "border": null, + "bottom": null, + "display": null, + "flex": null, + "flex_flow": null, + "grid_area": null, + "grid_auto_columns": null, + "grid_auto_flow": null, + "grid_auto_rows": null, + "grid_column": null, + "grid_gap": null, + "grid_row": null, + "grid_template_areas": null, + "grid_template_columns": null, + "grid_template_rows": null, + "height": null, + "justify_content": null, + "justify_items": null, + "left": null, + "margin": null, + "max_height": null, + "max_width": null, + "min_height": null, + "min_width": null, + "object_fit": null, + "object_position": null, + "order": null, + "overflow": null, + "overflow_x": null, + "overflow_y": null, + "padding": null, + "right": null, + "top": null, + "visibility": null, + "width": null + } + }, + "b2605b2db94b4b929a9f7c927fdf88f5": { + "model_module": "@jupyter-widgets/controls", + "model_name": "DescriptionStyleModel", + "model_module_version": "1.5.0", + "state": { + "_model_module": "@jupyter-widgets/controls", + "_model_module_version": "1.5.0", + "_model_name": "DescriptionStyleModel", + "_view_count": null, + "_view_module": "@jupyter-widgets/base", + "_view_module_version": "1.2.0", + "_view_name": "StyleView", + "description_width": "" + } + } + } + } + }, + "cells": [ + { + "cell_type": "code", + "execution_count": 3, + "metadata": { + "id": "9LbvNo43_S8s" + }, + "outputs": [], + "source": [ + "%%capture\n", + "# install PyTorch Geometric if running on Google Colab\n", + "import sys\n", + "if 'google.colab' in sys.modules:\n", + " !pip install node2vec\n", + " import torch\n", + "\n", + " def format_pytorch_version(version):\n", + " return version.split('+')[0]\n", + "\n", + " TORCH_version = torch.__version__\n", + " TORCH = format_pytorch_version(TORCH_version)\n", + "\n", + " def format_cuda_version(version):\n", + " return 'cu' + version.replace('.', '')\n", + "\n", + " CUDA_version = torch.version.cuda\n", + " CUDA = format_cuda_version(CUDA_version)\n", + "\n", + " !pip install torch-scatter -f https://pytorch-geometric.com/whl/torch-{TORCH}+{CUDA}.html\n", + " !pip install torch-sparse -f https://pytorch-geometric.com/whl/torch-{TORCH}+{CUDA}.html\n", + " !pip install torch-cluster -f https://pytorch-geometric.com/whl/torch-{TORCH}+{CUDA}.html\n", + " !pip install torch-spline-conv -f https://pytorch-geometric.com/whl/torch-{TORCH}+{CUDA}.html\n", + " !pip install torch-geometric" + ] + }, + { + "cell_type": "markdown", + "source": [ + "## Graph embedding-based methods\n", + "\n", + "Such techniques seek to apply graph embedding techniques to obtain node-level or graph-level representations and further use the representations for similarity learning. For example, DeepWalk and Node2Vec can be used to extract meaningful embedding that can then be used to define a similarity function or to predict similarity scores. For example, in Tixier et al. (2015), node2vec was used for encoding node embeddings for representing a graph as an image. Specifically, two-dimensional (2D) histograms obtained from those node embeddings were passed to a classical 2D convolutional neural network (CNN) architecture designed for images. Such a simple yet powerful approach enabled good results to be obtained for many benchmark datasets." + ], + "metadata": { + "id": "BIK1pgU4_lWd" + } + }, + { + "cell_type": "code", + "source": [ + "# Method 1: Graph Embedding-based (Node2Vec)\n", + "import networkx as nx\n", + "import numpy as np\n", + "from sklearn.model_selection import train_test_split\n", + "from sklearn.metrics import accuracy_score\n", + "#from sklearn.preprocessing import LabelEncoder\n", + "\n", + "# Load necessary libraries for each method\n", + "from node2vec import Node2Vec\n", + "import torch\n", + "import torch.nn as nn\n", + "import torch.optim as optim\n", + "\n", + "# Create toy dataset with simple graphs\n", + "num_graphs = 10\n", + "graphs = [nx.erdos_renyi_graph(10, np.random.rand()) for _ in range(num_graphs)]\n", + "\n", + "# Labels for graph similarity task (could be used for graph classification or regression)\n", + "labels = [np.random.choice([0,1]) for _ in range(num_graphs)]\n", + "\n", + "# Function to generate 2D histogram from node embeddings\n", + "def generate_2d_histogram(node_embeddings, bins=16):\n", + " # Flatten embeddings to create histograms\n", + " embeddings = np.vstack(node_embeddings)\n", + " histogram, xedges, yedges = np.histogram2d(embeddings[:, 0], embeddings[:, 1], bins=bins)\n", + " return histogram\n", + "\n", + "# Prepare graph-level 2D histograms from node embeddings\n", + "graph_histograms = []\n", + "for i, graph in enumerate(graphs):\n", + " node2vec = Node2Vec(graph, dimensions=64, walk_length=10, num_walks=80, workers=4)\n", + " model = node2vec.fit()\n", + " node_embeddings = [model.wv.get_vector(str(node)) for node in graph.nodes()]\n", + " histogram = generate_2d_histogram(node_embeddings)\n", + " graph_histograms.append(histogram)\n", + "\n", + "# Convert histograms into tensors for CNN\n", + "graph_histograms = np.array(graph_histograms)\n", + "graph_histograms = torch.tensor(graph_histograms, dtype=torch.float32)\n", + "\n", + "# Split histograms into training and testing sets\n", + "train_histograms, test_histograms, train_labels, test_labels = train_test_split(graph_histograms, labels, test_size=0.5, random_state=42)\n", + "\n", + "# Define a simple 2D CNN model for graph classification\n", + "class GraphCNN(nn.Module):\n", + " def __init__(self, input_channels, num_classes):\n", + " super(GraphCNN, self).__init__()\n", + " self.conv1 = nn.Conv2d(input_channels, 32, kernel_size=3, stride=1, padding=1)\n", + " self.pool = nn.MaxPool2d(2, 2)\n", + " self.conv2 = nn.Conv2d(32, 64, kernel_size=3, stride=1, padding=1)\n", + " self.fc1 = nn.Linear(1024, 128)\n", + " self.fc2 = nn.Linear(128, num_classes)\n", + " self.relu = nn.ReLU()\n", + " self.dropout = nn.Dropout(0.5)\n", + "\n", + " def forward(self, x):\n", + " x = self.relu(self.conv1(x))\n", + " x = self.pool(x)\n", + " x = self.relu(self.conv2(x))\n", + " x = self.pool(x)\n", + " x = x.view(5, -1)\n", + " x = self.relu(self.fc1(x))\n", + " x = self.dropout(x)\n", + " x = self.fc2(x)\n", + " return x\n", + "\n", + "# Initialize and train the CNN model\n", + "num_classes = 2 # Binary classification\n", + "input_channels = 1 # Single channel for histogram\n", + "bins = 16 # Same as used in generate_2d_histogram function\n", + "\n", + "train_histograms = train_histograms.unsqueeze(1) # Add channel dimension\n", + "test_histograms = test_histograms.unsqueeze(1)\n", + "\n", + "cnn_model = GraphCNN(input_channels, num_classes)\n", + "criterion = nn.CrossEntropyLoss()\n", + "optimizer = optim.Adam(cnn_model.parameters(), lr=0.001)\n", + "\n", + "# Training loop\n", + "cnn_model.train()\n", + "epochs = 20\n", + "for epoch in range(epochs):\n", + " optimizer.zero_grad()\n", + " outputs = cnn_model(train_histograms)\n", + " loss = criterion(outputs, torch.tensor(train_labels, dtype=torch.long))\n", + " loss.backward()\n", + " optimizer.step()\n", + " print(f\"Epoch {epoch+1}/{epochs}, Loss: {loss.item()}\")\n", + "\n", + "# Evaluate on test set\n", + "cnn_model.eval()\n", + "with torch.no_grad():\n", + " test_outputs = cnn_model(test_histograms)\n", + " predictions = torch.argmax(test_outputs, axis=1)\n", + " accuracy = accuracy_score(test_labels, predictions.numpy())\n", + " print(f\"Test Accuracy: {accuracy}\")" + ], + "metadata": { + "id": "2-3ku6QR_ZWa", + "colab": { + "base_uri": "https://localhost:8080/", + "height": 701, + "referenced_widgets": [ + "947a2ce0171c4582843c5afb590471fb", + "f43faf84d7f041b08bcbec1aeeb5297a", + "d3fda1a8024c4f308dc36d2216006a46", + "ebd67e8c91f94cda8c314ff8c387a7d4", + "4a1994565cd541389bacb618bfb889cc", + "9b6d7a51282e46409eedb05fa786e629", + "0a0a68b09ba54987b47fd441d23c8870", + "28ce9bcc08504d7eb458d15b955005a9", + "a17cd8706d5a4961858297899f996a86", + "93995324744e414b8b88453ea975245f", + "66779461ba7f42a796d5cced4dbde20d", + "fb23e41eee404e1681c922bfda1f0c68", + "1dbae508a6c44c8380c809c5acb13ddd", + "d57001a6ba65463fb4e2bd4621f34f33", + "d66f73a1b19540448d470371576bca83", + "51c89c0f6e0e47d18921a58d801b2f63", + "75d57c5cbf274d0ba193c3174436ba59", + "9b8b3255b71343c9bdc4c9bbf1fec334", + "23d54b49aeb8431f952e5a4684d306d9", + "7e69d1332106437d85b83b5eddc77ec5", + "8a02cb6a232f49179af3fa323fd7a454", + "95d14bda117042398d9af86a756a3152", + "bd63c7b0c5c040ba9541bd2fcef51758", + "bad3cb7ac7994943a3a582b42278a1f8", + "6dcc66d8f2a445c49350bf22b5ff0294", + "4041adbf739847fd8e94d4b68c82955c", + "0ec4eb7a45d045bda9ddab55c34b8a32", + "eb3f54e018714fff9354e26b74f1323f", + "e9a3b4516afb4d8a93cf2a273acf5250", + "8b7bde7d326348ada0df55190cb19f40", + "61fdf65c194e4a109b348f2b06868422", + "6e8f4eef4c1240dc988e901039379cc9", + "a3822e2c9a144b6ba3862242a7d45c11", + "e31117d627db40b1a2614fb8d93ea9ff", + "3ad70def5d9a4d4586fb2e68632c67d2", + "679e128edd4d4c649ee0e652349539eb", + "d95a076be82c4ddd9f73b003e5fb2cf3", + "ab1d862212a0499fa73bdf7dd52113ec", + "7235a60e23cb4f91aa79997515024da2", + "884e184fd62d4d2bb599c42c12071d7c", + "a4009f909cd14d45b383c54bdb0f8b1c", + "7e4d5719ff144f7bba6ee64fd2da1705", + "07d05bdabf13439e801368d8d71669f4", + "1ab67407ab29460db2847ad7f406a6ae", + "28827ff18f394b4f96afef0cb2657061", + "5ce2477ccab74444b23e667e050f80d8", + "0d7b0d9bab3841a385a985b631738310", + "1b0cc9b414ec49acaa29a350537eb501", + "11e55760c4bf4ca7bbbd6c76aed0a639", + "605dec3cb9e34c6facf1e950c7502f0a", + "246986c6101148c8ba5f5dbb5d005b27", + "a49e73b3bdc6400da3903f982bc6d04b", + "4e875ca7b1d6463a9cac747767578deb", + "21f1ed46aaa141a5bb3b18ffa2c3ec8a", + "8f85b000d9b047ccb087df6613a300aa", + "1d74ff82049e414187206135c4d343fc", + "2f1f7a3164b6495290f3713e7f16bad3", + "d00413a5520942e9b3781157c8963241", + "aee093ae1ca54185a96300136c291eca", + "088b6089e6dd4d6981e6725e995b08e6", + "a40370ec8cac44e9b504e76a0b4400ae", + "62d80c02b0cc4f7a8d9132d7009b5956", + "637687ffca774e9aa04b569cb783e868", + "df3b12fff35a47f396c20810ad255b03", + "716d1e2329654e2890512b5c3fee4b72", + "600f6222fded403d8774aafda306df9d", + "0e6effb2c0bb4b2684885a3fea92a4cf", + "8f47ee7259e347d59e014380683efe82", + "8579f1a93aae40358563cf973b94fdcb", + "5eeeb0ad6ee840f58ea2788a61b23b12", + "4914e6a968374755ae8f3f33adb0f234", + "a59961195bb54dc9aff4361c02bc8de1", + "d4d97096bd6740e29dc8eb433df5431c", + "a9c2475224694ff3bfb80fbe57a1fb28", + "4018af520be648a5a270a0d87bb16065", + "20458297119b4d80bb0d8792b4e53cb3", + "25385bed8021400f9719895ee82ab0dd", + "2b43715603bd456182172b2fbf76cdd7", + "52bb5e354ffd4c9187a6db8abb000b6a", + "c0203eaa5aa3411386ca3fcd7928cb0e", + "4b77514afd0a4c7793b2669080c4d536", + "473123bbd1ab4876b12afb4949a95502", + "5dadb931453647159eda4a23ccfb48ff", + "3dc24387c3f04141a3eabc46c05182a0", + "4752f3e2381d4cedaaaa84b5398fd8fc", + "73ea01915aed40679bc760f21050398f", + "45212dc9ec004f3386d619affb7a9fd3", + "a125c58f4ded4590abb54d38f7e43f61", + "cc1306eca0264b13a51fbe2cf7e4892e", + "f158f5017b6e4d0eb810687dd261d674", + "6b60df7692be4c3483739ffd44ea9330", + "a615098947e44dea94da81b8e6e713d2", + "406b57f23f7148f5aa613ad9bf6583e2", + "4de9ab2c41e241c7a7f6727ab4a5da82", + "ffd2871c1de341d1a06bd376cc984506", + "04e18937beda476e9fb939e3fc3e908d", + "5a00cc7519634a35911849774d063cfe", + "9d5919e531dd41b2a39fde1d852f6315", + "078cfe33751445ca9b4386f9d1c60985", + "303291d220a948e2a61bcfed9b793b41", + "5a94a608304c479a972772c72096abf0", + "22f2b4423b2748b8ba2c5dbde91edb1d", + "598ed931496c4cf4bcfcb036424aa54a", + "c3e6a0769acb4f04942dbf041f6630d6", + "978825cc0ef54d0da29e1d7984c42e1a", + "72e1f1437f984212a3a24e28efb657ef", + "90b65155158649888da232b24cb1cf2e", + "1766dd5e4f7747d2af886ea4d8bf461b", + "5c7eb0f86cde44feb6d76ab2dbff30cd", + "b2605b2db94b4b929a9f7c927fdf88f5" + ] + }, + "outputId": "0d861fe0-e3f8-47e1-8a8b-cc7d1d061ff4" + }, + "execution_count": 4, + "outputs": [ + { + "output_type": "display_data", + "data": { + "text/plain": [ + "Computing transition probabilities: 0%| | 0/10 [00:00:16: UserWarning: No data for colormapping provided via 'c'. Parameters 'cmap' will be ignored\n", + " scatter = plt.scatter(x_t[:, 0], x_t[:, 1], c=y, cmap=\"jet\", alpha=alpha)\n" + ] + }, + { + "output_type": "display_data", + "data": { + "text/plain": [ + "
" + ], + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAlAAAAJdCAYAAAD9fEmbAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjguMCwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy81sbWrAAAACXBIWXMAAA9hAAAPYQGoP6dpAABos0lEQVR4nO3deXxU9dn///csyUy2GRJMhAiGVUGogli4xX2lFLXaFq3aCrZ1t6h4a6VWAStSxarf2opL7yp411btovevaitVW6tYtSBWENyQoCBrYIYkZLLM+f2BM2aSSTKTzJk558zr+Xjw0MxMcj6zX+f6XJ/r4zIMwxAAAABS5s71AAAAAOyGAAoAACBNBFAAAABpIoACAABIEwEUAABAmgigAAAA0kQABQAAkCYCKAAAgDQRQAEAAKSJAAqWNXPmTA0ZMiTXw0g6DpfLpXnz5mV9LLk6bjrefPNNTZ48WSUlJXK5XFq1alWuh2Q7Vnntx/z973+Xy+XS3//+91wPJW3HH3+8xo4dm5Vjpfr+nDdvnlwuV8JlQ4YM0cyZM80ZGExBAGUjLpcrpX+xD7nt27frqquu0qhRo1RUVKSqqipNnDhRP/zhD1VfXx//uzNnzpTL5dKhhx6qZDv7uFwuXXnllfGfN2zY0O3xf/rTn5r+WDjZs88+a/kgqSstLS2aPn266urqdPfdd+vRRx9VTU1N0tu+++67mjdvnjZs2JDdQQJABnhzPQCk7tFHH034eenSpVq2bFmny0ePHq26ujodccQRCofD+u53v6tRo0Zp586d+s9//qPFixfrsssuU2lpacLvvfPOO/rjH/+ob3zjGymN59xzz9VXv/rVTpePHz8+zXuW3EMPPaRoNJqRv5Vpe/fulddrztvn2Wef1S9/+cukQZSZx82Ejz76SLW1tXrooYf0/e9/v9vbvvvuu5o/f76OP/54S2VbgFx477335HaT07AT634So5Nvf/vbCT//61//0rJlyzpdLkmLFi3Sxo0b9eqrr2ry5MkJ14XDYRUWFiZcVlRUpMGDB+uWW27R17/+9U7p5WQOP/zwpMfOlIKCAtP+dl/5/f68Om6qtm3bJknq169fbgdiMY2NjSouLs71MGBhPp8v10NAmgh3Heqjjz6Sx+PRf/3Xf3W6LhAIdPoidrvd+vGPf6z//Oc/+tOf/mTauO688065XC7V1tZ2um7OnDkqLCzUrl27JCWvA/nd736nCRMmqKysTIFAQF/60pf0//7f/4tfn6y2QJIeeeQRuVyuhOmip59+WtOmTVN1dbV8Pp+GDx+un/zkJ2pra+vxfnSsddizZ4+uvvpqDRkyRD6fT1VVVTrllFO0cuXK+G3++c9/avr06TrwwAPl8/k0ePBgXXPNNdq7d2/8NjNnztQvf/nL+DFi/7o6riS99dZbmjp1qgKBgEpLS3XSSSfpX//6V9L7/+qrr2r27NmqrKxUSUmJzjrrLG3fvr3H+ytJL774oo455hiVlJSoX79++trXvqa1a9cmjP24446TJE2fPl0ul0vHH3980r/1yCOPaPr06ZKkE044odP0syQ999xz8eOVlZVp2rRpWrNmTcLfmTlzpkpLS7Vx40addtppKi0t1QEHHBB/DN955x2deOKJKikpUU1NjR577LGkj8vLL7+sSy65RP3791cgENAFF1wQfx22d99992nMmDHy+Xyqrq7WFVdcod27dyfcJlZzs2LFCh177LEqLi7Wj370I0l9e80lM2TIEJ122ml65ZVXNHHiRPn9fg0bNkxLly7tdNv169dr+vTpqqioUHFxsf7rv/5LzzzzTKfbffrppzrzzDNVUlKiqqoqXXPNNYpEIkmP//rrr+srX/mKgsGgiouLddxxx+nVV19NaeyRSERz587ViBEj4u+H66+/vtOxYiUETz75pA455BAVFRXpyCOP1DvvvCNJeuCBBzRixAj5/X4df/zxXU4Jr1ixQpMnT1ZRUZGGDh2q+++/v9djikQiuuaaa1RZWamysjKdccYZ+vTTT5Me95VXXtGXv/xl+f1+DR8+XA888EDS23WsgUrnPRuNRjVv3jxVV1eruLhYJ5xwgt59991Of7OlpUXz58/XyJEj5ff71b9/fx199NFatmxZ0jGhe2SgHKqmpkZtbW169NFHNWPGjJR+57zzztNPfvIT3XLLLTrrrLN6zEI1NjZqx44dnS7v169fl9NMZ599tq6//no98cQTuu666xKue+KJJ3TqqaeqvLw86e8uW7ZM5557rk466STdfvvtkqS1a9fq1Vdf1VVXXZXKXUzwyCOPqLS0VLNnz1ZpaalefPFF3XzzzQqHw1q0aFFaf+vSSy/V73//e1155ZU65JBDtHPnTr3yyitau3atDj/8cEnSk08+qcbGRl122WXq37+/3njjDd1777369NNP9eSTT0qSLrnkEm3evDnp1Gwya9as0THHHKNAIKDrr79eBQUFeuCBB3T88cfrH//4hyZNmpRw+x/84AcqLy/X3LlztWHDBt1zzz268sor9fjjj3d7nL/97W+aOnWqhg0bpnnz5mnv3r269957ddRRR2nlypUaMmSILrnkEh1wwAG67bbbNGvWLH35y1/W/vvvn/TvHXvssZo1a5Z+/vOf60c/+pFGjx4tSfH/xl63U6ZM0e23367GxkYtXrxYRx99tN56662EwLqtrU1Tp07VscceqzvuuEO/+c1vdOWVV6qkpEQ33nijzj//fH3961/X/fffrwsuuEBHHnmkhg4dmjCeK6+8Uv369dO8efP03nvvafHixaqtrY0XT0v7gvP58+fr5JNP1mWXXRa/3ZtvvqlXX301IWO6c+dOTZ06Vd/61rf07W9/O/44ZPI1F/Phhx/qm9/8pr73ve9pxowZ+vWvf62ZM2dqwoQJGjNmjCRp69atmjx5shobGzVr1iz1799fS5Ys0RlnnKHf//73OuussyTtmyI+6aSTtHHjRs2aNUvV1dV69NFH9eKLL3Y67osvvqipU6dqwoQJmjt3rtxutx5++GGdeOKJ+uc//6mJEyd2OeZoNKozzjhDr7zyii6++GKNHj1a77zzju6++269//77euqppxJu/89//lP/93//pyuuuEKStHDhQp122mm6/vrrdd999+nyyy/Xrl27dMcdd+i73/1up/Hu2rVLX/3qV3X22Wfr3HPP1RNPPKHLLrtMhYWF+u53v5v2mL7//e/rf//3f3Xeeedp8uTJevHFFzVt2rRO9/Odd97RqaeeqsrKSs2bN0+tra2aO3dul++LZFJ5z86ZM0d33HGHTj/9dE2ZMkVvv/22pkyZoqampoS/NW/ePC1cuFDf//73NXHiRIXDYf373//WypUrdcopp6Q8JnzOgG1dccUVRldP4ZYtW4zKykpDkjFq1Cjj0ksvNR577DFj9+7dnW47Y8YMo6SkxDAMw1iyZIkhyfjjH/8Yv16SccUVV8R//vjjjw1JXf577bXXuh33kUceaUyYMCHhsjfeeMOQZCxdujRhXDU1NfGfr7rqKiMQCBitra1d/u25c+cmfUwefvhhQ5Lx8ccfxy9rbGzsdLtLLrnEKC4uNpqamroch2Hs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\n" + }, + "metadata": {} + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "You may want to use these embeddings for downstream tasks such as link prediction! To this aim, you can split the dataset in order to create \"future\" link examples. Check [the stellargraph repo](https://colab.research.google.com/github/stellargraph/stellargraph/blob/master/demos/link-prediction/ctdne-link-prediction.ipynb#scrollTo=I2Vw-NfmeMU5) for a full example" + ], + "metadata": { + "id": "dXukSMRqCcct" + } + }, + { + "cell_type": "markdown", + "source": [ + "## Temporal Graph Neural Network\n", + "In this example, we will explore the implementation of Temporal Graph Networks (TGN) using PyTorch Geometric (PyG). TGNs are designed to handle dynamic graphs where interactions between nodes occur at different timestamps. We'll use the Wikipedia dataset from JODIE, where nodes represent users and articles, and edges represent user-article interactions." + ], + "metadata": { + "id": "_SBxlsmfUkMx" + } + }, + { + "cell_type": "code", + "source": [ + "%%capture\n", + "# install PyTorch Geometric if running on Google Colab\n", + "import sys\n", + "if 'google.colab' in sys.modules:\n", + " import torch\n", + "\n", + " def format_pytorch_version(version):\n", + " return version.split('+')[0]\n", + "\n", + " TORCH_version = torch.__version__\n", + " TORCH = format_pytorch_version(TORCH_version)\n", + "\n", + " def format_cuda_version(version):\n", + " return 'cu' + version.replace('.', '')\n", + "\n", + " CUDA_version = torch.version.cuda\n", + " CUDA = format_cuda_version(CUDA_version)\n", + "\n", + " !pip install torch-scatter -f https://pytorch-geometric.com/whl/torch-{TORCH}+{CUDA}.html\n", + " !pip install torch-sparse -f https://pytorch-geometric.com/whl/torch-{TORCH}+{CUDA}.html\n", + " !pip install torch-cluster -f https://pytorch-geometric.com/whl/torch-{TORCH}+{CUDA}.html\n", + " !pip install torch-spline-conv -f https://pytorch-geometric.com/whl/torch-{TORCH}+{CUDA}.html\n", + " !pip install torch-geometric" + ], + "metadata": { + "id": "plWKrZwaQeRY" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "First, let's set up our environment and load the data.\n", + "We use the JODIE Wikipedia dataset, which contains temporal interactions between users and articles.\n", + "\n", + "The `TemporalDataLoader` is specially designed for temporal graphs. The `neg_sampling_ratio=1.0` means for each positive edge, we sample one negative edge for training." + ], + "metadata": { + "id": "VhcWnVDsVAOn" + } + }, + { + "cell_type": "code", + "source": [ + "# Setup and Data Loading\n", + "import os.path as osp\n", + "import torch\n", + "from sklearn.metrics import average_precision_score, roc_auc_score\n", + "from torch.nn import Linear\n", + "from torch_geometric.datasets import JODIEDataset\n", + "from torch_geometric.loader import TemporalDataLoader\n", + "\n", + "# Device configuration\n", + "device = torch.device('cuda' if torch.cuda.is_available() else 'cpu')\n", + "\n", + "# Load Wikipedia dataset from JODIE\n", + "path = osp.join('data', 'JODIE')\n", + "dataset = JODIEDataset(path, name='wikipedia')\n", + "data = dataset[0]\n", + "data = data.to(device) # Move data to GPU if available\n", + "\n", + "# Split dataset into train, validation, and test sets\n", + "train_data, val_data, test_data = data.train_val_test_split(\n", + " val_ratio=0.15, test_ratio=0.15)\n", + "\n", + "# Create data loaders with negative sampling\n", + "train_loader = TemporalDataLoader(\n", + " train_data,\n", + " batch_size=200,\n", + " neg_sampling_ratio=1.0,\n", + ")\n", + "\n", + "val_loader = TemporalDataLoader(\n", + " val_data,\n", + " batch_size=200,\n", + " neg_sampling_ratio=1.0,\n", + ")\n", + "\n", + "test_loader = TemporalDataLoader(\n", + " test_data,\n", + " batch_size=200,\n", + " neg_sampling_ratio=1.0,\n", + ")\n", + "\n", + "neighbor_loader = LastNeighborLoader(data.num_nodes, size=10, device=device)" + ], + "metadata": { + "id": "WylvEgEsUPEK" + }, + "execution_count": 33, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Let's now proceed implementing the key components of TGN.\n", + "* The memory module is a key component of TGN that maintains node states over time" + ], + "metadata": { + "id": "x3JPyEy3VPOn" + } + }, + { + "cell_type": "code", + "source": [ + "from torch_geometric.nn import TGNMemory, TransformerConv\n", + "from torch_geometric.nn.models.tgn import (\n", + " IdentityMessage,\n", + " LastAggregator,\n", + " LastNeighborLoader,\n", + ")\n", + "\n", + "memory_dim = 100\n", + "time_dim = 100\n", + "embedding_dim = 100\n", + "\n", + "memory = TGNMemory(\n", + " data.num_nodes, # Number of nodes in the graph\n", + " data.msg.size(-1), # Message dimension\n", + " memory_dim, # Memory dimension\n", + " time_dim, # Time encoding dimension\n", + " message_module=IdentityMessage(data.msg.size(-1), memory_dim, time_dim),\n", + " aggregator_module=LastAggregator(),\n", + ").to(device)" + ], + "metadata": { + "id": "sX2UdSRFVb8Y" + }, + "execution_count": 35, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "* Together with the `TGNMemory`, we will also create a GNN for obtaining the embeddings. In this example, we will define a `GraphAttentionEmbedding` class, which uses the `TransformerConv` module (a message passing module implemented in PyTorch)." + ], + "metadata": { + "id": "b-paMXo2VqOq" + } + }, + { + "cell_type": "code", + "source": [ + "class GraphAttentionEmbedding(torch.nn.Module):\n", + " def __init__(self, in_channels, out_channels, msg_dim, time_enc):\n", + " super().__init__()\n", + " self.time_enc = time_enc\n", + " edge_dim = msg_dim + time_enc.out_channels\n", + " self.conv = TransformerConv(in_channels, out_channels // 2, heads=2,\n", + " dropout=0.1, edge_dim=edge_dim)\n", + "\n", + " def forward(self, x, last_update, edge_index, t, msg):\n", + " # Compute relative temporal encoding\n", + " rel_t = last_update[edge_index[0]] - t\n", + " rel_t_enc = self.time_enc(rel_t.to(x.dtype))\n", + " # Concatenate temporal and message features\n", + " edge_attr = torch.cat([rel_t_enc, msg], dim=-1)\n", + " return self.conv(x, edge_index, edge_attr)\n", + "\n", + "# Create the GNN\n", + "gnn = GraphAttentionEmbedding(\n", + " in_channels=memory_dim,\n", + " out_channels=embedding_dim,\n", + " msg_dim=data.msg.size(-1),\n", + " time_enc=memory.time_enc,\n", + ").to(device)" + ], + "metadata": { + "id": "x_MgWFMZVusK" + }, + "execution_count": 36, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "The GraphAttentionEmbedding uses a transformer-based graph convolution that:\n", + "1. Encodes temporal information using relative timestamps\n", + "2. Combines temporal encodings with edge messages\n", + "3. Applies multi-head attention to compute node embeddings" + ], + "metadata": { + "id": "jbRFwBECV0My" + } + }, + { + "cell_type": "markdown", + "source": [ + "* Finally, let's use a simple MLP that predicts link probabilities between node pairs:" + ], + "metadata": { + "id": "K0AapIP9V7FC" + } + }, + { + "cell_type": "code", + "source": [ + "class LinkPredictor(torch.nn.Module):\n", + " def __init__(self, in_channels):\n", + " super().__init__()\n", + " self.lin_src = Linear(in_channels, in_channels)\n", + " self.lin_dst = Linear(in_channels, in_channels)\n", + " self.lin_final = Linear(in_channels, 1)\n", + "\n", + " def forward(self, z_src, z_dst):\n", + " h = self.lin_src(z_src) + self.lin_dst(z_dst)\n", + " h = h.relu()\n", + " return self.lin_final(h)\n", + "\n", + "# Create the LinkPredictor Object\n", + "link_pred = LinkPredictor(in_channels=embedding_dim).to(device)" + ], + "metadata": { + "id": "NH_0oS0OV_Sx" + }, + "execution_count": 37, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "### Training\n", + "A few important points about the training:\n", + "\n", + "1. Memory and neighbor states are reset at the start of each epoch\n", + "For each batch, we first compute temporal neighborhoods using neighbor_loader\n", + "2. Node embeddings are computed using the current memory state and graph attention\n", + "3. The model predicts both positive and negative links\n", + "After prediction, we update the memory with the true interactions\n" + ], + "metadata": { + "id": "poGFIqhKWD02" + } + }, + { + "cell_type": "code", + "source": [ + "# Let's define the optimizer and the Loss function\n", + "optimizer = torch.optim.Adam(set(memory.parameters()) | set(gnn.parameters()) | set(link_pred.parameters()), lr=0.0001)\n", + "criterion = torch.nn.BCEWithLogitsLoss()\n", + "\n", + "# Helper vector to map global node indices to local ones.\n", + "assoc = torch.empty(data.num_nodes, dtype=torch.long, device=device)" + ], + "metadata": { + "id": "IkpNhogDbN-K" + }, + "execution_count": null, + "outputs": [] + }, + { + "cell_type": "code", + "source": [ + "def train():\n", + " # Reset memory and neighbor loader states\n", + " memory.reset_state()\n", + " neighbor_loader.reset_state()\n", + "\n", + " total_loss = 0\n", + " for batch in train_loader:\n", + " optimizer.zero_grad()\n", + " batch = batch.to(device)\n", + "\n", + " # Get temporal neighborhood\n", + " n_id, edge_index, e_id = neighbor_loader(batch.n_id)\n", + " assoc[n_id] = torch.arange(n_id.size(0), device=device)\n", + "\n", + " # Compute node embeddings\n", + " z, last_update = memory(n_id)\n", + " z = gnn(z, last_update, edge_index, data.t[e_id].to(device),\n", + " data.msg[e_id].to(device))\n", + "\n", + " # Predict positive and negative links\n", + " pos_out = link_pred(z[assoc[batch.src]], z[assoc[batch.dst]])\n", + " neg_out = link_pred(z[assoc[batch.src]], z[assoc[batch.neg_dst]])\n", + "\n", + " # Compute binary cross entropy loss\n", + " loss = criterion(pos_out, torch.ones_like(pos_out))\n", + " loss += criterion(neg_out, torch.zeros_like(neg_out))\n", + "\n", + " # Update memory and graph structure\n", + " memory.update_state(batch.src, batch.dst, batch.t, batch.msg)\n", + " neighbor_loader.insert(batch.src, batch.dst)\n", + "\n", + " loss.backward()\n", + " optimizer.step()\n", + " memory.detach()\n", + " total_loss += float(loss) * batch.num_events\n", + "\n", + " return total_loss / train_data.num_events" + ], + "metadata": { + "id": "6ddZznkJWEgP" + }, + "execution_count": 38, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "Let's also implement a testing function for model evaluation" + ], + "metadata": { + "id": "0mAVcbdiVxjT" + } + }, + { + "cell_type": "code", + "source": [ + "@torch.no_grad()\n", + "def test(loader):\n", + " # Set all modules to evaluation mode\n", + " memory.eval()\n", + " gnn.eval()\n", + " link_pred.eval()\n", + "\n", + " # Set random seed for reproducible negative sampling\n", + " torch.manual_seed(12345)\n", + "\n", + " aps, aucs = [], []\n", + " for batch in loader:\n", + " batch = batch.to(device)\n", + "\n", + " # Get temporal neighborhood for current batch\n", + " n_id, edge_index, e_id = neighbor_loader(batch.n_id)\n", + " # Create mapping from global to local node indices\n", + " assoc[n_id] = torch.arange(n_id.size(0), device=device)\n", + "\n", + " # Get node embeddings from memory\n", + " z, last_update = memory(n_id)\n", + " # Update embeddings using graph attention\n", + " z = gnn(z, last_update, edge_index, data.t[e_id].to(device),\n", + " data.msg[e_id].to(device))\n", + "\n", + " # Predict on positive and negative edges\n", + " pos_out = link_pred(z[assoc[batch.src]], z[assoc[batch.dst]])\n", + " neg_out = link_pred(z[assoc[batch.src]], z[assoc[batch.neg_dst]])\n", + "\n", + " # Combine predictions and convert to probabilities\n", + " y_pred = torch.cat([pos_out, neg_out], dim=0).sigmoid().cpu()\n", + " # Create ground truth labels (1 for positive edges, 0 for negative)\n", + " y_true = torch.cat(\n", + " [torch.ones(pos_out.size(0)),\n", + " torch.zeros(neg_out.size(0))], dim=0)\n", + "\n", + " # Calculate metrics\n", + " aps.append(average_precision_score(y_true, y_pred))\n", + " aucs.append(roc_auc_score(y_true, y_pred))\n", + "\n", + " # Update memory and graph with ground truth interactions\n", + " memory.update_state(batch.src, batch.dst, batch.t, batch.msg)\n", + " neighbor_loader.insert(batch.src, batch.dst)\n", + "\n", + " # Return average metrics across all batches\n", + " return float(torch.tensor(aps).mean()), float(torch.tensor(aucs).mean())" + ], + "metadata": { + "id": "Fg0UOoVEWdkJ" + }, + "execution_count": 39, + "outputs": [] + }, + { + "cell_type": "markdown", + "source": [ + "We evaluate the model using two metrics:\n", + "\n", + "* Average Precision Score (AP): Measures the precision-recall trade-off\n", + "* Area Under ROC Curve (AUC): Measures the model's ability to distinguish between classes" + ], + "metadata": { + "id": "sl-cqTNYWtYH" + } + }, + { + "cell_type": "markdown", + "source": [ + "Finally, let's train and test the model" + ], + "metadata": { + "id": "TCvdFDqkXtpN" + } + }, + { + "cell_type": "code", + "source": [ + "# Training and evaluation loop\n", + "for epoch in range(1, 51):\n", + " loss = train()\n", + " print(f'Epoch: {epoch:02d}, Loss: {loss:.4f}')\n", + "\n", + " # Evaluate on validation and test sets\n", + " val_ap, val_auc = test(val_loader)\n", + " test_ap, test_auc = test(test_loader)\n", + "\n", + " print(f'Val AP: {val_ap:.4f}, Val AUC: {val_auc:.4f}')\n", + " print(f'Test AP: {test_ap:.4f}, Test AUC: {test_auc:.4f}')" + ], + "metadata": { + "colab": { + "base_uri": "https://localhost:8080/" + }, + "id": "9I8tl_PeXpWh", + "outputId": "591f36a7-0f65-43c8-b833-9fd2943c8782" + }, + "execution_count": 40, + "outputs": [ + { + "output_type": "stream", + "name": "stdout", + "text": [ + "Epoch: 01, Loss: 1.1953\n", + "Val AP: 0.8400, Val AUC: 0.8394\n", + "Test AP: 0.8249, Test AUC: 0.8217\n", + "Epoch: 02, Loss: 0.9529\n", + "Val AP: 0.8881, Val AUC: 0.8773\n", + "Test AP: 0.8728, Test AUC: 0.8625\n", + "Epoch: 03, Loss: 0.8445\n", + "Val AP: 0.9094, Val AUC: 0.8986\n", + "Test AP: 0.8955, Test AUC: 0.8858\n", + "Epoch: 04, Loss: 0.7768\n", + "Val AP: 0.9191, Val AUC: 0.9075\n", + "Test AP: 0.9053, Test AUC: 0.8954\n", + "Epoch: 05, Loss: 0.7427\n", + "Val AP: 0.9231, Val AUC: 0.9117\n", + "Test AP: 0.9088, Test AUC: 0.8997\n", + "Epoch: 06, Loss: 0.7220\n", + "Val AP: 0.9260, Val AUC: 0.9147\n", + "Test AP: 0.9105, Test AUC: 0.9024\n", + "Epoch: 07, Loss: 0.7063\n", + "Val AP: 0.9271, Val AUC: 0.9164\n", + "Test AP: 0.9128, Test AUC: 0.9051\n", + "Epoch: 08, Loss: 0.6925\n", + "Val AP: 0.9285, Val AUC: 0.9180\n", + "Test AP: 0.9145, Test AUC: 0.9074\n", + "Epoch: 09, Loss: 0.6801\n", + "Val AP: 0.9306, Val AUC: 0.9204\n", + "Test AP: 0.9177, Test AUC: 0.9096\n", + "Epoch: 10, Loss: 0.6675\n", + "Val AP: 0.9318, Val AUC: 0.9220\n", + "Test AP: 0.9199, Test AUC: 0.9117\n", + "Epoch: 11, Loss: 0.6555\n", + "Val AP: 0.9335, Val AUC: 0.9237\n", + "Test AP: 0.9224, Test AUC: 0.9142\n", + "Epoch: 12, Loss: 0.6445\n", + "Val AP: 0.9349, Val AUC: 0.9250\n", + "Test AP: 0.9244, Test AUC: 0.9158\n", + "Epoch: 13, Loss: 0.6333\n", + "Val AP: 0.9364, Val AUC: 0.9268\n", + "Test AP: 0.9254, Test AUC: 0.9172\n", + "Epoch: 14, Loss: 0.6250\n", + "Val AP: 0.9361, Val AUC: 0.9277\n", + "Test AP: 0.9233, Test AUC: 0.9179\n", + "Epoch: 15, Loss: 0.6164\n", + "Val AP: 0.9375, Val AUC: 0.9284\n", + "Test AP: 0.9262, Test AUC: 0.9190\n", + "Epoch: 16, Loss: 0.6088\n", + "Val AP: 0.9384, Val AUC: 0.9293\n", + "Test AP: 0.9279, Test AUC: 0.9201\n", + "Epoch: 17, Loss: 0.6013\n", + "Val AP: 0.9392, Val AUC: 0.9301\n", + "Test AP: 0.9282, Test AUC: 0.9206\n", + "Epoch: 18, Loss: 0.5945\n", + "Val AP: 0.9399, Val AUC: 0.9307\n", + "Test AP: 0.9292, Test AUC: 0.9212\n", + "Epoch: 19, Loss: 0.5876\n", + "Val AP: 0.9403, Val AUC: 0.9311\n", + "Test AP: 0.9290, Test AUC: 0.9216\n", + "Epoch: 20, Loss: 0.5813\n", + "Val AP: 0.9404, Val AUC: 0.9316\n", + "Test AP: 0.9289, Test AUC: 0.9223\n", + "Epoch: 21, Loss: 0.5745\n", + "Val AP: 0.9410, Val AUC: 0.9316\n", + "Test AP: 0.9304, Test AUC: 0.9231\n", + "Epoch: 22, Loss: 0.5681\n", + "Val AP: 0.9417, Val AUC: 0.9324\n", + "Test AP: 0.9303, Test AUC: 0.9232\n", + "Epoch: 23, Loss: 0.5615\n", + "Val AP: 0.9415, Val AUC: 0.9325\n", + "Test AP: 0.9294, Test AUC: 0.9238\n", + "Epoch: 24, Loss: 0.5554\n", + "Val AP: 0.9424, Val AUC: 0.9336\n", + "Test AP: 0.9292, Test AUC: 0.9242\n", + "Epoch: 25, Loss: 0.5491\n", + "Val AP: 0.9434, Val AUC: 0.9340\n", + "Test AP: 0.9322, Test AUC: 0.9249\n", + "Epoch: 26, Loss: 0.5429\n", + "Val AP: 0.9433, Val AUC: 0.9344\n", + "Test AP: 0.9302, Test AUC: 0.9252\n", + "Epoch: 27, Loss: 0.5373\n", + "Val AP: 0.9435, Val AUC: 0.9346\n", + "Test AP: 0.9304, Test AUC: 0.9255\n", + "Epoch: 28, Loss: 0.5308\n", + "Val AP: 0.9440, Val AUC: 0.9350\n", + "Test AP: 0.9303, Test AUC: 0.9259\n", + "Epoch: 29, Loss: 0.5252\n", + "Val AP: 0.9444, Val AUC: 0.9350\n", + "Test AP: 0.9311, Test AUC: 0.9260\n", + "Epoch: 30, Loss: 0.5198\n", + "Val AP: 0.9451, Val AUC: 0.9358\n", + "Test AP: 0.9319, Test AUC: 0.9267\n", + "Epoch: 31, Loss: 0.5147\n", + "Val AP: 0.9452, Val AUC: 0.9359\n", + "Test AP: 0.9321, Test AUC: 0.9269\n", + "Epoch: 32, Loss: 0.5098\n", + "Val AP: 0.9453, Val AUC: 0.9363\n", + "Test AP: 0.9323, Test AUC: 0.9275\n", + "Epoch: 33, Loss: 0.5045\n", + "Val AP: 0.9458, Val AUC: 0.9362\n", + "Test AP: 0.9325, Test AUC: 0.9271\n", + "Epoch: 34, Loss: 0.5001\n", + "Val AP: 0.9460, Val AUC: 0.9366\n", + "Test AP: 0.9334, Test AUC: 0.9275\n", + "Epoch: 35, Loss: 0.4949\n", + "Val AP: 0.9460, Val AUC: 0.9366\n", + "Test AP: 0.9328, Test AUC: 0.9274\n", + "Epoch: 36, Loss: 0.4907\n", + "Val AP: 0.9464, Val AUC: 0.9370\n", + "Test AP: 0.9337, Test AUC: 0.9282\n", + "Epoch: 37, Loss: 0.4867\n", + "Val AP: 0.9463, Val AUC: 0.9372\n", + "Test AP: 0.9333, Test AUC: 0.9279\n", + "Epoch: 38, Loss: 0.4825\n", + "Val AP: 0.9469, Val AUC: 0.9372\n", + "Test AP: 0.9338, Test AUC: 0.9281\n", + "Epoch: 39, Loss: 0.4782\n", + "Val AP: 0.9470, Val AUC: 0.9375\n", + "Test AP: 0.9339, Test AUC: 0.9281\n", + "Epoch: 40, Loss: 0.4740\n", + "Val AP: 0.9477, Val AUC: 0.9377\n", + "Test AP: 0.9350, Test AUC: 0.9285\n", + "Epoch: 41, Loss: 0.4707\n", + "Val AP: 0.9487, Val AUC: 0.9383\n", + "Test AP: 0.9363, Test AUC: 0.9292\n", + "Epoch: 42, Loss: 0.4662\n", + "Val AP: 0.9486, Val AUC: 0.9381\n", + "Test AP: 0.9363, Test AUC: 0.9292\n", + "Epoch: 43, Loss: 0.4625\n", + "Val AP: 0.9484, Val AUC: 0.9382\n", + "Test AP: 0.9357, Test AUC: 0.9294\n", + "Epoch: 44, Loss: 0.4592\n", + "Val AP: 0.9482, Val AUC: 0.9382\n", + "Test AP: 0.9354, Test AUC: 0.9294\n", + "Epoch: 45, Loss: 0.4552\n", + "Val AP: 0.9484, Val AUC: 0.9385\n", + "Test AP: 0.9351, Test AUC: 0.9289\n", + "Epoch: 46, Loss: 0.4517\n", + "Val AP: 0.9488, Val AUC: 0.9385\n", + "Test AP: 0.9350, Test AUC: 0.9290\n", + "Epoch: 47, Loss: 0.4490\n", + "Val AP: 0.9486, Val AUC: 0.9389\n", + "Test AP: 0.9354, Test AUC: 0.9293\n", + "Epoch: 48, Loss: 0.4457\n", + "Val AP: 0.9485, Val AUC: 0.9385\n", + "Test AP: 0.9348, Test AUC: 0.9287\n", + "Epoch: 49, Loss: 0.4426\n", + "Val AP: 0.9496, Val AUC: 0.9394\n", + "Test AP: 0.9357, Test AUC: 0.9293\n", + "Epoch: 50, Loss: 0.4389\n", + "Val AP: 0.9490, Val AUC: 0.9391\n", + "Test AP: 0.9354, Test AUC: 0.9296\n" + ] + } + ] + }, + { + "cell_type": "markdown", + "source": [ + "The model achieves around 93.50% performance on the Wikipedia dataset. Notice that the performance differs slightly from the original TGN paper as noted in the PyTorch Geometric repository.\n", + "\n", + "Here, a slightly different evaluation setup is used. Predictions within the same batch are made in parallel, meaning that interactions occurring later in the batch do not have access to any information about earlier interactions in the same batch. By contrast, the original TGN paper's code allows access to earlier interactions in the batch when sampling node neighborhoods for later interactions. While both methods are valid, we, in collaboration with the authors of the paper, chose to present this version as it is more realistic and provides a better testing ground for future methodologies." + ], + "metadata": { + "id": "xyT5TyO7XwAl" + } + }, + { + "cell_type": "markdown", + "source": [ + "### Final notes\n", + "* The interested reader can take a look at [Pytorch Geometric Temporal](https://pytorch-geometric-temporal.readthedocs.io/en/latest/modules/root.html) a temporal graph neural network extension library for PyTorch Geometric.\n", + "* A DGL implementation of TGN can be found [here](https://github.com/ytchx1999/TGN-DGL)" + ], + "metadata": { + "id": "ZcdNbcCEQwnQ" + } + }, + { + "cell_type": "code", + "source": [], + "metadata": { + "id": "0_1XwgXXRFYM" + }, + "execution_count": null, + "outputs": [] + } + ] +} \ No newline at end of file