{ "cells": [ { "cell_type": "markdown", "metadata": {}, "source": [ "# Advanced multiverse structures\n", "\n", "Sometimes a multiverse is more complex than a fully connected grid of options. To express dependencies and constraints, you can add rules in the `config` dictionary.\n", "\n", "Three rule types exist:\n", "\n", "- `\"exclude\"` — keep the universe but set specific keys to `NaN` when conditions match \n", "- `\"remove\"` — drop universes entirely when conditions match \n", "- `\"order\"` — control the generation order of decisions\n", "\n", "There is also an optional flag:\n", "\n", "- `\"deduplicate\"` — collapse identical universes after `exclude`/`order` (defaults to `True`). \n", " Universes are considered identical even if their values are `NaN` (treated as equal).\n", "\n", "\n", "Have a look at the following example, which would result in 36 universes for a fully connected multiverse (3 * 3 * 2 * 2). However, we decide to:\n", "\n", "- Exclude the `value` decision from all universes which contain `function1` being `a` or `b`\n", "- Exclude the `option` decision from all universes with `function2` being `d`\n", "- Remove all universes which contain `function1` `c` and option `False`\n" ] }, { "cell_type": "code", "execution_count": 2, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Exclusion summary\n", "-----------------\n", "Total number of universes: 72 (includes ordering permutations)\n", " - Set 'value' to NaN for universes matching {'function1': 'a'} (10 total).\n", " - Set 'option' to NaN for universes matching {'function2': 'd'} (8 total).\n", " - Set 'value' to NaN for universes matching {'function1': 'b'} (10 total).\n", " - Removed 8 out of 40 remaining universes:\n", " Rule [{'function1': 'c'}, {'option': False}] excluded 8 universes:\n", " {'function1': 'c', 'function2': 'e', 'value': 4, 'option': False}\n", " {'function1': 'c', 'function2': 'e', 'value': 5, 'option': False}\n", " {'function1': 'c', 'function2': 'f', 'value': 4, 'option': False}\n", " {'function1': 'c', 'function2': 'f', 'value': 5, 'option': False}\n", " {'function2': 'e', 'function1': 'c', 'value': 4, 'option': False}\n", " {'function2': 'e', 'function1': 'c', 'value': 5, 'option': False}\n", " {'function2': 'f', 'function1': 'c', 'value': 4, 'option': False}\n", " {'function2': 'f', 'function1': 'c', 'value': 5, 'option': False}\n", "\n", "32 universes remain for analysis.\n" ] }, { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
UniverseDecision 1Value 1Decision 2Value 2Decision 3Value 3Decision 4Value 4
0Universe_1function1afunction2dvalueNaNoptionNaN
1Universe_2function1afunction2evalueNaNoptionTrue
2Universe_3function1afunction2evalueNaNoptionFalse
3Universe_4function1afunction2fvalueNaNoptionTrue
4Universe_5function1afunction2fvalueNaNoptionFalse
5Universe_6function1bfunction2dvalueNaNoptionNaN
6Universe_7function1bfunction2evalueNaNoptionTrue
7Universe_8function1bfunction2evalueNaNoptionFalse
8Universe_9function1bfunction2fvalueNaNoptionTrue
9Universe_10function1bfunction2fvalueNaNoptionFalse
10Universe_11function1cfunction2dvalue4.0optionNaN
11Universe_12function1cfunction2dvalue5.0optionNaN
12Universe_13function1cfunction2evalue4.0optionTrue
13Universe_14function1cfunction2evalue5.0optionTrue
14Universe_15function1cfunction2fvalue4.0optionTrue
15Universe_16function1cfunction2fvalue5.0optionTrue
16Universe_17function2dfunction1avalueNaNoptionNaN
17Universe_18function2dfunction1bvalueNaNoptionNaN
18Universe_19function2dfunction1cvalue4.0optionNaN
19Universe_20function2dfunction1cvalue5.0optionNaN
20Universe_21function2efunction1avalueNaNoptionTrue
21Universe_22function2efunction1avalueNaNoptionFalse
22Universe_23function2efunction1bvalueNaNoptionTrue
23Universe_24function2efunction1bvalueNaNoptionFalse
24Universe_25function2efunction1cvalue4.0optionTrue
25Universe_26function2efunction1cvalue5.0optionTrue
26Universe_27function2ffunction1avalueNaNoptionTrue
27Universe_28function2ffunction1avalueNaNoptionFalse
28Universe_29function2ffunction1bvalueNaNoptionTrue
29Universe_30function2ffunction1bvalueNaNoptionFalse
30Universe_31function2ffunction1cvalue4.0optionTrue
31Universe_32function2ffunction1cvalue5.0optionTrue
\n", "
" ], "text/plain": [ " Universe Decision 1 Value 1 Decision 2 Value 2 Decision 3 Value 3 \\\n", "0 Universe_1 function1 a function2 d value NaN \n", "1 Universe_2 function1 a function2 e value NaN \n", "2 Universe_3 function1 a function2 e value NaN \n", "3 Universe_4 function1 a function2 f value NaN \n", "4 Universe_5 function1 a function2 f value NaN \n", "5 Universe_6 function1 b function2 d value NaN \n", "6 Universe_7 function1 b function2 e value NaN \n", "7 Universe_8 function1 b function2 e value NaN \n", "8 Universe_9 function1 b function2 f value NaN \n", "9 Universe_10 function1 b function2 f value NaN \n", "10 Universe_11 function1 c function2 d value 4.0 \n", "11 Universe_12 function1 c function2 d value 5.0 \n", "12 Universe_13 function1 c function2 e value 4.0 \n", "13 Universe_14 function1 c function2 e value 5.0 \n", "14 Universe_15 function1 c function2 f value 4.0 \n", "15 Universe_16 function1 c function2 f value 5.0 \n", "16 Universe_17 function2 d function1 a value NaN \n", "17 Universe_18 function2 d function1 b value NaN \n", "18 Universe_19 function2 d function1 c value 4.0 \n", "19 Universe_20 function2 d function1 c value 5.0 \n", "20 Universe_21 function2 e function1 a value NaN \n", "21 Universe_22 function2 e function1 a value NaN \n", "22 Universe_23 function2 e function1 b value NaN \n", "23 Universe_24 function2 e function1 b value NaN \n", "24 Universe_25 function2 e function1 c value 4.0 \n", "25 Universe_26 function2 e function1 c value 5.0 \n", "26 Universe_27 function2 f function1 a value NaN \n", "27 Universe_28 function2 f function1 a value NaN \n", "28 Universe_29 function2 f function1 b value NaN \n", "29 Universe_30 function2 f function1 b value NaN \n", "30 Universe_31 function2 f function1 c value 4.0 \n", "31 Universe_32 function2 f function1 c value 5.0 \n", "\n", " Decision 4 Value 4 \n", "0 option NaN \n", "1 option True \n", "2 option False \n", "3 option True \n", "4 option False \n", "5 option NaN \n", "6 option True \n", "7 option False \n", "8 option True \n", "9 option False \n", "10 option NaN \n", "11 option NaN \n", "12 option True \n", "13 option True \n", "14 option True \n", "15 option True \n", "16 option NaN \n", "17 option NaN \n", "18 option NaN \n", "19 option NaN \n", "20 option True \n", "21 option False \n", "22 option True \n", "23 option False \n", "24 option True \n", "25 option True \n", "26 option True \n", "27 option False \n", "28 option True \n", "29 option False \n", "30 option True \n", "31 option True " ] }, "metadata": {}, "output_type": "display_data" } ], "source": [ "from comet.multiverse import Multiverse\n", "\n", "forking_paths = {\n", " \"function1\": [\"a\", \"b\", \"c\"],\n", " \"function2\": [\"d\", \"e\", \"f\"],\n", " \"value\": [4, 5],\n", " \"option\": [True, False]\n", "}\n", "\n", "config = {\n", " \"order\": \n", " # Have universes for different ordering of functions\n", " [[\"function1\", \"function2\", \"value\", \"option\"],\n", " [\"function2\", \"function1\", \"value\", \"option\"]],\n", " \"exclude\": [\n", " # Value is irrelevant for all function1 options\n", " [{\"function1\": \"a\"}, \"value\"],\n", " [{\"function1\": \"b\"}, \"value\"],\n", "\n", " # Function b never has any option → ignore it (set to NaN)\n", " [{\"function2\": \"d\"}, \"option\"],\n", " ],\n", " \"remove\": [\n", " # Function c only allowed with option == True → drop the False ones\n", " [{\"function1\": \"c\"}, {\"option\": False}],\n", " ],\n", " # Optional (True by default): make a/b/c + multiple values/options collapse cleanly\n", " \"deduplicate\": True\n", "}\n", "\n", "def analysis_template():\n", " function1 = {{function1}}\n", " function2 = {{function2}}\n", " value = {{value}}\n", " option = {{option}}\n", "\n", "mverse = Multiverse(name=\"example_mv_structure\")\n", "mverse.create(analysis_template, forking_paths, config)\n", "mverse.summary()" ] } ], "metadata": { "kernelspec": { "display_name": "comet-test", "language": "python", "name": "python3" }, "language_info": { "codemirror_mode": { "name": "ipython", "version": 3 }, "file_extension": ".py", "mimetype": "text/x-python", "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", "version": "3.13.0" } }, "nbformat": 4, "nbformat_minor": 2 }