From 420b4ed670443a788bf107c279165a6f9575642d Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Wed, 17 Jul 2024 15:54:49 +0200 Subject: [PATCH 01/77] add notebook --- tutorial/SMT_DesignSpace_example.ipynb | 304 ++++++++++++++++++++++--- 1 file changed, 275 insertions(+), 29 deletions(-) diff --git a/tutorial/SMT_DesignSpace_example.ipynb b/tutorial/SMT_DesignSpace_example.ipynb index 8d66cc644..3993bd788 100644 --- a/tutorial/SMT_DesignSpace_example.ipynb +++ b/tutorial/SMT_DesignSpace_example.ipynb @@ -21,9 +21,9 @@ "This tutorial describes how to use de DesignSpace within the SMT toolbox. \n", "
\n", " \n", - " May 2024 - `SMT version 2.5.1`\n", + " July 2024 - `SMT version 2.6.3`\n", " \n", - " Jasper Bussemaker (DLR), Paul Saves, and Nathalie BARTOLI (ONERA/DTIS/M2CI)" + " Paul Saves, Jasper Bussemaker (DLR), and Nathalie BARTOLI (ONERA/DTIS/M2CI)" ] }, { @@ -77,21 +77,82 @@ "name": "stdout", "output_type": "stream", "text": [ - "Requirement already satisfied: smt in d:\\bartoli\\anaconda3\\lib\\site-packages (2.5.0)\n", - "Requirement already satisfied: scikit-learn in d:\\bartoli\\anaconda3\\lib\\site-packages (from smt) (1.3.0)\n", - "Requirement already satisfied: pyDOE3 in d:\\bartoli\\anaconda3\\lib\\site-packages (from smt) (1.0.1)\n", - "Requirement already satisfied: scipy in d:\\bartoli\\anaconda3\\lib\\site-packages (from smt) (1.11.1)\n", - "Requirement already satisfied: jenn in d:\\bartoli\\anaconda3\\lib\\site-packages (from smt) (1.0.3)\n", - "Requirement already satisfied: orjson>=3.9 in d:\\bartoli\\anaconda3\\lib\\site-packages (from jenn->smt) (3.9.15)\n", - "Requirement already satisfied: numpy>=1.22 in d:\\bartoli\\anaconda3\\lib\\site-packages (from jenn->smt) (1.24.3)\n", - "Requirement already satisfied: joblib>=1.1.1 in d:\\bartoli\\anaconda3\\lib\\site-packages (from scikit-learn->smt) (1.2.0)\n", - "Requirement already satisfied: threadpoolctl>=2.0.0 in d:\\bartoli\\anaconda3\\lib\\site-packages (from scikit-learn->smt) (2.2.0)\n" + "Requirement already satisfied: configspace==0.6.1 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (0.6.1)\n", + "Requirement already satisfied: numpy in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from configspace==0.6.1) (1.23.5)\n", + "Requirement already satisfied: pyparsing in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from configspace==0.6.1) (3.0.9)\n", + "Requirement already satisfied: scipy in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from configspace==0.6.1) (1.11.3)\n", + "Requirement already satisfied: typing-extensions in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from configspace==0.6.1) (4.11.0)\n", + "Requirement already satisfied: more-itertools in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from configspace==0.6.1) (8.12.0)\n", + "Requirement already satisfied: smt in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (2.6.2)\n", + "Requirement already satisfied: scikit-learn in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.4.0)\n", + "Requirement already satisfied: pyDOE3 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.0.3)\n", + "Requirement already satisfied: scipy in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.11.3)\n", + "Requirement already satisfied: jenn in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.0.6)\n", + "Requirement already satisfied: jsonpointer>=2.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (3.0.0)\n", + "Requirement already satisfied: jsonschema>=4.22 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (4.22.0)\n", + "Requirement already satisfied: orjson>=3.9 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (3.10.6)\n", + "Requirement already satisfied: numpy>=1.22 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (1.23.5)\n", + "Requirement already satisfied: joblib>=1.2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from scikit-learn->smt) (1.4.2)\n", + "Requirement already satisfied: threadpoolctl>=2.0.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from scikit-learn->smt) (3.5.0)\n", + "Requirement already satisfied: attrs>=22.2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (23.1.0)\n", + "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (2023.12.1)\n", + "Requirement already satisfied: referencing>=0.28.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.35.1)\n", + "Requirement already satisfied: rpds-py>=0.7.1 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.18.1)\n", + "Collecting git+https://github.com/jbussemaker/adsg-core.git@dev\n", + " Cloning https://github.com/jbussemaker/adsg-core.git (to revision dev) to /tmp/pip-req-build-qsmkmsaa\n", + " Running command git clone --filter=blob:none --quiet https://github.com/jbussemaker/adsg-core.git /tmp/pip-req-build-qsmkmsaa\n", + " Running command git checkout -b dev --track origin/dev\n", + " Switched to a new branch 'dev'\n", + " Branch 'dev' set up to track remote branch 'dev' from 'origin'.\n", + " Resolved https://github.com/jbussemaker/adsg-core.git to commit be22d7db9cfb0dafc125cc87ec3b86228886d5f9\n", + " Installing build dependencies ... \u001b[?25ldone\n", + "\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n", + "\u001b[?25h Preparing metadata (pyproject.toml) ... \u001b[?25ldone\n", + "\u001b[?25hRequirement already satisfied: networkx~=2.6 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (2.8.8)\n", + "Requirement already satisfied: lxml in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (5.2.2)\n", + "Requirement already satisfied: pydot in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (3.0.1)\n", + "Requirement already satisfied: cached-property>=1.5 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (1.5.2)\n", + "Requirement already satisfied: appdirs in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (1.4.4)\n", + "Requirement already satisfied: numpy<2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (1.23.5)\n", + "Requirement already satisfied: scipy~=1.9 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (1.11.3)\n", + "Requirement already satisfied: pandas in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (2.2.2)\n", + "Requirement already satisfied: numba~=0.56 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (0.60.0)\n", + "Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from numba~=0.56->adsg-core==1.1.0) (0.43.0)\n", + "Requirement already satisfied: python-dateutil>=2.8.2 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from pandas->adsg-core==1.1.0) (2.8.2)\n", + "Requirement already satisfied: pytz>=2020.1 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from pandas->adsg-core==1.1.0) (2024.1)\n", + "Requirement already satisfied: tzdata>=2022.7 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from pandas->adsg-core==1.1.0) (2024.1)\n", + "Requirement already satisfied: pyparsing>=3.0.9 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from pydot->adsg-core==1.1.0) (3.0.9)\n", + "Requirement already satisfied: six>=1.5 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from python-dateutil>=2.8.2->pandas->adsg-core==1.1.0) (1.16.0)\n", + "Requirement already satisfied: smt in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (2.6.2)\n", + "Requirement already satisfied: scikit-learn in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.4.0)\n", + "Requirement already satisfied: pyDOE3 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.0.3)\n", + "Requirement already satisfied: scipy in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.11.3)\n", + "Requirement already satisfied: jenn in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.0.6)\n", + "Requirement already satisfied: jsonpointer>=2.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (3.0.0)\n", + "Requirement already satisfied: jsonschema>=4.22 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (4.22.0)\n", + "Requirement already satisfied: orjson>=3.9 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (3.10.6)\n", + "Requirement already satisfied: numpy>=1.22 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (1.23.5)\n", + "Requirement already satisfied: joblib>=1.2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from scikit-learn->smt) (1.4.2)\n", + "Requirement already satisfied: threadpoolctl>=2.0.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from scikit-learn->smt) (3.5.0)\n", + "Requirement already satisfied: attrs>=22.2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (23.1.0)\n", + "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (2023.12.1)\n", + "Requirement already satisfied: referencing>=0.28.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.35.1)\n", + "Requirement already satisfied: rpds-py>=0.7.1 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.18.1)\n" ] } ], "source": [ + "!pip install configspace==0.6.1\n", + "#!pip install adsg_core --pre\n", + "#!pip install adsg-core[nb]\n", + "\n", "#to install smt\n", - "!pip install smt" + "!pip install smt\n", + "\n", + "!pip install git+https://github.com/jbussemaker/adsg-core.git@dev\n", + "\n", + "#to have the latest version\n", + "!pip install smt --pre" ] }, { @@ -122,8 +183,50 @@ "metadata": {}, "outputs": [], "source": [ - "from smt.utils.design_space import DesignSpace, FloatVariable, IntegerVariable, OrdinalVariable, CategoricalVariable\n", - "import numpy as np" + "#to ignore warning messages\n", + "import warnings\n", + "warnings.filterwarnings(\"ignore\")\n", + "\n", + "import os\n", + "import unittest\n", + "import numpy as np\n", + "from sys import argv\n", + "import matplotlib.pyplot as plt\n", + "import time\n", + "%matplotlib inline\n", + "\n", + "from smt.applications import EGO\n", + "from smt.applications.ego import Evaluator\n", + "from smt.utils.sm_test_case import SMTestCase\n", + "from smt.problems import Branin, Rosenbrock, HierarchicalGoldstein\n", + "from smt.sampling_methods import FullFactorial\n", + "from multiprocessing import Pool\n", + "from smt.sampling_methods import LHS\n", + "import itertools\n", + "from smt.surrogate_models import (\n", + " KRG,\n", + " GEKPLS,\n", + " KPLS,\n", + " QP,\n", + " MixIntKernelType,\n", + " MixHrcKernelType,\n", + ")\n", + "from smt.applications.mixed_integer import (\n", + " MixedIntegerContext,\n", + " MixedIntegerSamplingMethod,\n", + " MixedIntegerKrigingModel\n", + ")\n", + "\n", + "from smt.utils.design_space import (\n", + " DesignSpace,\n", + " FloatVariable,\n", + " IntegerVariable,\n", + " OrdinalVariable,\n", + " CategoricalVariable,\n", + ")\n", + "\n", + "import plotly.io as pio\n", + "pio.renderers.default='notebook'\n" ] }, { @@ -189,13 +292,13 @@ "output_type": "stream", "text": [ "Data encoded: \n", - " [[1. 0. 0. 0.52853667]\n", - " [1. 0. 1. 0.09673616]\n", - " [0. 0. 1. 0.33682711]\n", - " [0. 1. 1. 0.91199549]\n", - " [1. 0. 2. 0.67001367]]\n", + " [[ 0. 2. -0. 0.2080406 ]\n", + " [ 0. 0. 1. 0.68792902]\n", + " [ 0. 2. 1. 0.32768399]\n", + " [ 0. 1. -0. 0.67460808]\n", + " [ 0. 0. -0. 0.08387924]]\n", "Data in initial space: \n", - " [['B', 'C', 0.0, 0.5285366741197288], ['B', 'C', 1.0, 0.09673615686563666], ['A', 'C', 1.0, 0.33682711198922366], ['A', 'D', 1.0, 0.9119954884545415], ['B', 'C', 2.0, 0.6700136703569705]]\n" + " [['A', 'E', -0.0, 0.20804060028495952], ['A', 'C', 1.0, 0.6879290240972027], ['A', 'E', 1.0, 0.32768399075187604], ['A', 'D', -0.0, 0.6746080768493098], ['A', 'C', -0.0, 0.08387924339852171]]\n" ] } ], @@ -219,11 +322,11 @@ "output_type": "stream", "text": [ "Which variables are active \n", - " [[ True False True True]\n", - " [ True False True True]\n", + " [[ True True True True]\n", + " [ True True True True]\n", " [ True True True True]\n", " [ True True True True]\n", - " [ True False True True]]\n" + " [ True True True True]]\n" ] } ], @@ -314,11 +417,11 @@ "output_type": "stream", "text": [ "Data encoded: \n", - " [[0.76145156 1.55158873 0.70950859]\n", - " [0.15453887 0.5979029 5.24003766]\n", - " [0.98290394 0.82219187 3.92612692]\n", - " [0.40976592 0.09755228 2.0798789 ]\n", - " [0.31427305 1.74529453 3.30571286]]\n", + " [[0.6211392 0.99609568 3.79829878]\n", + " [0.70086578 1.5552522 0.77369391]\n", + " [0.74386417 0.43386098 1.77447691]\n", + " [0.56025309 0.11930465 1.25259765]\n", + " [0.23214073 1.88632861 1.48669667]]\n", "Is_acting: \n", " [[ True True True]\n", " [ True True True]\n", @@ -333,6 +436,149 @@ "print('Is_acting: \\n', is_acting_sampled_cont)" ] }, + { + "cell_type": "markdown", + "metadata": {}, + "source": [ + "# Moving towards Architecture Design Space Graph (ADSG)" + ] + }, + { + "cell_type": "code", + "execution_count": 10, + "metadata": {}, + "outputs": [ + { + "data": { + "text/html": [ + "
\n", + "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "from adsg_core import BasicADSG, NamedNode, SelectionChoiceNode,DesignVariableNode\n", + "\n", + "# Create the ADSG\n", + "adsg = BasicADSG()\n", + "\n", + "ndv=14\n", + "\n", + "\n", + "# Create nodes\n", + "n = [NamedNode(f'N{i}') for i in range(ndv)]\n", + "n = [NamedNode(\"MLP\"),NamedNode(\"Learning rate\"), NamedNode(\"Activation function\"),\n", + " NamedNode(\"Optimizer\"),NamedNode(\"Decay\"),NamedNode(\"Power update\"), NamedNode(\"Average start\"),\n", + " NamedNode(\"Running Average 1\"),NamedNode(\"Running Average 2\"),NamedNode(\"Numerical Stability\"),\n", + " NamedNode(\"Nb. layers\"), NamedNode(\"Layer 1\"), NamedNode(\"Layer 2\"), NamedNode(\"Layer 3\"), # NamedNode(\"Dropout\"),\n", + " NamedNode(\"ASGD\"),NamedNode(\"Adam\"), NamedNode(\"20...40\"),NamedNode(\"40\"),NamedNode(\"45\"),NamedNode(\"20...40\"), NamedNode(\"40\"),NamedNode(\"45\"), NamedNode(\"20...40\"),NamedNode(\"40\"),NamedNode(\"45\")]\n", + "adsg.add_node(n[1])\n", + "adsg.add_node(n[2])\n", + "#adsg.add_node(n[3])\n", + "\n", + "# Add some edges\n", + "adsg.add_edges([\n", + " # (n[0], n[1]),\n", + " # (n[0], n[2]),\n", + " # (n[0], n[3]),\n", + " (n[3],n[10]),\n", + " (n[14],n[4]),\n", + " (n[14],n[5]),\n", + " (n[14],n[6]),\n", + " (n[15],n[7]),\n", + " (n[15],n[8]),\n", + " (n[15],n[9]),\n", + "])\n", + "\n", + "choiceo=adsg.add_selection_choice(\"Optimizer_Choice\", n[3], [n[14], n[15]])\n", + "\n", + "\n", + "choicenl=adsg.add_selection_choice(\"#layers\", n[10], [n[11], n[12],n[13]])\n", + "adsg.add_edges([ (n[12],n[11]), (n[13],n[12]) ])\n", + "a = []\n", + "for i in range(3) :\n", + " a.append(NamedNode(str(25+5*i)))\n", + "b = a.copy()\n", + "b.append(n[17])\n", + "b.append(n[18])\n", + "choicel1=adsg.add_selection_choice(\"#neurons\", n[11], b)\n", + "\n", + "\n", + "a = []\n", + "for i in range(3) :\n", + " a.append(NamedNode(str(25+5*i)))\n", + "b = a.copy()\n", + "b.append(n[20])\n", + "b.append(n[21])\n", + "choicel1=adsg.add_selection_choice(\"#neurons\", n[12], b)\n", + "\n", + "a = []\n", + "for i in range(3) :\n", + " a.append(NamedNode(str(25+5*i)))\n", + "b = a.copy()\n", + "b.append(n[23])\n", + "b.append(n[24])\n", + "choicel1=adsg.add_selection_choice(\"#neurons\", n[13], b)\n", + "\n", + "#adsg.add_edges([ (n[18],n[17]), (n[17],n[16]) ])\n", + "#adsg.add_edges([ (n[21],n[20]), (n[20],n[19]) ])\n", + "#adsg.add_edges([ (n[24],n[23]), (n[23],n[22]) ])\n", + "\n", + "adsg.add_incompatibility_constraint([n[15], n[13]])\n", + "adsg.add_incompatibility_constraint([n[14], n[17]])\n", + "adsg.add_incompatibility_constraint([n[14], n[18]])\n", + "adsg.add_incompatibility_constraint([n[14], n[20]])\n", + "adsg.add_incompatibility_constraint([n[14], n[21]])\n", + "adsg.add_incompatibility_constraint([n[14], n[23]])\n", + "adsg.add_incompatibility_constraint([n[14], n[24]])\n", + "start_nodes = set()\n", + "start_nodes.add(n[3])\n", + "start_nodes.add(n[2])\n", + "start_nodes.add(n[1])\n", + "#start_nodes.add(n[0])\n", + "\n", + "\n", + "\n", + "adsg.add_edges([\n", + " (n[1], DesignVariableNode('x0', bounds=(0, 1))),\n", + " (n[4], DesignVariableNode('x1', bounds=(0, 1))),\n", + " (n[5], DesignVariableNode('x2', bounds=(0, 1))),\n", + " (n[6], DesignVariableNode('x3', bounds=(0, 1))),\n", + " (n[7], DesignVariableNode('x4', bounds=(0, 1))),\n", + " (n[8], DesignVariableNode('x5', bounds=(0, 1))),\n", + " (n[9], DesignVariableNode('x6', bounds=(0, 1))),\n", + " #(n[11], DesignVariableNode('x7', options=(\"0\", \"1\"))),\n", + "\n", + "])\n", + "\n", + "choiceo=adsg.add_selection_choice(\"Activation_Choice\", n[2], [NamedNode(\"ReLU\"), NamedNode(\"Sigmoid\"),NamedNode(\"Tanh\")])\n", + "\n", + "adsg = adsg.set_start_nodes(start_nodes)\n", + "\n", + "adsg.render()\n", + "\n" + ] + }, { "cell_type": "code", "execution_count": null, @@ -362,7 +608,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.11.5" + "version": "3.9.18" } }, "nbformat": 4, From ff17d9d43ca834374487fc1d21ea2446e08cd181 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Thu, 18 Jul 2024 17:27:09 +0200 Subject: [PATCH 02/77] update design space utils --- smt/utils/design_space.py | 38 ++- smt/utils/test/test_design_space.py | 25 +- tutorial/SMT_DesignSpace_example.ipynb | 356 ++++++++++++++++++++++--- 3 files changed, 374 insertions(+), 45 deletions(-) diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index 19e878af9..ab3271eec 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -1017,7 +1017,9 @@ def _correct_get_acting(self, x: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: configs.append(self._get_correct_config(xi[inv_cs_var_idx])) # Convert Configuration objects to design vectors and get the is_active matrix - return self._configs_to_x(configs) + x_out, is_act = self._configs_to_x(configs) + self._impute_non_acting(x_out, is_act) + return x_out, is_act # Simplified implementation # Correct discrete variables @@ -1190,7 +1192,7 @@ def _impute_non_acting(self, x: np.ndarray, is_acting: np.ndarray): for i, dv in enumerate(self.design_variables): if isinstance(dv, FloatVariable): # Impute continuous variables to the mid of their bounds - x[~is_acting[:, i], i] = 0.5 * (dv.upper - dv.lower) + x[~is_acting[:, i], i] = 0.5 * (dv.upper - dv.lower) + dv.lower else: # Impute discrete variables to their lower bounds @@ -1300,3 +1302,35 @@ def get_neighbors( return super().get_neighbors( value, rs, number=number, transform=transform, std=std ) + + +def convert_adsg_to_legacy(adsg) -> "BaseDesignSpace": + """Interface to turn adsg input formats into legacy DesignSpace""" + + # Define the mixed hierarchical design space + from adsg_core import SelectionChoiceNode + from adsg_core import GraphProcessor + + gp = GraphProcessor(adsg) + listvar = [] + gvars = gp._all_des_var_data[0] + + for i in gvars: + print(i._bounds, i.n_opts, type(i.node)) + if i._bounds is not None: + listvar.append(FloatVariable(lower=i._bounds[0], upper=i._bounds[1])) + elif type(i.node) is SelectionChoiceNode: + a = str(i._opts).replace("[", "").replace("]", "").split(",") + listvar.append(CategoricalVariable(a)) + else: + a = ( + str(i._opts) + .replace("[", "") + .replace("]", "") + .replace(" ", "") + .replace("'", "") + .split(",") + ) + listvar.append(OrdinalVariable(a)) + + DesignSpace(listvar) diff --git a/smt/utils/test/test_design_space.py b/smt/utils/test/test_design_space.py index 60cbd4515..353cf8f6e 100644 --- a/smt/utils/test/test_design_space.py +++ b/smt/utils/test/test_design_space.py @@ -340,7 +340,7 @@ def test_design_space_hierarchical(self): CategoricalVariable(["A", "B", "C"]), # x0 CategoricalVariable(["E", "F"]), # x1 IntegerVariable(0, 1), # x2 - FloatVariable(0, 1), # x3 + FloatVariable(0.1, 1), # x3 ], random_state=42, ) @@ -372,14 +372,14 @@ def test_design_space_hierarchical(self): [0, 1, 0, 0.75], [0, 1, 1, 0.25], [0, 1, 1, 0.75], - [1, 0, 0, 0.5], - [1, 0, 1, 0.5], - [1, 1, 0, 0.5], - [1, 1, 1, 0.5], - [2, 0, 0, 0.5], - [2, 0, 1, 0.5], - [2, 1, 0, 0.5], - [2, 1, 1, 0.5], + [1, 0, 0, 0.55], + [1, 0, 1, 0.55], + [1, 1, 0, 0.55], + [1, 1, 1, 0.55], + [2, 0, 0, 0.55], + [2, 0, 1, 0.55], + [2, 1, 0, 0.55], + [2, 1, 1, 0.55], ] ), ) @@ -410,11 +410,11 @@ def test_design_space_hierarchical(self): x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) assert x_sampled.shape == (100, 4) x_sampled[is_acting_sampled[:, 3], 3] = np.round( - x_sampled[is_acting_sampled[:, 3], 3] + x_sampled[is_acting_sampled[:, 3], 3], 4 ) x_corr, is_acting_corr = ds.correct_get_acting(x_sampled) - self.assertTrue(np.all(x_corr == x_sampled)) + self.assertTrue(np.sum(np.abs(x_corr - x_sampled)) < 1e-12) self.assertTrue(np.all(is_acting_corr == is_acting_sampled)) seen_x = set() @@ -422,7 +422,7 @@ def test_design_space_hierarchical(self): for i, xi in enumerate(x_sampled): seen_x.add(tuple(xi)) seen_is_acting.add(tuple(is_acting_sampled[i, :])) - assert len(seen_x) == 16 + assert len(seen_x) == 49 assert len(seen_is_acting) == 2 @unittest.skipIf( @@ -583,7 +583,6 @@ def _is_conditionally_acting(self) -> np.ndarray: ds.declare_decreed_var( decreed_var=3, meta_var=0, meta_value="A" ) # Activate x3 if x0 == A - self.assertRaises( RuntimeError, lambda: ds.sample_valid_x(10, random_state=42) ) diff --git a/tutorial/SMT_DesignSpace_example.ipynb b/tutorial/SMT_DesignSpace_example.ipynb index 3993bd788..ca2f3e252 100644 --- a/tutorial/SMT_DesignSpace_example.ipynb +++ b/tutorial/SMT_DesignSpace_example.ipynb @@ -63,7 +63,7 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 49, "metadata": { "colab": { "base_uri": "https://localhost:8080/", @@ -99,8 +99,8 @@ "Requirement already satisfied: referencing>=0.28.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.35.1)\n", "Requirement already satisfied: rpds-py>=0.7.1 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.18.1)\n", "Collecting git+https://github.com/jbussemaker/adsg-core.git@dev\n", - " Cloning https://github.com/jbussemaker/adsg-core.git (to revision dev) to /tmp/pip-req-build-qsmkmsaa\n", - " Running command git clone --filter=blob:none --quiet https://github.com/jbussemaker/adsg-core.git /tmp/pip-req-build-qsmkmsaa\n", + " Cloning https://github.com/jbussemaker/adsg-core.git (to revision dev) to /tmp/pip-req-build-o31nndpu\n", + " Running command git clone --filter=blob:none --quiet https://github.com/jbussemaker/adsg-core.git /tmp/pip-req-build-o31nndpu\n", " Running command git checkout -b dev --track origin/dev\n", " Switched to a new branch 'dev'\n", " Branch 'dev' set up to track remote branch 'dev' from 'origin'.\n", @@ -179,7 +179,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 50, "metadata": {}, "outputs": [], "source": [ @@ -256,7 +256,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 51, "metadata": {}, "outputs": [ { @@ -284,7 +284,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 52, "metadata": {}, "outputs": [ { @@ -292,13 +292,13 @@ "output_type": "stream", "text": [ "Data encoded: \n", - " [[ 0. 2. -0. 0.2080406 ]\n", - " [ 0. 0. 1. 0.68792902]\n", - " [ 0. 2. 1. 0.32768399]\n", - " [ 0. 1. -0. 0.67460808]\n", - " [ 0. 0. -0. 0.08387924]]\n", + " [[ 0. 0. -0. 0.7453051 ]\n", + " [ 1. 0. -0. 0.7540022 ]\n", + " [ 0. 0. -0. 0.39730034]\n", + " [ 1. 0. -0. 0.96248124]\n", + " [ 0. 1. 2. 0.01214101]]\n", "Data in initial space: \n", - " [['A', 'E', -0.0, 0.20804060028495952], ['A', 'C', 1.0, 0.6879290240972027], ['A', 'E', 1.0, 0.32768399075187604], ['A', 'D', -0.0, 0.6746080768493098], ['A', 'C', -0.0, 0.08387924339852171]]\n" + " [['A', 'C', -0.0, 0.7453050971816425], ['B', 'C', -0.0, 0.75400220455586], ['A', 'C', -0.0, 0.3973003372895373], ['B', 'C', -0.0, 0.9624812375788672], ['A', 'D', 2.0, 0.012141012751323066]]\n" ] } ], @@ -314,7 +314,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 53, "metadata": {}, "outputs": [ { @@ -323,9 +323,9 @@ "text": [ "Which variables are active \n", " [[ True True True True]\n", + " [ True False True True]\n", " [ True True True True]\n", - " [ True True True True]\n", - " [ True True True True]\n", + " [ True False True True]\n", " [ True True True True]]\n" ] } @@ -339,7 +339,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 54, "metadata": {}, "outputs": [ { @@ -381,7 +381,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 68, "metadata": {}, "outputs": [ { @@ -400,7 +400,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 69, "metadata": {}, "outputs": [], "source": [ @@ -409,7 +409,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 70, "metadata": {}, "outputs": [ { @@ -417,11 +417,11 @@ "output_type": "stream", "text": [ "Data encoded: \n", - " [[0.6211392 0.99609568 3.79829878]\n", - " [0.70086578 1.5552522 0.77369391]\n", - " [0.74386417 0.43386098 1.77447691]\n", - " [0.56025309 0.11930465 1.25259765]\n", - " [0.23214073 1.88632861 1.48669667]]\n", + " [[0.87450777 0.5580441 1.89993119]\n", + " [0.83090714 1.14443431 4.59216557]\n", + " [0.36138225 1.7307304 4.26503332]\n", + " [0.6663468 1.76684207 1.24310083]\n", + " [0.39783524 1.05625929 1.07178548]]\n", "Is_acting: \n", " [[ True True True]\n", " [ True True True]\n", @@ -445,20 +445,20 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 71, "metadata": {}, "outputs": [ { "data": { "text/html": [ - "
\n", + "
\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", + "\n" + ], + "text/plain": [ + "" + ] + }, + "metadata": {}, + "output_type": "display_data" } ], "source": [ - "print(design_space)\n", - "print(gp.dv_is_conditionally_active)" + "design_space = ArchDesignSpaceGraph(adsg=adsg)\n", + "design_space._sample_valid_x(1,return_render=True)[2][0].render()" ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] } ], "metadata": { From d6efc167515be181ac20b2ecfb9fa348c9bc13f9 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Mon, 19 Aug 2024 11:19:59 +0200 Subject: [PATCH 15/77] ruff' ' --- smt/utils/design_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index 197d95a99..9e41d7ced 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -1330,7 +1330,7 @@ def _sample_valid_x( return np.array(configs1), np.array(configs2), np.array(configs0) else : return np.array(configs1), np.array(configs2) - + def _is_conditionally_acting(self) -> np.ndarray: # Decreed variables are the conditionally acting variables return np.array(self.graph_proc.dv_is_conditionally_active) From aab216cd4c66c71d781b5105b4c6343e860d0b6f Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Mon, 19 Aug 2024 12:38:10 +0200 Subject: [PATCH 16/77] assert --- smt/utils/test/test_design_space.py | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/smt/utils/test/test_design_space.py b/smt/utils/test/test_design_space.py index 97d3271cc..04f66f302 100644 --- a/smt/utils/test/test_design_space.py +++ b/smt/utils/test/test_design_space.py @@ -424,7 +424,10 @@ def test_design_space_hierarchical(self): for i, xi in enumerate(x_sampled): seen_x.add(tuple(xi)) seen_is_acting.add(tuple(is_acting_sampled[i, :])) - assert len(seen_x) == 42 + if HAS_ADSG : + assert len(seen_x) == 49 + else : + assert len(seen_x) == 42 assert len(seen_is_acting) == 2 @unittest.skipIf( @@ -630,7 +633,7 @@ def test_restrictive_value_constraint_ordinal(self): ), x_cartesian2, ) - +ConfigSpace @unittest.skipIf( not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" ) From c6480493e0baff2e2a7c5d6c7e95616050329923 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Mon, 19 Aug 2024 12:38:43 +0200 Subject: [PATCH 17/77] assert --- smt/utils/test/test_design_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smt/utils/test/test_design_space.py b/smt/utils/test/test_design_space.py index 04f66f302..c7a317159 100644 --- a/smt/utils/test/test_design_space.py +++ b/smt/utils/test/test_design_space.py @@ -633,7 +633,7 @@ def test_restrictive_value_constraint_ordinal(self): ), x_cartesian2, ) -ConfigSpace + @unittest.skipIf( not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" ) From ac7996fffd04b6c4243c60e272d95d23fb6ccf3e Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Fri, 23 Aug 2024 11:46:24 +0200 Subject: [PATCH 18/77] Merge branch 'master' into master-3 --- tutorial/SMT_DesignSpace_example.ipynb | 156 +++++++++++++++++-------- 1 file changed, 107 insertions(+), 49 deletions(-) diff --git a/tutorial/SMT_DesignSpace_example.ipynb b/tutorial/SMT_DesignSpace_example.ipynb index 8defe08bd..96641caed 100644 --- a/tutorial/SMT_DesignSpace_example.ipynb +++ b/tutorial/SMT_DesignSpace_example.ipynb @@ -77,7 +77,82 @@ "name": "stdout", "output_type": "stream", "text": [ - + "Requirement already satisfied: configspace==0.6.1 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (0.6.1)\n", + "Requirement already satisfied: numpy in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from configspace==0.6.1) (1.23.5)\n", + "Requirement already satisfied: pyparsing in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from configspace==0.6.1) (3.0.9)\n", + "Requirement already satisfied: scipy in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from configspace==0.6.1) (1.11.3)\n", + "Requirement already satisfied: typing-extensions in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from configspace==0.6.1) (4.11.0)\n", + "Requirement already satisfied: more-itertools in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from configspace==0.6.1) (8.12.0)\n", + "Requirement already satisfied: smt in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (2.6.2)\n", + "Requirement already satisfied: scikit-learn in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.4.0)\n", + "Requirement already satisfied: pyDOE3 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.0.3)\n", + "Requirement already satisfied: scipy in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.11.3)\n", + "Requirement already satisfied: jenn in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.0.6)\n", + "Requirement already satisfied: jsonpointer>=2.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (3.0.0)\n", + "Requirement already satisfied: jsonschema>=4.22 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (4.22.0)\n", + "Requirement already satisfied: orjson>=3.9 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (3.10.6)\n", + "Requirement already satisfied: numpy>=1.22 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (1.23.5)\n", + "Requirement already satisfied: joblib>=1.2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from scikit-learn->smt) (1.4.2)\n", + "Requirement already satisfied: threadpoolctl>=2.0.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from scikit-learn->smt) (3.5.0)\n", + "Requirement already satisfied: attrs>=22.2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (23.1.0)\n", + "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (2023.12.1)\n", + "Requirement already satisfied: referencing>=0.28.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.35.1)\n", + "Requirement already satisfied: rpds-py>=0.7.1 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.18.1)\n", + "Collecting git+https://github.com/jbussemaker/adsg-core.git@dev\n", + " Cloning https://github.com/jbussemaker/adsg-core.git (to revision dev) to /tmp/pip-req-build-ir_ifw9y\n", + " Running command git clone --filter=blob:none --quiet https://github.com/jbussemaker/adsg-core.git /tmp/pip-req-build-ir_ifw9y\n", + " Running command git checkout -b dev --track origin/dev\n", + " Switched to a new branch 'dev'\n", + " Branch 'dev' set up to track remote branch 'dev' from 'origin'.\n", + " Resolved https://github.com/jbussemaker/adsg-core.git to commit b3df09cb1a7aeb35868a6da12ce13cee7bd6b4d3\n", + " Installing build dependencies ... \u001b[?25ldone\n", + "\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n", + "\u001b[?25h Preparing metadata (pyproject.toml) ... \u001b[?25ldone\n", + "\u001b[?25hRequirement already satisfied: networkx~=2.6 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (2.8.8)\n", + "Requirement already satisfied: lxml in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (5.2.2)\n", + "Requirement already satisfied: pydot in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (3.0.1)\n", + "Requirement already satisfied: cached-property>=1.5 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (1.5.2)\n", + "Requirement already satisfied: appdirs in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (1.4.4)\n", + "Requirement already satisfied: numpy<2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (1.23.5)\n", + "Requirement already satisfied: scipy~=1.9 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (1.11.3)\n", + "Requirement already satisfied: pandas in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (2.2.2)\n", + "Requirement already satisfied: numba~=0.56 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from adsg-core==1.1.0) (0.60.0)\n", + "Requirement already satisfied: llvmlite<0.44,>=0.43.0dev0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from numba~=0.56->adsg-core==1.1.0) (0.43.0)\n", + "Requirement already satisfied: python-dateutil>=2.8.2 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from pandas->adsg-core==1.1.0) (2.8.2)\n", + "Requirement already satisfied: pytz>=2020.1 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from pandas->adsg-core==1.1.0) (2024.1)\n", + "Requirement already satisfied: tzdata>=2022.7 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from pandas->adsg-core==1.1.0) (2024.1)\n", + "Requirement already satisfied: pyparsing>=3.0.9 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from pydot->adsg-core==1.1.0) (3.0.9)\n", + "Requirement already satisfied: six>=1.5 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from python-dateutil>=2.8.2->pandas->adsg-core==1.1.0) (1.16.0)\n", + "Requirement already satisfied: smt in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (2.6.2)\n", + "Requirement already satisfied: scikit-learn in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.4.0)\n", + "Requirement already satisfied: pyDOE3 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.0.3)\n", + "Requirement already satisfied: scipy in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.11.3)\n", + "Requirement already satisfied: jenn in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.0.6)\n", + "Requirement already satisfied: jsonpointer>=2.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (3.0.0)\n", + "Requirement already satisfied: jsonschema>=4.22 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (4.22.0)\n", + "Requirement already satisfied: orjson>=3.9 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (3.10.6)\n", + "Requirement already satisfied: numpy>=1.22 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (1.23.5)\n", + "Requirement already satisfied: joblib>=1.2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from scikit-learn->smt) (1.4.2)\n", + "Requirement already satisfied: threadpoolctl>=2.0.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from scikit-learn->smt) (3.5.0)\n", + "Requirement already satisfied: attrs>=22.2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (23.1.0)\n", + "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (2023.12.1)\n", + "Requirement already satisfied: referencing>=0.28.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.35.1)\n", + "Requirement already satisfied: rpds-py>=0.7.1 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.18.1)\n" + ] + } + ], + "source": [ + "!pip install configspace==0.6.1\n", + "#!pip install adsg_core --pre\n", + "#!pip install adsg-core[nb]\n", + "\n", + "#to install smt\n", + "!pip install smt\n", + "\n", + "!pip install git+https://github.com/jbussemaker/adsg-core.git@dev\n", + "\n", + "#to have the latest version\n", + "!pip install smt --pre\n" ] }, { @@ -144,7 +219,6 @@ "\n", "from smt.utils.design_space import (\n", " ArchDesignSpaceGraph,\n", - " DesignSpace,\n", " FloatVariable,\n", " IntegerVariable,\n", @@ -155,7 +229,6 @@ "import plotly.io as pio\n", "pio.renderers.default='notebook'\n", "from smt.utils.design_space import ensure_design_space\n" - ] }, { @@ -197,24 +270,18 @@ } ], "source": [ - "# Instantiate the design space with all its design variables:\n", - "\n", - "ds = DesignSpace(\n", - " [\n", - " CategoricalVariable(\n", - " [\"A\", \"B\"]\n", - " ), # x0 categorical: A or B; order is not relevant\n", - " OrdinalVariable([\"C\", \"D\", \"E\"]), # x1 ordinal: C, D or E; order is relevant\n", - " IntegerVariable(0, 2), # x2 integer between 0 and 2 (inclusive): 0, 1, 2\n", - " FloatVariable(0, 1), # c3 continuous between 0 and 1\n", - " ]\n", - ")\n", - "\n", - "print(\"Number of design variables\", len(ds.design_variables))\n", - "# You can define decreed variables (conditional activation):\n", - "ds.declare_decreed_var(\n", - " decreed_var=1, meta_var=0, meta_value=\"A\"\n", - ") # Activate x1 if x0 == A" + "#Instantiate the design space with all its design variables:\n", + "\n", + "ds = DesignSpace([\n", + " CategoricalVariable(['A', 'B']), # x0 categorical: A or B; order is not relevant\n", + " OrdinalVariable(['C', 'D', 'E']), # x1 ordinal: C, D or E; order is relevant\n", + " IntegerVariable(0, 2), # x2 integer between 0 and 2 (inclusive): 0, 1, 2\n", + " FloatVariable(0, 1), # c3 continuous between 0 and 1\n", + " ])\n", + "\n", + "print(\"Number of design variables\",len(ds.design_variables))\n", + "#You can define decreed variables (conditional activation):\n", + "ds.declare_decreed_var(decreed_var=1, meta_var=0, meta_value='A') # Activate x1 if x0 == A" ] }, { @@ -227,24 +294,24 @@ "output_type": "stream", "text": [ "Data encoded: \n", - " [[0. 2. 1. 0.50141714]\n", - " [1. 0. 1. 0.48517298]\n", - " [0. 1. 2. 0.83539973]\n", - " [0. 0. 1. 0.65900747]\n", - " [0. 2. 1. 0.5664969 ]]\n", + " [[ 0. 1. 2. 0.72339664]\n", + " [ 0. 2. 1. 0.48105205]\n", + " [ 1. 0. 2. 0.17240634]\n", + " [ 1. 0. -0. 0.87990382]\n", + " [ 1. 0. 2. 0.16811015]]\n", "Data in initial space: \n", - " [['A', 'E', 1.0, 0.5014171417556681], ['B', 'C', 1.0, 0.48517297677504534], ['A', 'D', 2.0, 0.835399731580032], ['A', 'C', 1.0, 0.6590074713239295], ['A', 'E', 1.0, 0.5664968989411066]]\n" + " [['A', 'D', 2.0, 0.7233966383505663], ['A', 'E', 1.0, 0.48105205278872476], ['B', 'C', 2.0, 0.17240633644362413], ['B', 'C', -0.0, 0.8799038248668171], ['B', 'C', 2.0, 0.16811014980997951]]\n" ] } ], "source": [ "## To give some examples\n", - "# It is also possible to randomly sample design vectors conforming to the constraints:\n", + "#It is also possible to randomly sample design vectors conforming to the constraints:\n", "n = 5\n", "x_sampled, is_acting_sampled = ds.sample_valid_x(5)\n", "\n", - "print(\"Data encoded: \\n\", x_sampled)\n", - "print(\"Data in initial space: \\n\", ds.decode_values(x_sampled))" + "print('Data encoded: \\n', x_sampled)\n", + "print('Data in initial space: \\n', ds.decode_values(x_sampled))" ] }, { @@ -266,9 +333,9 @@ } ], "source": [ - "# After defining everything correctly, you can then use the design space object\n", - "# to correct design vectors and get information about which design variables are acting:\n", - "x_corr, is_acting = ds.correct_get_acting(x_sampled)\n", + "#After defining everything correctly, you can then use the design space object \n", + "#to correct design vectors and get information about which design variables are acting:\n", + "x_corr, is_acting = ds.correct_get_acting(x_sampled) \n", "print(\"Which variables are active \\n\", is_acting)" ] }, @@ -298,16 +365,13 @@ } ], "source": [ - "# If needed, it is possible to get the legacy design space definition format:\n", + "#If needed, it is possible to get the legacy design space definition format:\n", "xlimits = ds.get_x_limits()\n", "cont_bounds = ds.get_num_bounds()\n", "unfolded_cont_bounds = ds.get_unfolded_num_bounds()\n", "print(\"Limits of each variable \\n\", xlimits)\n", "print(\"Continuous bounds with the encoding done (4 variables now) \\n\", cont_bounds)\n", - "print(\n", - " \"Continuous bounds with the unfolded encoding done (5 variables now)\\n\",\n", - " unfolded_cont_bounds,\n", - ")" + "print(\"Continuous bounds with the unfolded encoding done (5 variables now)\\n\", unfolded_cont_bounds)" ] }, { @@ -331,14 +395,9 @@ } ], "source": [ - "# You can also instantiate a purely-continuous design space from bounds directly:\n", - "continuous_design_space = DesignSpace([(0, 1), (0, 2), (0.5, 5.5)])\n", - "print(\n", - " \"Number of design variables =\",\n", - " continuous_design_space.n_dv,\n", - " \" or \",\n", - " len(continuous_design_space.design_variables),\n", - ")" + "#You can also instantiate a purely-continuous design space from bounds directly:\n", + "continuous_design_space = DesignSpace([(0, 1), (0, 2), (.5, 5.5)])\n", + "print(\"Number of design variables =\",continuous_design_space.n_dv, ' or ', len(continuous_design_space.design_variables))" ] }, { @@ -365,7 +424,6 @@ " [0.55936887 0.8485448 4.47086478]\n", " [0.60566526 0.20722261 5.13021323]\n", " [0.54840481 1.10410051 4.93602065]]\n", - "Is_acting: \n", " [[ True True True]\n", " [ True True True]\n", @@ -376,8 +434,8 @@ } ], "source": [ - "print(\"Data encoded: \\n\", x_sampled_cont)\n", - "print(\"Is_acting: \\n\", is_acting_sampled_cont)" + "print('Data encoded: \\n', x_sampled_cont)\n", + "print('Is_acting: \\n', is_acting_sampled_cont)" ] }, { From 7012809e31548e8a7cf73f1ed84dc5ad7e927004 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Fri, 23 Aug 2024 13:28:13 +0200 Subject: [PATCH 19/77] ruff 0.6.2 --- smt/utils/design_space.py | 9 +- smt/utils/test/test_design_space.py | 4 +- tutorial/SMT_DesignSpace_example.ipynb | 317 +++++++++++++------------ 3 files changed, 172 insertions(+), 158 deletions(-) diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index 9e41d7ced..597ed3fb7 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -1309,7 +1309,10 @@ def __init__( self._is_decreed = design_space._is_decreed def _sample_valid_x( - self, n: int, random_state=None, return_render=False, + self, + n: int, + random_state=None, + return_render=False, ) -> Tuple[np.ndarray, np.ndarray]: """Sample design vectors""" # Get design vectors and get the is_active matrix @@ -1326,9 +1329,9 @@ def _sample_valid_x( configs2.append( self.graph_proc.get_graph(self.graph_proc.get_random_design_vector())[2] ) - if return_render : + if return_render: return np.array(configs1), np.array(configs2), np.array(configs0) - else : + else: return np.array(configs1), np.array(configs2) def _is_conditionally_acting(self) -> np.ndarray: diff --git a/smt/utils/test/test_design_space.py b/smt/utils/test/test_design_space.py index c7a317159..008066f00 100644 --- a/smt/utils/test/test_design_space.py +++ b/smt/utils/test/test_design_space.py @@ -424,9 +424,9 @@ def test_design_space_hierarchical(self): for i, xi in enumerate(x_sampled): seen_x.add(tuple(xi)) seen_is_acting.add(tuple(is_acting_sampled[i, :])) - if HAS_ADSG : + if HAS_ADSG: assert len(seen_x) == 49 - else : + else: assert len(seen_x) == 42 assert len(seen_is_acting) == 2 diff --git a/tutorial/SMT_DesignSpace_example.ipynb b/tutorial/SMT_DesignSpace_example.ipynb index 96641caed..fab7ce341 100644 --- a/tutorial/SMT_DesignSpace_example.ipynb +++ b/tutorial/SMT_DesignSpace_example.ipynb @@ -99,12 +99,12 @@ "Requirement already satisfied: referencing>=0.28.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.35.1)\n", "Requirement already satisfied: rpds-py>=0.7.1 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.18.1)\n", "Collecting git+https://github.com/jbussemaker/adsg-core.git@dev\n", - " Cloning https://github.com/jbussemaker/adsg-core.git (to revision dev) to /tmp/pip-req-build-ir_ifw9y\n", - " Running command git clone --filter=blob:none --quiet https://github.com/jbussemaker/adsg-core.git /tmp/pip-req-build-ir_ifw9y\n", + " Cloning https://github.com/jbussemaker/adsg-core.git (to revision dev) to /tmp/pip-req-build-r6vxrr33\n", + " Running command git clone --filter=blob:none --quiet https://github.com/jbussemaker/adsg-core.git /tmp/pip-req-build-r6vxrr33\n", " Running command git checkout -b dev --track origin/dev\n", " Switched to a new branch 'dev'\n", " Branch 'dev' set up to track remote branch 'dev' from 'origin'.\n", - " Resolved https://github.com/jbussemaker/adsg-core.git to commit b3df09cb1a7aeb35868a6da12ce13cee7bd6b4d3\n", + " Resolved https://github.com/jbussemaker/adsg-core.git to commit 01cb8af781f47701317e7f5ac5f4d82ef300d38f\n", " Installing build dependencies ... \u001b[?25ldone\n", "\u001b[?25h Getting requirements to build wheel ... \u001b[?25ldone\n", "\u001b[?25h Preparing metadata (pyproject.toml) ... \u001b[?25ldone\n", @@ -146,13 +146,13 @@ "#!pip install adsg_core --pre\n", "#!pip install adsg-core[nb]\n", "\n", - "#to install smt\n", + "# to install smt\n", "!pip install smt\n", "\n", "!pip install git+https://github.com/jbussemaker/adsg-core.git@dev\n", "\n", - "#to have the latest version\n", - "!pip install smt --pre\n" + "# to have the latest version\n", + "!pip install smt --pre" ] }, { @@ -183,39 +183,8 @@ "metadata": {}, "outputs": [], "source": [ - "#to ignore warning messages\n", - "import warnings\n", - "warnings.filterwarnings(\"ignore\")\n", - "\n", - "import os\n", - "import unittest\n", - "import numpy as np\n", - "from sys import argv\n", - "import matplotlib.pyplot as plt\n", - "import time\n", "%matplotlib inline\n", "\n", - "from smt.applications import EGO\n", - "from smt.applications.ego import Evaluator\n", - "from smt.utils.sm_test_case import SMTestCase\n", - "from smt.problems import Branin, Rosenbrock, HierarchicalGoldstein\n", - "from smt.sampling_methods import FullFactorial\n", - "from multiprocessing import Pool\n", - "from smt.sampling_methods import LHS\n", - "import itertools\n", - "from smt.surrogate_models import (\n", - " KRG,\n", - " GEKPLS,\n", - " KPLS,\n", - " QP,\n", - " MixIntKernelType,\n", - " MixHrcKernelType,\n", - ")\n", - "from smt.applications.mixed_integer import (\n", - " MixedIntegerContext,\n", - " MixedIntegerSamplingMethod,\n", - " MixedIntegerKrigingModel\n", - ")\n", "\n", "from smt.utils.design_space import (\n", " ArchDesignSpaceGraph,\n", @@ -225,10 +194,15 @@ " OrdinalVariable,\n", " CategoricalVariable,\n", ")\n", - "from adsg_core.graph.graph_edges import EdgeType\n", + "\n", "import plotly.io as pio\n", - "pio.renderers.default='notebook'\n", - "from smt.utils.design_space import ensure_design_space\n" + "\n", + "# to ignore warning messages\n", + "import warnings\n", + "\n", + "warnings.filterwarnings(\"ignore\")\n", + "\n", + "pio.renderers.default = \"notebook\"" ] }, { @@ -270,18 +244,24 @@ } ], "source": [ - "#Instantiate the design space with all its design variables:\n", - "\n", - "ds = DesignSpace([\n", - " CategoricalVariable(['A', 'B']), # x0 categorical: A or B; order is not relevant\n", - " OrdinalVariable(['C', 'D', 'E']), # x1 ordinal: C, D or E; order is relevant\n", - " IntegerVariable(0, 2), # x2 integer between 0 and 2 (inclusive): 0, 1, 2\n", - " FloatVariable(0, 1), # c3 continuous between 0 and 1\n", - " ])\n", - "\n", - "print(\"Number of design variables\",len(ds.design_variables))\n", - "#You can define decreed variables (conditional activation):\n", - "ds.declare_decreed_var(decreed_var=1, meta_var=0, meta_value='A') # Activate x1 if x0 == A" + "# Instantiate the design space with all its design variables:\n", + "\n", + "ds = DesignSpace(\n", + " [\n", + " CategoricalVariable(\n", + " [\"A\", \"B\"]\n", + " ), # x0 categorical: A or B; order is not relevant\n", + " OrdinalVariable([\"C\", \"D\", \"E\"]), # x1 ordinal: C, D or E; order is relevant\n", + " IntegerVariable(0, 2), # x2 integer between 0 and 2 (inclusive): 0, 1, 2\n", + " FloatVariable(0, 1), # c3 continuous between 0 and 1\n", + " ]\n", + ")\n", + "\n", + "print(\"Number of design variables\", len(ds.design_variables))\n", + "# You can define decreed variables (conditional activation):\n", + "ds.declare_decreed_var(\n", + " decreed_var=1, meta_var=0, meta_value=\"A\"\n", + ") # Activate x1 if x0 == A" ] }, { @@ -294,24 +274,24 @@ "output_type": "stream", "text": [ "Data encoded: \n", - " [[ 0. 1. 2. 0.72339664]\n", - " [ 0. 2. 1. 0.48105205]\n", - " [ 1. 0. 2. 0.17240634]\n", - " [ 1. 0. -0. 0.87990382]\n", - " [ 1. 0. 2. 0.16811015]]\n", + " [[ 1. 0. -0. 0.94502275]\n", + " [ 1. 0. -0. 0.65314755]\n", + " [ 1. 0. 1. 0.94803344]\n", + " [ 1. 0. 2. 0.74665591]\n", + " [ 0. 2. 2. 0.62429367]]\n", "Data in initial space: \n", - " [['A', 'D', 2.0, 0.7233966383505663], ['A', 'E', 1.0, 0.48105205278872476], ['B', 'C', 2.0, 0.17240633644362413], ['B', 'C', -0.0, 0.8799038248668171], ['B', 'C', 2.0, 0.16811014980997951]]\n" + " [['B', 'C', -0.0, 0.9450227460759346], ['B', 'C', -0.0, 0.6531475548727604], ['B', 'C', 1.0, 0.9480334401750217], ['B', 'C', 2.0, 0.7466559097987561], ['A', 'E', 2.0, 0.6242936690099832]]\n" ] } ], "source": [ "## To give some examples\n", - "#It is also possible to randomly sample design vectors conforming to the constraints:\n", + "# It is also possible to randomly sample design vectors conforming to the constraints:\n", "n = 5\n", "x_sampled, is_acting_sampled = ds.sample_valid_x(5)\n", "\n", - "print('Data encoded: \\n', x_sampled)\n", - "print('Data in initial space: \\n', ds.decode_values(x_sampled))" + "print(\"Data encoded: \\n\", x_sampled)\n", + "print(\"Data in initial space: \\n\", ds.decode_values(x_sampled))" ] }, { @@ -324,18 +304,18 @@ "output_type": "stream", "text": [ "Which variables are active \n", - " [[ True True True True]\n", - " [ True True True True]\n", + " [[ True False True True]\n", + " [ True False True True]\n", " [ True False True True]\n", " [ True False True True]\n", - " [ True False True True]]\n" + " [ True True True True]]\n" ] } ], "source": [ - "#After defining everything correctly, you can then use the design space object \n", - "#to correct design vectors and get information about which design variables are acting:\n", - "x_corr, is_acting = ds.correct_get_acting(x_sampled) \n", + "# After defining everything correctly, you can then use the design space object\n", + "# to correct design vectors and get information about which design variables are acting:\n", + "x_corr, is_acting = ds.correct_get_acting(x_sampled)\n", "print(\"Which variables are active \\n\", is_acting)" ] }, @@ -365,13 +345,16 @@ } ], "source": [ - "#If needed, it is possible to get the legacy design space definition format:\n", + "# If needed, it is possible to get the legacy design space definition format:\n", "xlimits = ds.get_x_limits()\n", "cont_bounds = ds.get_num_bounds()\n", "unfolded_cont_bounds = ds.get_unfolded_num_bounds()\n", "print(\"Limits of each variable \\n\", xlimits)\n", "print(\"Continuous bounds with the encoding done (4 variables now) \\n\", cont_bounds)\n", - "print(\"Continuous bounds with the unfolded encoding done (5 variables now)\\n\", unfolded_cont_bounds)" + "print(\n", + " \"Continuous bounds with the unfolded encoding done (5 variables now)\\n\",\n", + " unfolded_cont_bounds,\n", + ")" ] }, { @@ -395,9 +378,14 @@ } ], "source": [ - "#You can also instantiate a purely-continuous design space from bounds directly:\n", - "continuous_design_space = DesignSpace([(0, 1), (0, 2), (.5, 5.5)])\n", - "print(\"Number of design variables =\",continuous_design_space.n_dv, ' or ', len(continuous_design_space.design_variables))" + "# You can also instantiate a purely-continuous design space from bounds directly:\n", + "continuous_design_space = DesignSpace([(0, 1), (0, 2), (0.5, 5.5)])\n", + "print(\n", + " \"Number of design variables =\",\n", + " continuous_design_space.n_dv,\n", + " \" or \",\n", + " len(continuous_design_space.design_variables),\n", + ")" ] }, { @@ -419,11 +407,11 @@ "output_type": "stream", "text": [ "Data encoded: \n", - " [[0.59113267 0.889812 1.43795594]\n", - " [0.92579169 1.04417172 4.43938601]\n", - " [0.55936887 0.8485448 4.47086478]\n", - " [0.60566526 0.20722261 5.13021323]\n", - " [0.54840481 1.10410051 4.93602065]]\n", + " [[0.32273725 1.13803607 0.6039725 ]\n", + " [0.1895724 1.63284148 3.92965975]\n", + " [0.01270165 0.76386364 5.27401859]\n", + " [0.90201543 1.23767912 1.84026453]\n", + " [0.18923128 0.79938574 3.65151063]]\n", "Is_acting: \n", " [[ True True True]\n", " [ True True True]\n", @@ -434,8 +422,8 @@ } ], "source": [ - "print('Data encoded: \\n', x_sampled_cont)\n", - "print('Is_acting: \\n', is_acting_sampled_cont)" + "print(\"Data encoded: \\n\", x_sampled_cont)\n", + "print(\"Is_acting: \\n\", is_acting_sampled_cont)" ] }, { @@ -453,14 +441,14 @@ { "data": { "text/html": [ - "
\n", + "
\n", "\n", "\n", "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "from adsg_core import BasicADSG, NamedNode, DesignVariableNode\n", - "\n", - "# Create the ADSG\n", - "adsg = BasicADSG()\n", - "\n", - "ndv = 13\n", - "\n", - "\n", - "# Create nodes\n", - "n = [NamedNode(f\"N{i}\") for i in range(ndv)]\n", - "n = [\n", - " NamedNode(\"MLP\"),\n", - " NamedNode(\"Learning_rate\"),\n", - " NamedNode(\"Activation_function\"),\n", - " NamedNode(\"Optimizer\"),\n", - " NamedNode(\"Decay\"),\n", - " NamedNode(\"Power_update\"),\n", - " NamedNode(\"Average_start\"),\n", - " NamedNode(\"Running_Average_1\"),\n", - " NamedNode(\"Running_Average_2\"),\n", - " NamedNode(\"Numerical_Stability\"),\n", - " NamedNode(\"Nb_layers\"),\n", - " NamedNode(\"Layer_1\"),\n", - " NamedNode(\"Layer_2\"),\n", - " NamedNode(\"Layer_3\"), # NamedNode(\"Dropout\"),\n", - " NamedNode(\"ASGD\"),\n", - " NamedNode(\"Adam\"),\n", - " NamedNode(\"20...40\"),\n", - " NamedNode(\"40\"),\n", - " NamedNode(\"45\"),\n", - " NamedNode(\"20...40\"),\n", - " NamedNode(\"40\"),\n", - " NamedNode(\"45\"),\n", - " NamedNode(\"20...40\"),\n", - " NamedNode(\"40\"),\n", - " NamedNode(\"45\"),\n", - "]\n", - "adsg.add_node(n[1])\n", - "adsg.add_node(n[2])\n", - "# adsg.add_node(n[3])\n", - "\n", - "# Add some edges\n", - "adsg.add_edges(\n", - " [\n", - " # (n[0], n[1]),\n", - " # (n[0], n[2]),\n", - " # (n[0], n[3]),\n", - " (n[3], n[10]),\n", - " (n[14], n[4]),\n", - " (n[14], n[5]),\n", - " (n[14], n[6]),\n", - " (n[15], n[7]),\n", - " (n[15], n[8]),\n", - " (n[15], n[9]),\n", - " ]\n", - ")\n", - "\n", - "choiceo = adsg.add_selection_choice(\"Optimizer_Choice\", n[3], [n[14], n[15]])\n", - "\n", - "\n", - "choicenl = adsg.add_selection_choice(\"#layers\", n[10], [n[11], n[12], n[13]])\n", - "# adsg.add_edges([ (n[12],n[11]), (n[13],n[12]) ])\n", - "a = []\n", - "for i in range(3):\n", - " a.append(NamedNode(str(25 + 5 * i)))\n", - "b = a.copy()\n", - "b.append(n[17])\n", - "b.append(n[18])\n", - "choicel1 = adsg.add_selection_choice(\"#neurons_1\", n[11], b)\n", - "adsg.add_edges([(n[12], choicel1), (n[13], choicel1)])\n", - "\n", - "\n", - "a = []\n", - "for i in range(3):\n", - " a.append(NamedNode(str(25 + 5 * i)))\n", - "b = a.copy()\n", - "b.append(n[20])\n", - "b.append(n[21])\n", - "choicel1 = adsg.add_selection_choice(\"#neurons_2\", n[12], b)\n", - "adsg.add_edges([(n[13], choicel1)])\n", - "\n", - "a = []\n", - "for i in range(3):\n", - " a.append(NamedNode(str(25 + 5 * i)))\n", - "b = a.copy()\n", - "b.append(n[23])\n", - "b.append(n[24])\n", - "choicel1 = adsg.add_selection_choice(\"#neurons_3\", n[13], b)\n", - "\n", - "# adsg.add_edges([ (n[18],n[17]), (n[17],n[16]) ])\n", - "# adsg.add_edges([ (n[21],n[20]), (n[20],n[19]) ])\n", - "# adsg.add_edges([ (n[24],n[23]), (n[23],n[22]) ])\n", - "\n", - "adsg.add_incompatibility_constraint([n[15], n[13]])\n", - "adsg.add_incompatibility_constraint([n[14], n[17]])\n", - "adsg.add_incompatibility_constraint([n[14], n[18]])\n", - "adsg.add_incompatibility_constraint([n[14], n[20]])\n", - "adsg.add_incompatibility_constraint([n[14], n[21]])\n", - "adsg.add_incompatibility_constraint([n[14], n[23]])\n", - "adsg.add_incompatibility_constraint([n[14], n[24]])\n", - "start_nodes = set()\n", - "start_nodes.add(n[3])\n", - "start_nodes.add(n[2])\n", - "start_nodes.add(n[1])\n", - "# start_nodes.add(n[0])\n", - "\n", - "\n", - "adsg.add_edges(\n", - " [\n", - " (n[1], DesignVariableNode(\"x0\", bounds=(0, 1))),\n", - " (n[4], DesignVariableNode(\"x1\", bounds=(0, 1))),\n", - " (n[5], DesignVariableNode(\"x2\", bounds=(0, 1))),\n", - " (n[6], DesignVariableNode(\"x3\", bounds=(0, 1))),\n", - " (n[7], DesignVariableNode(\"x4\", bounds=(0, 1))),\n", - " (n[8], DesignVariableNode(\"x5\", bounds=(0, 1))),\n", - " (n[9], DesignVariableNode(\"x6\", bounds=(0, 1))),\n", - " # (n[11], DesignVariableNode('x7', options=(\"0\", \"1\"))),\n", - " ]\n", - ")\n", - "\n", - "choiceo = adsg.add_selection_choice(\n", - " \"Activation_Choice\",\n", - " n[2],\n", - " [NamedNode(\"ReLU\"), NamedNode(\"Sigmoid\"), NamedNode(\"Tanh\")],\n", - ")\n", - "\n", - "adsg = adsg.set_start_nodes(start_nodes)\n", - "adsg.render()" - ] - }, - { - "cell_type": "code", - "execution_count": 11, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Design variables: [DV: #layers [3 opts], DV: Activation_Choice [3 opts], DV: Optimizer_Choice [2 opts], DV: #neurons_1 [5 opts], DV: #neurons_2 [5 opts]]\n", - "DV: #neurons_3 [5 opts], DV: x0 [0.00..1.00], DV: x1 [0.00..1.00], DV: x2 [0.00..1.00], DV: x3 [0.00..1.00], DV: x4 [0.00..1.00], DV: x5 [0.00..1.00], DV: x6 [0.00..1.00]]\n", - "Objectives: []\n", - "Constraints: []\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_validn_declaredn_discreten_dim_contn_dim_cont_meann_existimp_ratioimp_ratio_combimp_ratio_continf_idxdist_correncoder
type
option-decisions2071350600.016.5217396.5217391.000.5319860.0complete
additional-dvs2070074.02071.7500001.0000001.751.0000000.0
total-design-space2072250674.0119.02173910.8695651.750.4933050.0complete
total-design-problem2072250674.0119.02173910.8695651.750.4933050.0complete
\n", - "
" - ], - "text/plain": [ - " n_valid n_declared n_discrete n_dim_cont \\\n", - "type \n", - "option-decisions 207 1350 6 0 \n", - "additional-dvs 207 0 0 7 \n", - "total-design-space 207 2250 6 7 \n", - "total-design-problem 207 2250 6 7 \n", - "\n", - " n_dim_cont_mean n_exist imp_ratio imp_ratio_comb \\\n", - "type \n", - "option-decisions 0.0 1 6.521739 6.521739 \n", - "additional-dvs 4.0 207 1.750000 1.000000 \n", - "total-design-space 4.0 1 19.021739 10.869565 \n", - "total-design-problem 4.0 1 19.021739 10.869565 \n", - "\n", - " imp_ratio_cont inf_idx dist_corr encoder \n", - "type \n", - "option-decisions 1.00 0.531986 0.0 complete \n", - "additional-dvs 1.75 1.000000 0.0 \n", - "total-design-space 1.75 0.493305 0.0 complete \n", - "total-design-problem 1.75 0.493305 0.0 complete " - ] - }, - "execution_count": 11, - "metadata": {}, - "output_type": "execute_result" - } - ], - "source": [ - "from adsg_core import GraphProcessor\n", - "\n", - "gp = GraphProcessor(adsg)\n", - "\n", - "print(\"Design variables:\", gp.des_vars[0:5])\n", - "print(str(gp.des_vars[5:])[1:])\n", - "print(\"Objectives:\", gp.objectives)\n", - "print(\"Constraints:\", gp.constraints)\n", - "\n", - "# Display some details about the encoders used for\n", - "# formulating the optimization problem\n", - "gp.get_statistics()" - ] - }, - { - "cell_type": "code", - "execution_count": 12, - "metadata": {}, - "outputs": [ - { - "data": { - "text/html": [ - "
\n", - "\n", - "\n" - ], - "text/plain": [ - "" - ] - }, - "metadata": {}, - "output_type": "display_data" - } - ], - "source": [ - "design_space = ArchDesignSpaceGraph(adsg=adsg)\n", - "design_space._sample_valid_x(1, return_render=True)[2][0].render()" - ] - } - ], - "metadata": { - "colab": { - "include_colab_link": true, - "name": "SMT_DesignSpace_example.ipynb", - "provenance": [] - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.18" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} From 6ea35b59b58afb5c26a40dc052832e63c182e25d Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 10:36:31 +0200 Subject: [PATCH 22/77] add import --- .github/workflows/tests_coverage.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.github/workflows/tests_coverage.yml b/.github/workflows/tests_coverage.yml index 4bd893df2..20124338b 100644 --- a/.github/workflows/tests_coverage.yml +++ b/.github/workflows/tests_coverage.yml @@ -28,6 +28,8 @@ jobs: run: | pip install --upgrade pip pip install -r requirements.txt numpy==1.26.4 ConfigSpace==0.6.1 adsg-core==1.1.0 + pip install git+https://github.com/SMTorg/smt-design-space + pip list pip install -e . From f0ef7b8cbf81caf55afd76e0199f92fa0462c365 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 13:13:40 +0200 Subject: [PATCH 23/77] remove debrecated package utils --- smt/applications/ego.py | 2 +- smt/applications/mfk.py | 2 +- smt/applications/mixed_integer.py | 2 +- smt/applications/tests/test_mixed_integer.py | 26 +++++++++++--------- smt/problems/hierarchical_goldstein.py | 2 +- smt/problems/mixed_cantilever_beam.py | 2 +- smt/problems/neural_network.py | 2 +- smt/problems/problem.py | 2 +- smt/surrogate_models/__init__.py | 2 +- smt/surrogate_models/gpx.py | 2 +- smt/surrogate_models/krg_based.py | 2 +- smt/utils/kriging.py | 2 +- 12 files changed, 25 insertions(+), 23 deletions(-) diff --git a/smt/applications/ego.py b/smt/applications/ego.py index 405571c6b..bbb0fe10d 100644 --- a/smt/applications/ego.py +++ b/smt/applications/ego.py @@ -18,7 +18,7 @@ ) from smt.sampling_methods import LHS from smt.surrogate_models import GEKPLS, GPX, KPLS, KPLSK, KRG, MGP -from smt.utils.design_space import ( +from SMTDesignSpace.design_space import ( BaseDesignSpace, DesignSpace, ) diff --git a/smt/applications/mfk.py b/smt/applications/mfk.py index ab1876120..91192bfc0 100644 --- a/smt/applications/mfk.py +++ b/smt/applications/mfk.py @@ -23,7 +23,7 @@ MixIntKernelType, compute_n_param, ) -from smt.utils.design_space import ensure_design_space +from SMTDesignSpace.design_space import ensure_design_space from smt.utils.kriging import ( componentwise_distance, compute_X_cont, diff --git a/smt/applications/mixed_integer.py b/smt/applications/mixed_integer.py index c1e76ad9a..cac4f11e3 100644 --- a/smt/applications/mixed_integer.py +++ b/smt/applications/mixed_integer.py @@ -12,7 +12,7 @@ from smt.surrogate_models.krg_based import KrgBased, MixIntKernelType from smt.surrogate_models.surrogate_model import SurrogateModel from smt.utils.checks import ensure_2d_array -from smt.utils.design_space import ( +from SMTDesignSpace.design_space import ( BaseDesignSpace, CategoricalVariable, ensure_design_space, diff --git a/smt/applications/tests/test_mixed_integer.py b/smt/applications/tests/test_mixed_integer.py index 2da0b2ba8..c9c18cf22 100644 --- a/smt/applications/tests/test_mixed_integer.py +++ b/smt/applications/tests/test_mixed_integer.py @@ -17,7 +17,17 @@ except ImportError: NO_MATPLOTLIB = True -import smt.utils.design_space as ds +from SMTDesignSpace import design_space as ds +from SMTDesignSpace.design_space import ( + HAS_CONFIG_SPACE, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, +) + + from smt.applications.mixed_integer import ( MixedIntegerContext, MixedIntegerKrigingModel, @@ -33,14 +43,6 @@ MixHrcKernelType, MixIntKernelType, ) -from smt.utils.design_space import ( - HAS_CONFIG_SPACE, - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, -) class TestMixedInteger(unittest.TestCase): @@ -474,7 +476,7 @@ def run_mixed_integer_lhs_example(self): from smt.applications.mixed_integer import MixedIntegerSamplingMethod from smt.sampling_methods import LHS - from smt.utils.design_space import ( + from SMTDesignSpace import ( CategoricalVariable, DesignSpace, FloatVariable, @@ -539,7 +541,7 @@ def run_mixed_integer_context_example(self): from smt.applications.mixed_integer import MixedIntegerContext from smt.surrogate_models import KRG - from smt.utils.design_space import ( + from SMTDesignSpace.design_space import ( CategoricalVariable, DesignSpace, FloatVariable, @@ -799,7 +801,7 @@ def run_hierarchical_design_space_example(self): ) from smt.sampling_methods import LHS from smt.surrogate_models import KRG, MixHrcKernelType, MixIntKernelType - from smt.utils.design_space import ( + from SMTDesignSpace import ( CategoricalVariable, DesignSpace, FloatVariable, diff --git a/smt/problems/hierarchical_goldstein.py b/smt/problems/hierarchical_goldstein.py index 43166d23a..b3ba4d831 100644 --- a/smt/problems/hierarchical_goldstein.py +++ b/smt/problems/hierarchical_goldstein.py @@ -10,7 +10,7 @@ import numpy as np from smt.problems.problem import Problem -from smt.utils.design_space import ( +from SMTDesignSpace.design_space import ( CategoricalVariable, DesignSpace, FloatVariable, diff --git a/smt/problems/mixed_cantilever_beam.py b/smt/problems/mixed_cantilever_beam.py index 4c410b47e..071c1e8db 100644 --- a/smt/problems/mixed_cantilever_beam.py +++ b/smt/problems/mixed_cantilever_beam.py @@ -10,7 +10,7 @@ import numpy as np from smt.problems.problem import Problem -from smt.utils.design_space import CategoricalVariable, DesignSpace, FloatVariable +from SMTDesignSpace.design_space import CategoricalVariable, DesignSpace, FloatVariable class MixedCantileverBeam(Problem): diff --git a/smt/problems/neural_network.py b/smt/problems/neural_network.py index 849f9b39d..f45b5b5d1 100644 --- a/smt/problems/neural_network.py +++ b/smt/problems/neural_network.py @@ -11,7 +11,7 @@ import numpy as np from smt.problems.problem import Problem -from smt.utils.design_space import ( +from SMTDesignSpace.design_space import ( CategoricalVariable, DesignSpace, FloatVariable, diff --git a/smt/problems/problem.py b/smt/problems/problem.py index 5bda81c9c..6fc4cc543 100644 --- a/smt/problems/problem.py +++ b/smt/problems/problem.py @@ -11,7 +11,7 @@ import numpy as np from smt.utils.checks import ensure_2d_array -from smt.utils.design_space import BaseDesignSpace, DesignSpace +from SMTDesignSpace.design_space import BaseDesignSpace, DesignSpace from smt.utils.options_dictionary import OptionsDictionary diff --git a/smt/surrogate_models/__init__.py b/smt/surrogate_models/__init__.py index 8c963d5ca..86f1a6000 100644 --- a/smt/surrogate_models/__init__.py +++ b/smt/surrogate_models/__init__.py @@ -10,7 +10,7 @@ from .sgp import SGP from .krg_based import MixIntKernelType -from smt.utils.design_space import ( +from SMTDesignSpace.design_space import ( DesignSpace, FloatVariable, IntegerVariable, diff --git a/smt/surrogate_models/gpx.py b/smt/surrogate_models/gpx.py index 6ee0581b6..3eaa04816 100644 --- a/smt/surrogate_models/gpx.py +++ b/smt/surrogate_models/gpx.py @@ -1,7 +1,7 @@ import numpy as np from smt.surrogate_models.surrogate_model import SurrogateModel -from smt.utils.design_space import ( +from SMTDesignSpace.design_space import ( BaseDesignSpace, ensure_design_space, ) diff --git a/smt/surrogate_models/krg_based.py b/smt/surrogate_models/krg_based.py index 1393cb5d4..15ca4cb48 100644 --- a/smt/surrogate_models/krg_based.py +++ b/smt/surrogate_models/krg_based.py @@ -23,7 +23,7 @@ ActExp, ) from smt.utils.checks import check_support, ensure_2d_array -from smt.utils.design_space import ( +from SMTDesignSpace.design_space import ( BaseDesignSpace, CategoricalVariable, ensure_design_space, diff --git a/smt/utils/kriging.py b/smt/utils/kriging.py index e7f7d9c65..f2faec2ca 100644 --- a/smt/utils/kriging.py +++ b/smt/utils/kriging.py @@ -12,7 +12,7 @@ from sklearn.cross_decomposition import PLSRegression as pls from sklearn.metrics.pairwise import check_pairwise_arrays -from smt.utils.design_space import CategoricalVariable +from SMTDesignSpace.design_space import CategoricalVariable USE_NUMBA_JIT = int(os.getenv("USE_NUMBA_JIT", 0)) prange = range From 8683a99182c3a1015118b8dada9b0b01ddabcad3 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 13:22:41 +0200 Subject: [PATCH 24/77] add requirements --- .github/workflows/tests_coverage.yml | 2 -- requirements.txt | 1 + setup.py | 3 --- smt/applications/tests/test_ego.py | 2 +- 4 files changed, 2 insertions(+), 6 deletions(-) diff --git a/.github/workflows/tests_coverage.yml b/.github/workflows/tests_coverage.yml index 20124338b..4bd893df2 100644 --- a/.github/workflows/tests_coverage.yml +++ b/.github/workflows/tests_coverage.yml @@ -28,8 +28,6 @@ jobs: run: | pip install --upgrade pip pip install -r requirements.txt numpy==1.26.4 ConfigSpace==0.6.1 adsg-core==1.1.0 - pip install git+https://github.com/SMTorg/smt-design-space - pip list pip install -e . diff --git a/requirements.txt b/requirements.txt index d8cb72d99..bf31d6b06 100644 --- a/requirements.txt +++ b/requirements.txt @@ -11,3 +11,4 @@ pytest-cov # allows to get coverage report ruff # format and lint code jenn >= 1.0.2, <2.0 egobox ~= 0.20.0 +git+https://github.com/SMTorg/smt-design-space \ No newline at end of file diff --git a/setup.py b/setup.py index ae1eeb0eb..ae462c220 100644 --- a/setup.py +++ b/setup.py @@ -118,9 +118,6 @@ "numba": [ # pip install smt[numba] "numba~=0.56.4", ], - "cs": [ # pip install smt[cs] - "ConfigSpace~=0.6.1", - ], "gpx": ["egobox~=0.20"], # pip install smt[gpx] }, python_requires=">=3.8", diff --git a/smt/applications/tests/test_ego.py b/smt/applications/tests/test_ego.py index 8704bed98..7016806e2 100644 --- a/smt/applications/tests/test_ego.py +++ b/smt/applications/tests/test_ego.py @@ -11,7 +11,7 @@ import numpy as np -import smt.utils.design_space as ds +from SMTDesignSpace import design_space as ds from smt.applications import EGO from smt.applications.ego import Evaluator from smt.applications.mixed_integer import ( From fe346f0c6652004d3adee807fcc1f70fe2e528ad Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 13:28:51 +0200 Subject: [PATCH 25/77] remove test --- smt/utils/test/test_design_space.py | 845 ---------------------------- 1 file changed, 845 deletions(-) delete mode 100644 smt/utils/test/test_design_space.py diff --git a/smt/utils/test/test_design_space.py b/smt/utils/test/test_design_space.py deleted file mode 100644 index 008066f00..000000000 --- a/smt/utils/test/test_design_space.py +++ /dev/null @@ -1,845 +0,0 @@ -""" -Author: Jasper Bussemaker -""" - -import contextlib -import itertools -import unittest - -import numpy as np - -import smt.utils.design_space as ds -from smt.sampling_methods import LHS -from smt.utils.design_space import ( - HAS_CONFIG_SPACE, - HAS_ADSG, - ArchDesignSpaceGraph, - BaseDesignSpace, - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, -) - - -@contextlib.contextmanager -def simulate_no_config_space(do_simulate=True): - if ds.HAS_CONFIG_SPACE and do_simulate: - ds.HAS_CONFIG_SPACE = False - yield - ds.HAS_CONFIG_SPACE = True - else: - yield - - -class Test(unittest.TestCase): - def test_design_variables(self): - with self.assertRaises(ValueError): - FloatVariable(1, 0) - - float_var = FloatVariable(0, 1) - self.assertEqual(float_var.lower, 0) - self.assertEqual(float_var.upper, 1) - self.assertEqual(float_var.get_limits(), (0, 1)) - self.assertTrue(str(float_var)) - self.assertTrue(repr(float_var)) - self.assertEqual("FloatVariable", float_var.get_typename()) - - with self.assertRaises(ValueError): - IntegerVariable(1, 0) - - int_var = IntegerVariable(0, 1) - self.assertEqual(int_var.lower, 0) - self.assertEqual(int_var.upper, 1) - self.assertEqual(int_var.get_limits(), (0, 1)) - self.assertTrue(str(int_var)) - self.assertTrue(repr(int_var)) - self.assertEqual("IntegerVariable", int_var.get_typename()) - - with self.assertRaises(ValueError): - OrdinalVariable([]) - with self.assertRaises(ValueError): - OrdinalVariable(["1"]) - - ord_var = OrdinalVariable(["A", "B", "C"]) - self.assertEqual(ord_var.values, ["A", "B", "C"]) - self.assertEqual(ord_var.get_limits(), ["0", "1", "2"]) - self.assertEqual(ord_var.lower, 0) - self.assertEqual(ord_var.upper, 2) - self.assertTrue(str(ord_var)) - self.assertTrue(repr(ord_var)) - self.assertEqual("OrdinalVariable", ord_var.get_typename()) - - with self.assertRaises(ValueError): - CategoricalVariable([]) - with self.assertRaises(ValueError): - CategoricalVariable(["A"]) - - cat_var = CategoricalVariable(["A", "B", "C"]) - self.assertEqual(cat_var.values, ["A", "B", "C"]) - self.assertEqual(cat_var.get_limits(), ["A", "B", "C"]) - self.assertEqual(cat_var.lower, 0) - self.assertEqual(cat_var.upper, 2) - self.assertTrue(str(cat_var)) - self.assertTrue(repr(cat_var)) - self.assertEqual("CategoricalVariable", cat_var.get_typename()) - - def test_rounding(self): - ds = BaseDesignSpace( - [ - IntegerVariable(0, 5), - IntegerVariable(-1, 1), - IntegerVariable(2, 4), - ] - ) - - x = np.array( - list( - itertools.product( - np.linspace(0, 5, 20), np.linspace(-1, 1, 20), np.linspace(2, 4, 20) - ) - ) - ) - for i, dv in enumerate(ds.design_variables): - self.assertIsInstance(dv, IntegerVariable) - x[:, i] = ds._round_equally_distributed(x[:, i], dv.lower, dv.upper) - - x1, x1_counts = np.unique(x[:, 0], return_counts=True) - self.assertTrue(np.all(x1 == [0, 1, 2, 3, 4, 5])) - x1_counts = x1_counts / np.sum(x1_counts) - self.assertTrue(np.all(np.abs(x1_counts - np.mean(x1_counts)) <= 0.05)) - - x2, x2_counts = np.unique(x[:, 1], return_counts=True) - self.assertTrue(np.all(x2 == [-1, 0, 1])) - x2_counts = x2_counts / np.sum(x2_counts) - self.assertTrue(np.all(np.abs(x2_counts - np.mean(x2_counts)) <= 0.05)) - - x3, x3_counts = np.unique(x[:, 2], return_counts=True) - self.assertTrue(np.all(x3 == [2, 3, 4])) - x3_counts = x3_counts / np.sum(x3_counts) - self.assertTrue(np.all(np.abs(x3_counts - np.mean(x3_counts)) <= 0.05)) - - def test_base_design_space(self): - ds = BaseDesignSpace( - [ - CategoricalVariable(["A", "B"]), - IntegerVariable(0, 3), - FloatVariable(-0.5, 0.5), - ] - ) - self.assertEqual(ds.get_x_limits(), [["A", "B"], (0, 3), (-0.5, 0.5)]) - self.assertTrue(np.all(ds.get_num_bounds() == [[0, 1], [0, 3], [-0.5, 0.5]])) - self.assertTrue( - np.all( - ds.get_unfolded_num_bounds() == [[0, 1], [0, 1], [0, 3], [-0.5, 0.5]] - ) - ) - - x = np.array( - [ - [0, 0, 0], - [1, 2, 0.5], - [0, 3, 0.5], - ] - ) - is_acting = np.array( - [ - [True, True, False], - [True, False, True], - [False, True, True], - ] - ) - - x_unfolded, is_acting_unfolded = ds.unfold_x(x, is_acting) - self.assertTrue( - np.all( - x_unfolded - == [ - [1, 0, 0, 0], - [0, 1, 2, 0.5], - [1, 0, 3, 0.5], - ] - ) - ) - self.assertEqual(is_acting_unfolded.dtype, bool) - np.testing.assert_array_equal( - is_acting_unfolded, - [ - [True, True, True, False], - [True, True, False, True], - [False, False, True, True], - ], - ) - - x_folded, is_acting_folded = ds.fold_x(x_unfolded, is_acting_unfolded) - np.testing.assert_array_equal(x_folded, x) - np.testing.assert_array_equal(is_acting_folded, is_acting) - - x_unfold_mask, is_act_unfold_mask = ds.unfold_x( - x, is_acting, fold_mask=np.array([False] * 3) - ) - np.testing.assert_array_equal(x_unfold_mask, x) - np.testing.assert_array_equal(is_act_unfold_mask, is_acting) - - x_fold_mask, is_act_fold_mask = ds.fold_x( - x, is_acting, fold_mask=np.array([False] * 3) - ) - np.testing.assert_array_equal(x_fold_mask, x) - - np.testing.assert_array_equal(is_act_fold_mask, is_acting) - - def test_create_design_space(self): - DesignSpace([FloatVariable(0, 1)]) - with simulate_no_config_space(): - DesignSpace([FloatVariable(0, 1)]) - - def test_design_space(self): - ds = DesignSpace( - [ - CategoricalVariable(["A", "B", "C"]), - OrdinalVariable(["0", "1"]), - IntegerVariable(-1, 2), - FloatVariable(0.5, 1.5), - ], - random_state=42, - ) - self.assertEqual(len(ds.design_variables), 4) - if HAS_CONFIG_SPACE: - self.assertEqual(len(list(ds._cs.values())), 4) - self.assertTrue(np.all(~ds.is_conditionally_acting)) - if HAS_CONFIG_SPACE: - x, is_acting = ds.sample_valid_x(3, random_state=42) - self.assertEqual(x.shape, (3, 4)) - np.testing.assert_allclose( - x, - np.array( - [ - [1.0, 0.0, -0.0, 0.83370861], - [2.0, 0.0, -1.0, 0.64286682], - [2.0, 0.0, -0.0, 1.15088847], - ] - ), - atol=1e-8, - ) - else: - ds.sample_valid_x(3, random_state=42) - x = np.array( - [ - [1, 0, 0, 0.834], - [2, 0, -1, 0.6434], - [2, 0, 0, 1.151], - ] - ) - x, is_acting = ds.correct_get_acting(x) - - self.assertEqual(x.shape, (3, 4)) - self.assertEqual(is_acting.shape, x.shape) - - self.assertEqual(ds.decode_values(x, i_dv=0), ["B", "C", "C"]) - self.assertEqual(ds.decode_values(x, i_dv=1), ["0", "0", "0"]) - self.assertEqual(ds.decode_values(np.array([0, 1, 2]), i_dv=0), ["A", "B", "C"]) - self.assertEqual(ds.decode_values(np.array([0, 1]), i_dv=1), ["0", "1"]) - - self.assertEqual(ds.decode_values(x[0, :]), ["B", "0", 0, x[0, 3]]) - self.assertEqual(ds.decode_values(x[[0], :]), [["B", "0", 0, x[0, 3]]]) - self.assertEqual( - ds.decode_values(x), - [ - ["B", "0", 0, x[0, 3]], - ["C", "0", -1, x[1, 3]], - ["C", "0", 0, x[2, 3]], - ], - ) - - x_corr, is_act_corr = ds.correct_get_acting(x) - self.assertTrue(np.all(x_corr == x)) - self.assertTrue(np.all(is_act_corr == is_acting)) - - x_sampled_externally = LHS( - xlimits=ds.get_unfolded_num_bounds(), criterion="ese", random_state=42 - )(3) - x_corr, is_acting_corr = ds.correct_get_acting(x_sampled_externally) - x_corr, is_acting_corr = ds.fold_x(x_corr, is_acting_corr) - np.testing.assert_allclose( - x_corr, - np.array( - [ - [2.0, 0.0, -1.0, 1.34158548], - [0.0, 1.0, -0.0, 0.55199817], - [1.0, 1.0, 1.0, 1.15663662], - ] - ), - atol=1e-8, - ) - self.assertTrue(np.all(is_acting_corr)) - - x_unfolded, is_acting_unfolded = ds.sample_valid_x( - 3, unfolded=True, random_state=42 - ) - self.assertEqual(x_unfolded.shape, (3, 6)) - if HAS_CONFIG_SPACE: - np.testing.assert_allclose( - x_unfolded, - np.array( - [ - [1.0, 0.0, 0.0, 0.0, 2.0, 1.11213215], - [0.0, 1.0, 0.0, 1.0, -1.0, 1.09482857], - [1.0, 0.0, 0.0, 1.0, -1.0, 0.75061044], - ] - ), - atol=1e-8, - ) - - self.assertTrue(str(ds)) - self.assertTrue(repr(ds)) - - ds.correct_get_acting(np.array([[0, 0, 0, 1.6]])) - - def test_folding_mask(self): - ds = DesignSpace( - [ - CategoricalVariable(["A", "B", "C"]), - CategoricalVariable(["A", "B", "C"]), - ] - ) - x = np.array([[1, 2]]) - is_act = np.array([[True, False]]) - - self.assertEqual(ds._get_n_dim_unfolded(), 6) - - x_unfolded, is_act_unfolded = ds.unfold_x(x, is_act, np.array([True, False])) - self.assertTrue(np.all(x_unfolded == np.array([[0, 1, 0, 2]]))) - self.assertTrue( - np.all(is_act_unfolded == np.array([[True, True, True, False]])) - ) - - x_folded, is_act_folded = ds.fold_x( - x_unfolded, is_act_unfolded, np.array([True, False]) - ) - self.assertTrue(np.all(x_folded == x)) - self.assertTrue(np.all(is_act_folded == is_act)) - - def test_float_design_space(self): - ds = DesignSpace([(0, 1), (0.5, 2.5), (-0.4, 10)]) - assert ds.n_dv == 3 - assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) - assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) - - ds = DesignSpace([[0, 1], [0.5, 2.5], [-0.4, 10]]) - assert ds.n_dv == 3 - assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) - assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) - - ds = DesignSpace(np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) - assert ds.n_dv == 3 - assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) - assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) - - def test_design_space_hierarchical(self): - ds = DesignSpace( - [ - CategoricalVariable(["A", "B", "C"]), # x0 - CategoricalVariable(["E", "F"]), # x1 - IntegerVariable(0, 1), # x2 - FloatVariable(0.1, 1), # x3 - ], - random_state=42, - ) - ds.declare_decreed_var( - decreed_var=3, meta_var=0, meta_value="A" - ) # Activate x3 if x0 == A - - x_cartesian = np.array( - list(itertools.product([0, 1, 2], [0, 1], [0, 1], [0.25, 0.75])) - ) - self.assertEqual(x_cartesian.shape, (24, 4)) - - self.assertTrue( - np.all(ds.is_conditionally_acting == [False, False, False, True]) - ) - - x, is_acting = ds.correct_get_acting(x_cartesian) - _, is_unique = np.unique(x, axis=0, return_index=True) - self.assertEqual(len(is_unique), 16) - np.testing.assert_allclose( - x[is_unique, :], - np.array( - [ - [0, 0, 0, 0.25], - [0, 0, 0, 0.75], - [0, 0, 1, 0.25], - [0, 0, 1, 0.75], - [0, 1, 0, 0.25], - [0, 1, 0, 0.75], - [0, 1, 1, 0.25], - [0, 1, 1, 0.75], - [1, 0, 0, 0.55], - [1, 0, 1, 0.55], - [1, 1, 0, 0.55], - [1, 1, 1, 0.55], - [2, 0, 0, 0.55], - [2, 0, 1, 0.55], - [2, 1, 0, 0.55], - [2, 1, 1, 0.55], - ] - ), - ) - np.testing.assert_array_equal( - is_acting[is_unique, :], - np.array( - [ - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - ] - ), - ) - - x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) - assert x_sampled.shape == (100, 4) - x_sampled[is_acting_sampled[:, 3], 3] = np.round( - x_sampled[is_acting_sampled[:, 3], 3], 4 - ) - - x_corr, is_acting_corr = ds.correct_get_acting(x_sampled) - self.assertTrue(np.sum(np.abs(x_corr - x_sampled)) < 1e-12) - self.assertTrue(np.all(is_acting_corr == is_acting_sampled)) - - seen_x = set() - seen_is_acting = set() - for i, xi in enumerate(x_sampled): - seen_x.add(tuple(xi)) - seen_is_acting.add(tuple(is_acting_sampled[i, :])) - if HAS_ADSG: - assert len(seen_x) == 49 - else: - assert len(seen_x) == 42 - assert len(seen_is_acting) == 2 - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_design_space_hierarchical_config_space(self): - ds = DesignSpace( - [ - CategoricalVariable(["A", "B", "Cc"]), # x0 - CategoricalVariable(["E", "F"]), # x1 - IntegerVariable(0, 1), # x2 - FloatVariable(0, 1), # x3 - ], - random_state=42, - ) - ds.declare_decreed_var( - decreed_var=3, meta_var=0, meta_value="A" - ) # Activate x3 if x0 == A - ds.add_value_constraint( - var1=0, value1=["Cc"], var2=1, value2="F" - ) # Prevent a == C and b == F - - x_cartesian = np.array( - list(itertools.product([0, 1, 2], [0, 1], [0, 1], [0.25, 0.75])) - ) - self.assertEqual(x_cartesian.shape, (24, 4)) - - self.assertTrue( - np.all(ds.is_conditionally_acting == [False, False, False, True]) - ) - - x, is_acting = ds.correct_get_acting(x_cartesian) - _, is_unique = np.unique(x, axis=0, return_index=True) - self.assertEqual(len(is_unique), 14) - np.testing.assert_array_equal( - x[is_unique, :], - np.array( - [ - [0, 0, 0, 0.25], - [0, 0, 0, 0.75], - [0, 0, 1, 0.25], - [0, 0, 1, 0.75], - [0, 1, 0, 0.25], - [0, 1, 0, 0.75], - [0, 1, 1, 0.25], - [0, 1, 1, 0.75], - [1, 0, 0, 0.5], - [1, 0, 1, 0.5], - [1, 1, 0, 0.5], - [1, 1, 1, 0.5], - [2, 0, 0, 0.5], - [2, 0, 1, 0.5], - ] - ), - ) - np.testing.assert_array_equal( - is_acting[is_unique, :], - np.array( - [ - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - ] - ), - ) - - x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) - assert x_sampled.shape == (100, 4) - x_sampled[is_acting_sampled[:, 3], 3] = np.round( - x_sampled[is_acting_sampled[:, 3], 3] - ) - - x_corr, is_acting_corr = ds.correct_get_acting(x_sampled) - self.assertTrue(np.all(x_corr == x_sampled)) - self.assertTrue(np.all(is_acting_corr == is_acting_sampled)) - - seen_x = set() - seen_is_acting = set() - for i, xi in enumerate(x_sampled): - seen_x.add(tuple(xi)) - seen_is_acting.add(tuple(is_acting_sampled[i, :])) - assert len(seen_x) == 14 - assert len(seen_is_acting) == 2 - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_design_space_continuous(self): - ds = DesignSpace( - [ - FloatVariable(0, 1), # x0 - FloatVariable(0, 1), # x1 - FloatVariable(0, 1), # x2 - ], - random_state=42, - ) - ds.add_value_constraint( - var1=0, value1="<", var2=1, value2=">" - ) # Prevent x0 < x1 - ds.add_value_constraint( - var1=1, value1="<", var2=2, value2=">" - ) # Prevent x1 < x2 - - # correct_get_acting - x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) - self.assertTrue(np.min(x_sampled[:, 0] - x_sampled[:, 1]) > 0) - self.assertTrue(np.min(x_sampled[:, 1] - x_sampled[:, 2]) > 0) - ds = DesignSpace( - [ - IntegerVariable(0, 2), # x0 - FloatVariable(0, 2), # x1 - IntegerVariable(0, 2), # x2 - ], - random_state=42, - ) - ds.add_value_constraint( - var1=0, value1="<", var2=1, value2=">" - ) # Prevent x0 < x1 - ds.add_value_constraint( - var1=1, value1="<", var2=2, value2=">" - ) # Prevent x0 < x1 - - # correct_get_acting - x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) - self.assertTrue(np.min(x_sampled[:, 0] - x_sampled[:, 1]) > 0) - self.assertTrue(np.min(x_sampled[:, 1] - x_sampled[:, 2]) > 0) - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_check_conditionally_acting(self): - class WrongDesignSpace(DesignSpace): - def _is_conditionally_acting(self) -> np.ndarray: - return np.zeros((self.n_dv,), dtype=bool) - - for simulate_no_cs in [True, False]: - with simulate_no_config_space(simulate_no_cs): - ds = WrongDesignSpace( - [ - CategoricalVariable(["A", "B", "C"]), # x0 - CategoricalVariable(["E", "F"]), # x1 - IntegerVariable(0, 1), # x2 - FloatVariable(0, 1), # x3 - ], - random_state=42, - ) - ds.declare_decreed_var( - decreed_var=3, meta_var=0, meta_value="A" - ) # Activate x3 if x0 == A - self.assertRaises( - RuntimeError, lambda: ds.sample_valid_x(10, random_state=42) - ) - - def test_check_conditionally_acting_2(self): - for simulate_no_cs in [True, False]: - with simulate_no_config_space(simulate_no_cs): - ds = DesignSpace( - [ - CategoricalVariable(["A", "B", "C"]), # x0 - CategoricalVariable(["E", "F"]), # x1 - IntegerVariable(0, 1), # x2 - FloatVariable(0, 1), # x3 - ], - random_state=42, - ) - ds.declare_decreed_var( - decreed_var=0, meta_var=1, meta_value="E" - ) # Activate x3 if x0 == A - - ds.sample_valid_x(10, random_state=42) - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_restrictive_value_constraint_ordinal(self): - ds = DesignSpace( - [ - OrdinalVariable(["0", "1", "2"]), - OrdinalVariable(["0", "1", "2"]), - ] - ) - assert list(ds._cs.values())[0].default_value == "0" - - ds.add_value_constraint(var1=0, value1="1", var2=1, value2="1") - ds.sample_valid_x(100, random_state=42) - - x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) - x_cartesian2, _ = ds.correct_get_acting(x_cartesian) - np.testing.assert_array_equal( - np.array( - [[0, 0], [0, 1], [0, 2], [1, 0], [0, 1], [1, 2], [2, 0], [2, 1], [2, 2]] - ), - x_cartesian2, - ) - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_restrictive_value_constraint_integer(self): - ds = DesignSpace( - [ - IntegerVariable(0, 2), - IntegerVariable(0, 2), - ] - ) - assert list(ds._cs.values())[0].default_value == 1 - - ds.add_value_constraint(var1=0, value1=1, var2=1, value2=1) - ds.sample_valid_x(100, random_state=42) - - x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) - ds.correct_get_acting(x_cartesian) - x_cartesian2, _ = ds.correct_get_acting(x_cartesian) - np.testing.assert_array_equal( - np.array( - [[0, 0], [0, 1], [0, 2], [1, 0], [2, 0], [1, 2], [2, 0], [2, 1], [2, 2]] - ), - x_cartesian2, - ) - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_restrictive_value_constraint_categorical(self): - ds = DesignSpace( - [ - CategoricalVariable(["a", "b", "c"]), - CategoricalVariable(["a", "b", "c"]), - ] - ) - assert list(ds._cs.values())[0].default_value == "a" - - ds.add_value_constraint(var1=0, value1="b", var2=1, value2="b") - ds.sample_valid_x(100, random_state=42) - - x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) - ds.correct_get_acting(x_cartesian) - x_cartesian2, _ = ds.correct_get_acting(x_cartesian) - np.testing.assert_array_equal( - np.array( - [[0, 0], [0, 1], [0, 2], [1, 0], [0, 1], [1, 2], [2, 0], [2, 1], [2, 2]] - ), - x_cartesian2, - ) - - @unittest.skipIf( - not (HAS_CONFIG_SPACE and HAS_ADSG), - "Architecture Design Space Graph or ConfigSpace not installed.", - ) - def test_adsg_to_legacy(self): - from adsg_core import BasicADSG, NamedNode, DesignVariableNode - from smt.utils.design_space import ensure_design_space - from adsg_core import GraphProcessor - - # Create the ADSG - adsg = BasicADSG() - ndv = 13 - # Create nodes - n = [NamedNode(f"N{i}") for i in range(ndv)] - n = [ - NamedNode("MLP"), - NamedNode("Learning_rate"), - NamedNode("Activation_function"), - NamedNode("Optimizer"), - NamedNode("Decay"), - NamedNode("Power_update"), - NamedNode("Average_start"), - NamedNode("Running_Average_1"), - NamedNode("Running_Average_2"), - NamedNode("Numerical_Stability"), - NamedNode("Nb_layers"), - NamedNode("Layer_1"), - NamedNode("Layer_2"), - NamedNode("Layer_3"), # NamedNode("Dropout"), - NamedNode("ASGD"), - NamedNode("Adam"), - NamedNode("20...40"), - NamedNode("40"), - NamedNode("45"), - NamedNode("20...40"), - NamedNode("40"), - NamedNode("45"), - NamedNode("20...40"), - NamedNode("40"), - NamedNode("45"), - ] - adsg.add_node(n[1]) - adsg.add_node(n[2]) - adsg.add_edges( - [ - (n[3], n[10]), - (n[14], n[4]), - (n[14], n[5]), - (n[14], n[6]), - (n[15], n[7]), - (n[15], n[8]), - (n[15], n[9]), - ] - ) - adsg.add_selection_choice("Optimizer_Choice", n[3], [n[14], n[15]]) - adsg.add_selection_choice("#layers", n[10], [n[11], n[12], n[13]]) - a = [] - for i in range(3): - a.append(NamedNode(str(25 + 5 * i))) - b = a.copy() - b.append(n[17]) - b.append(n[18]) - choicel1 = adsg.add_selection_choice("#neurons_1", n[11], b) - adsg.add_edges([(n[12], choicel1), (n[13], choicel1)]) - - a = [] - for i in range(3): - a.append(NamedNode(str(25 + 5 * i))) - b = a.copy() - b.append(n[20]) - b.append(n[21]) - choicel1 = adsg.add_selection_choice("#neurons_2", n[12], b) - adsg.add_edges([(n[13], choicel1)]) - - a = [] - for i in range(3): - a.append(NamedNode(str(25 + 5 * i))) - b = a.copy() - b.append(n[23]) - b.append(n[24]) - choicel1 = adsg.add_selection_choice("#neurons_3", n[13], b) - - adsg.add_incompatibility_constraint([n[15], n[13]]) - adsg.add_incompatibility_constraint([n[14], n[17]]) - adsg.add_incompatibility_constraint([n[14], n[18]]) - adsg.add_incompatibility_constraint([n[14], n[20]]) - adsg.add_incompatibility_constraint([n[14], n[21]]) - adsg.add_incompatibility_constraint([n[14], n[23]]) - adsg.add_incompatibility_constraint([n[14], n[24]]) - start_nodes = set() - start_nodes.add(n[3]) - start_nodes.add(n[2]) - start_nodes.add(n[1]) - adsg.add_edges( - [ - (n[1], DesignVariableNode("x0", bounds=(0, 1))), - (n[4], DesignVariableNode("x1", bounds=(0, 1))), - (n[5], DesignVariableNode("x2", bounds=(0, 1))), - (n[6], DesignVariableNode("x3", bounds=(0, 1))), - (n[7], DesignVariableNode("x4", bounds=(0, 1))), - (n[8], DesignVariableNode("x5", bounds=(0, 1))), - (n[9], DesignVariableNode("x6", bounds=(0, 1))), - ] - ) - adsg.add_selection_choice( - "Activation_Choice", - n[2], - [NamedNode("ReLU"), NamedNode("Sigmoid"), NamedNode("Tanh")], - ) - adsg = adsg.set_start_nodes(start_nodes) - adsg.render() - gp = GraphProcessor(adsg) - gp.get_statistics() - design_space = ensure_design_space(design_space=adsg) - np.testing.assert_array_equal( - np.array( - [ - False, - False, - False, - True, - True, - True, - False, - True, - True, - True, - True, - True, - True, - ] - ), - design_space.is_conditionally_acting, - ) - design_space2 = ArchDesignSpaceGraph(adsg=adsg) - np.testing.assert_array_equal( - np.array( - [ - False, - False, - False, - True, - True, - True, - False, - True, - True, - True, - True, - True, - True, - ] - ), - design_space2.is_conditionally_acting, - ) - - -if __name__ == "__main__": - unittest.main() From c3c4b1712b44e3886da4b304a07b2021eed3f5ad Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 14:08:27 +0200 Subject: [PATCH 26/77] fix tests imports --- .github/workflows/tests_minimal.yml | 3 ++- smt/applications/tests/test_mfk_mfkpls_mixed.py | 2 +- smt/tests/test_derivs.py | 2 +- smt/tests/test_extrap.py | 2 +- smt/tests/test_low_dim.py | 2 +- smt/tests/test_output_derivs.py | 2 +- smt/tests/test_training_derivs.py | 2 +- 7 files changed, 8 insertions(+), 7 deletions(-) diff --git a/.github/workflows/tests_minimal.yml b/.github/workflows/tests_minimal.yml index 98b1f30eb..80d36c6aa 100644 --- a/.github/workflows/tests_minimal.yml +++ b/.github/workflows/tests_minimal.yml @@ -21,7 +21,8 @@ jobs: pip install --upgrade pip pip install numpy cython pip install -e . - + pip install -r requirements.txt + - name: Test with pytest run: | pip install pytest diff --git a/smt/applications/tests/test_mfk_mfkpls_mixed.py b/smt/applications/tests/test_mfk_mfkpls_mixed.py index 4604b9d98..6d7da0e74 100644 --- a/smt/applications/tests/test_mfk_mfkpls_mixed.py +++ b/smt/applications/tests/test_mfk_mfkpls_mixed.py @@ -32,7 +32,7 @@ KRG, MixIntKernelType, ) -from smt.utils.design_space import ( +from SMTDesignSpace.design_space import ( CategoricalVariable, DesignSpace, FloatVariable, diff --git a/smt/tests/test_derivs.py b/smt/tests/test_derivs.py index 9aeb6c7c8..79a87ebd7 100644 --- a/smt/tests/test_derivs.py +++ b/smt/tests/test_derivs.py @@ -13,7 +13,7 @@ from smt.applications import MFK from smt.problems import Sphere from smt.sampling_methods import LHS -from smt.utils.design_space import DesignSpace +from SMTDesignSpace.design_space import DesignSpace from smt.utils.misc import compute_rms_error from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_extrap.py b/smt/tests/test_extrap.py index 9167017eb..b928768a6 100644 --- a/smt/tests/test_extrap.py +++ b/smt/tests/test_extrap.py @@ -11,7 +11,7 @@ from smt.problems import Sphere from smt.sampling_methods import LHS -from smt.utils.design_space import DesignSpace +from SMTDesignSpace.design_space import DesignSpace from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_low_dim.py b/smt/tests/test_low_dim.py index f9c2b8ac0..3f14217c3 100644 --- a/smt/tests/test_low_dim.py +++ b/smt/tests/test_low_dim.py @@ -13,7 +13,7 @@ from smt.problems import Sphere, TensorProduct from smt.sampling_methods import LHS from smt.surrogate_models import LS, QP -from smt.utils.design_space import DesignSpace +from SMTDesignSpace.design_space import DesignSpace from smt.utils.misc import compute_rms_error from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_output_derivs.py b/smt/tests/test_output_derivs.py index 738ba04b5..f17a394b1 100644 --- a/smt/tests/test_output_derivs.py +++ b/smt/tests/test_output_derivs.py @@ -12,7 +12,7 @@ from smt.problems import Sphere from smt.sampling_methods import FullFactorial -from smt.utils.design_space import DesignSpace +from SMTDesignSpace.design_space import DesignSpace from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_training_derivs.py b/smt/tests/test_training_derivs.py index 689f68d8a..1383c38bb 100644 --- a/smt/tests/test_training_derivs.py +++ b/smt/tests/test_training_derivs.py @@ -12,7 +12,7 @@ from smt.problems import Sphere, TensorProduct from smt.sampling_methods import FullFactorial -from smt.utils.design_space import DesignSpace +from SMTDesignSpace.design_space import DesignSpace from smt.utils.misc import compute_rms_error from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase From 41f80a17ae2f3660b1471b447250cd4f78deaaf6 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 15:24:21 +0200 Subject: [PATCH 27/77] fix setup? --- setup.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/setup.py b/setup.py index ae462c220..ae1eeb0eb 100644 --- a/setup.py +++ b/setup.py @@ -118,6 +118,9 @@ "numba": [ # pip install smt[numba] "numba~=0.56.4", ], + "cs": [ # pip install smt[cs] + "ConfigSpace~=0.6.1", + ], "gpx": ["egobox~=0.20"], # pip install smt[gpx] }, python_requires=">=3.8", From f6bbaba0f7b6c3c00f391757ce7f6a99376d4d98 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 16:12:46 +0200 Subject: [PATCH 28/77] restore basedesignspace --- .github/workflows/tests_coverage.yml | 2 +- requirements.txt | 3 +- smt/applications/ego.py | 17 ++++++--- smt/applications/mfk.py | 13 ++++++- smt/applications/mixed_integer.py | 19 +++++++--- smt/applications/tests/test_ego.py | 21 ++++++++++- .../tests/test_mfk_mfkpls_mixed.py | 22 ++++++++---- smt/applications/tests/test_mixed_integer.py | 36 ++++++++++++------- smt/problems/hierarchical_goldstein.py | 25 +++++++++---- smt/problems/mixed_cantilever_beam.py | 15 +++++++- smt/problems/neural_network.py | 25 +++++++++---- smt/problems/problem.py | 13 ++++++- smt/surrogate_models/__init__.py | 34 ++++++++++++++---- smt/surrogate_models/gpx.py | 16 ++++++--- smt/surrogate_models/krg_based.py | 20 ++++++++--- .../tests/test_surrogate_model_examples.py | 2 +- smt/tests/test_derivs.py | 11 +++++- smt/tests/test_extrap.py | 11 +++++- smt/tests/test_low_dim.py | 11 +++++- smt/tests/test_output_derivs.py | 11 +++++- smt/tests/test_training_derivs.py | 11 +++++- smt/utils/kriging.py | 11 +++++- 22 files changed, 278 insertions(+), 71 deletions(-) diff --git a/.github/workflows/tests_coverage.yml b/.github/workflows/tests_coverage.yml index 4bd893df2..71dec8c5f 100644 --- a/.github/workflows/tests_coverage.yml +++ b/.github/workflows/tests_coverage.yml @@ -27,7 +27,7 @@ jobs: - name: Install dependencies run: | pip install --upgrade pip - pip install -r requirements.txt numpy==1.26.4 ConfigSpace==0.6.1 adsg-core==1.1.0 + pip install -r requirements.txt numpy==1.26.4 git+https://github.com/SMTorg/smt-design-space pip list pip install -e . diff --git a/requirements.txt b/requirements.txt index bf31d6b06..85d2089b3 100644 --- a/requirements.txt +++ b/requirements.txt @@ -10,5 +10,4 @@ pytest-xdist # allows running parallel testing with pytest -n pytest-cov # allows to get coverage report ruff # format and lint code jenn >= 1.0.2, <2.0 -egobox ~= 0.20.0 -git+https://github.com/SMTorg/smt-design-space \ No newline at end of file +egobox ~= 0.20.0 \ No newline at end of file diff --git a/smt/applications/ego.py b/smt/applications/ego.py index b3ee49073..d1332e624 100644 --- a/smt/applications/ego.py +++ b/smt/applications/ego.py @@ -19,10 +19,19 @@ ) from smt.sampling_methods import LHS from smt.surrogate_models import GEKPLS, GPX, KPLS, KPLSK, KRG, MGP -from SMTDesignSpace.design_space import ( - BaseDesignSpace, - DesignSpace, -) + +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + BaseDesignSpace, + DesignSpace, + ) +else: + from smt.utils.design_space import ( + DesignSpace, + BaseDesignSpace, + ) class Evaluator(object): diff --git a/smt/applications/mfk.py b/smt/applications/mfk.py index 7fd350f8e..d7ee2cb05 100644 --- a/smt/applications/mfk.py +++ b/smt/applications/mfk.py @@ -23,7 +23,18 @@ MixIntKernelType, compute_n_param, ) -from SMTDesignSpace.design_space import ensure_design_space +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + ensure_design_space, + ) +else: + from smt.utils.design_space import ( + ensure_design_space, + ) + + from smt.utils.kriging import ( componentwise_distance, compute_X_cont, diff --git a/smt/applications/mixed_integer.py b/smt/applications/mixed_integer.py index cac4f11e3..7175c0152 100644 --- a/smt/applications/mixed_integer.py +++ b/smt/applications/mixed_integer.py @@ -12,11 +12,20 @@ from smt.surrogate_models.krg_based import KrgBased, MixIntKernelType from smt.surrogate_models.surrogate_model import SurrogateModel from smt.utils.checks import ensure_2d_array -from SMTDesignSpace.design_space import ( - BaseDesignSpace, - CategoricalVariable, - ensure_design_space, -) +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + BaseDesignSpace, + ensure_design_space, + ) +else: + from smt.utils.design_space import ( + CategoricalVariable, + BaseDesignSpace, + ensure_design_space, + ) class MixedIntegerSamplingMethod(SamplingMethod): diff --git a/smt/applications/tests/test_ego.py b/smt/applications/tests/test_ego.py index 1822c1f58..0bf325c16 100644 --- a/smt/applications/tests/test_ego.py +++ b/smt/applications/tests/test_ego.py @@ -11,7 +11,26 @@ import numpy as np -from SMTDesignSpace import design_space as ds +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace import design_space as ds + from SMTDesignSpace.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) +else: + from smt.utils import design_space as ds + from smt.utils.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) from smt.applications import EGO from smt.applications.ego import Evaluator from smt.applications.mixed_integer import ( diff --git a/smt/applications/tests/test_mfk_mfkpls_mixed.py b/smt/applications/tests/test_mfk_mfkpls_mixed.py index 6d7da0e74..9a12eac3a 100644 --- a/smt/applications/tests/test_mfk_mfkpls_mixed.py +++ b/smt/applications/tests/test_mfk_mfkpls_mixed.py @@ -32,12 +32,22 @@ KRG, MixIntKernelType, ) -from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, -) +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + ) +else: + from smt.utils.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + ) class TestMFKmixed(unittest.TestCase): diff --git a/smt/applications/tests/test_mixed_integer.py b/smt/applications/tests/test_mixed_integer.py index c9c18cf22..d95293837 100644 --- a/smt/applications/tests/test_mixed_integer.py +++ b/smt/applications/tests/test_mixed_integer.py @@ -17,16 +17,28 @@ except ImportError: NO_MATPLOTLIB = True -from SMTDesignSpace import design_space as ds -from SMTDesignSpace.design_space import ( - HAS_CONFIG_SPACE, - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, -) - +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace import design_space as ds + from SMTDesignSpace.design_space import ( + HAS_CONFIG_SPACE, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) +else: + from smt.utils import design_space as ds + from smt.utils.design_space import ( + HAS_CONFIG_SPACE, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) from smt.applications.mixed_integer import ( MixedIntegerContext, @@ -476,7 +488,7 @@ def run_mixed_integer_lhs_example(self): from smt.applications.mixed_integer import MixedIntegerSamplingMethod from smt.sampling_methods import LHS - from SMTDesignSpace import ( + from SMTDesignSpace.design_space import ( CategoricalVariable, DesignSpace, FloatVariable, @@ -801,7 +813,7 @@ def run_hierarchical_design_space_example(self): ) from smt.sampling_methods import LHS from smt.surrogate_models import KRG, MixHrcKernelType, MixIntKernelType - from SMTDesignSpace import ( + from SMTDesignSpace.design_space import ( CategoricalVariable, DesignSpace, FloatVariable, diff --git a/smt/problems/hierarchical_goldstein.py b/smt/problems/hierarchical_goldstein.py index b3ba4d831..c8ada8c94 100644 --- a/smt/problems/hierarchical_goldstein.py +++ b/smt/problems/hierarchical_goldstein.py @@ -10,13 +10,24 @@ import numpy as np from smt.problems.problem import Problem -from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, -) +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) +else: + from smt.utils.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) class HierarchicalGoldstein(Problem): diff --git a/smt/problems/mixed_cantilever_beam.py b/smt/problems/mixed_cantilever_beam.py index 071c1e8db..9bdd9fa73 100644 --- a/smt/problems/mixed_cantilever_beam.py +++ b/smt/problems/mixed_cantilever_beam.py @@ -10,7 +10,20 @@ import numpy as np from smt.problems.problem import Problem -from SMTDesignSpace.design_space import CategoricalVariable, DesignSpace, FloatVariable +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) +else: + from smt.utils.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) class MixedCantileverBeam(Problem): diff --git a/smt/problems/neural_network.py b/smt/problems/neural_network.py index f45b5b5d1..cebba9c87 100644 --- a/smt/problems/neural_network.py +++ b/smt/problems/neural_network.py @@ -11,13 +11,24 @@ import numpy as np from smt.problems.problem import Problem -from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, -) +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) +else: + from smt.utils.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) class HierarchicalNeuralNetwork(Problem): diff --git a/smt/problems/problem.py b/smt/problems/problem.py index 6fc4cc543..f278a8be0 100644 --- a/smt/problems/problem.py +++ b/smt/problems/problem.py @@ -11,7 +11,18 @@ import numpy as np from smt.utils.checks import ensure_2d_array -from SMTDesignSpace.design_space import BaseDesignSpace, DesignSpace +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + BaseDesignSpace, + DesignSpace, + ) +else: + from smt.utils.design_space import ( + DesignSpace, + BaseDesignSpace, + ) from smt.utils.options_dictionary import OptionsDictionary diff --git a/smt/surrogate_models/__init__.py b/smt/surrogate_models/__init__.py index 86f1a6000..63bef148b 100644 --- a/smt/surrogate_models/__init__.py +++ b/smt/surrogate_models/__init__.py @@ -10,13 +10,33 @@ from .sgp import SGP from .krg_based import MixIntKernelType -from SMTDesignSpace.design_space import ( - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - CategoricalVariable, -) +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace import design_space as ds + from SMTDesignSpace.design_space import ( + HAS_CONFIG_SPACE, + CategoricalVariable, + BaseDesignSpace, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ensure_design_space, + ) +else: + from smt.utils import design_space as ds + from smt.utils.design_space import ( + HAS_CONFIG_SPACE, + CategoricalVariable, + DesignSpace, + BaseDesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ensure_design_space, + ) + from smt.utils.kriging import MixHrcKernelType __all__ = [ diff --git a/smt/surrogate_models/gpx.py b/smt/surrogate_models/gpx.py index 3eaa04816..96ca09733 100644 --- a/smt/surrogate_models/gpx.py +++ b/smt/surrogate_models/gpx.py @@ -1,10 +1,18 @@ import numpy as np from smt.surrogate_models.surrogate_model import SurrogateModel -from SMTDesignSpace.design_space import ( - BaseDesignSpace, - ensure_design_space, -) +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + BaseDesignSpace, + ensure_design_space, + ) +else: + from smt.utils.design_space import ( + BaseDesignSpace, + ensure_design_space, + ) try: import egobox as egx diff --git a/smt/surrogate_models/krg_based.py b/smt/surrogate_models/krg_based.py index 660e1ec13..f038676ea 100644 --- a/smt/surrogate_models/krg_based.py +++ b/smt/surrogate_models/krg_based.py @@ -23,11 +23,21 @@ ActExp, ) from smt.utils.checks import check_support, ensure_2d_array -from SMTDesignSpace.design_space import ( - BaseDesignSpace, - CategoricalVariable, - ensure_design_space, -) +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + BaseDesignSpace, + ensure_design_space, + ) +else: + from smt.utils.design_space import ( + CategoricalVariable, + BaseDesignSpace, + ensure_design_space, + ) + from smt.utils.kriging import ( MixHrcKernelType, differences, diff --git a/smt/surrogate_models/tests/test_surrogate_model_examples.py b/smt/surrogate_models/tests/test_surrogate_model_examples.py index a36753910..10ae60f43 100644 --- a/smt/surrogate_models/tests/test_surrogate_model_examples.py +++ b/smt/surrogate_models/tests/test_surrogate_model_examples.py @@ -249,7 +249,7 @@ def test_mixed_int_krg(self): from smt.applications.mixed_integer import MixedIntegerKrigingModel from smt.surrogate_models import KRG - from smt.utils.design_space import DesignSpace, IntegerVariable + from SMTDesignSpace.design_space import DesignSpace, IntegerVariable xt = np.array([0.0, 2.0, 3.0]) yt = np.array([0.0, 1.5, 0.9]) diff --git a/smt/tests/test_derivs.py b/smt/tests/test_derivs.py index 79a87ebd7..47cdc89c1 100644 --- a/smt/tests/test_derivs.py +++ b/smt/tests/test_derivs.py @@ -13,7 +13,16 @@ from smt.applications import MFK from smt.problems import Sphere from smt.sampling_methods import LHS -from SMTDesignSpace.design_space import DesignSpace +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + DesignSpace, + ) +else: + from smt.utils.design_space import ( + DesignSpace, + ) from smt.utils.misc import compute_rms_error from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_extrap.py b/smt/tests/test_extrap.py index b928768a6..ecc489e2b 100644 --- a/smt/tests/test_extrap.py +++ b/smt/tests/test_extrap.py @@ -11,7 +11,16 @@ from smt.problems import Sphere from smt.sampling_methods import LHS -from SMTDesignSpace.design_space import DesignSpace +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + DesignSpace, + ) +else: + from smt.utils.design_space import ( + DesignSpace, + ) from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_low_dim.py b/smt/tests/test_low_dim.py index 3f14217c3..27619faba 100644 --- a/smt/tests/test_low_dim.py +++ b/smt/tests/test_low_dim.py @@ -13,7 +13,16 @@ from smt.problems import Sphere, TensorProduct from smt.sampling_methods import LHS from smt.surrogate_models import LS, QP -from SMTDesignSpace.design_space import DesignSpace +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + DesignSpace, + ) +else: + from smt.utils.design_space import ( + DesignSpace, + ) from smt.utils.misc import compute_rms_error from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_output_derivs.py b/smt/tests/test_output_derivs.py index f17a394b1..9591fc75c 100644 --- a/smt/tests/test_output_derivs.py +++ b/smt/tests/test_output_derivs.py @@ -12,7 +12,16 @@ from smt.problems import Sphere from smt.sampling_methods import FullFactorial -from SMTDesignSpace.design_space import DesignSpace +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + DesignSpace, + ) +else: + from smt.utils.design_space import ( + DesignSpace, + ) from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_training_derivs.py b/smt/tests/test_training_derivs.py index 1383c38bb..77448f84a 100644 --- a/smt/tests/test_training_derivs.py +++ b/smt/tests/test_training_derivs.py @@ -12,7 +12,16 @@ from smt.problems import Sphere, TensorProduct from smt.sampling_methods import FullFactorial -from SMTDesignSpace.design_space import DesignSpace +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + DesignSpace, + ) +else: + from smt.utils.design_space import ( + DesignSpace, + ) from smt.utils.misc import compute_rms_error from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/utils/kriging.py b/smt/utils/kriging.py index f2faec2ca..01fd4dc26 100644 --- a/smt/utils/kriging.py +++ b/smt/utils/kriging.py @@ -12,7 +12,16 @@ from sklearn.cross_decomposition import PLSRegression as pls from sklearn.metrics.pairwise import check_pairwise_arrays -from SMTDesignSpace.design_space import CategoricalVariable +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + ) +else: + from smt.utils.design_space import ( + CategoricalVariable, + ) USE_NUMBA_JIT = int(os.getenv("USE_NUMBA_JIT", 0)) prange = range From 726b86053842e85f18a7aeed41e24993b75b2bad Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 16:14:18 +0200 Subject: [PATCH 29/77] restore ds --- smt/utils/design_space.py | 625 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 625 insertions(+) create mode 100644 smt/utils/design_space.py diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py new file mode 100644 index 000000000..cf6927aaa --- /dev/null +++ b/smt/utils/design_space.py @@ -0,0 +1,625 @@ +""" +Author: Jasper Bussemaker + +This package is distributed under New BSD license. +""" + +from typing import List, Optional, Tuple, Union + +import numpy as np + + +try: + from SMTDesignSpace import * + + HAS_SMTDesignSpace = True + +except ImportError: + HAS_SMTDesignSpace = False + + +class Configuration: + pass + + +class ConfigurationSpace: + pass + + +class UniformIntegerHyperparameter: + pass + + +def ensure_design_space(xt=None, xlimits=None, design_space=None) -> "BaseDesignSpace": + """Interface to turn legacy input formats into a DesignSpace""" + + if design_space is not None and isinstance(design_space, BaseDesignSpace): + return design_space + if HAS_ADSG and design_space is not None and isinstance(design_space, ADSG): + return _convert_adsg_to_legacy(design_space) + + if xlimits is not None: + return DesignSpace(xlimits) + + if xt is not None: + return DesignSpace([[np.min(xt) - 0.99, np.max(xt) + 1e-4]] * xt.shape[1]) + + raise ValueError("Nothing defined that could be interpreted as a design space!") + + +class DesignVariable: + """Base class for defining a design variable""" + + upper: Union[float, int] + lower: Union[float, int] + + def get_typename(self): + return self.__class__.__name__ + + def get_limits(self) -> Union[list, tuple]: + raise NotImplementedError + + def __str__(self): + raise NotImplementedError + + def __repr__(self): + raise NotImplementedError + + +class FloatVariable(DesignVariable): + """A continuous design variable, varying between its lower and upper bounds""" + + def __init__(self, lower: float, upper: float): + if upper <= lower: + raise ValueError( + f"Upper bound should be higher than lower bound: {upper} <= {lower}" + ) + self.lower = lower + self.upper = upper + + def get_limits(self) -> Tuple[float, float]: + return self.lower, self.upper + + def __str__(self): + return f"Float ({self.lower}, {self.upper})" + + def __repr__(self): + return f"{self.get_typename()}({self.lower}, {self.upper})" + + +class IntegerVariable(DesignVariable): + """An integer variable that can take any integer value between the bounds (inclusive)""" + + def __init__(self, lower: int, upper: int): + if upper <= lower: + raise ValueError( + f"Upper bound should be higher than lower bound: {upper} <= {lower}" + ) + self.lower = lower + self.upper = upper + + def get_limits(self) -> Tuple[int, int]: + return self.lower, self.upper + + def __str__(self): + return f"Int ({self.lower}, {self.upper})" + + def __repr__(self): + return f"{self.get_typename()}({self.lower}, {self.upper})" + + +class OrdinalVariable(DesignVariable): + """An ordinal variable that can take any of the given value, and where order between the values matters""" + + def __init__(self, values: List[Union[str, int, float]]): + if len(values) < 2: + raise ValueError(f"There should at least be 2 values: {values}") + self.values = values + + @property + def lower(self) -> int: + return 0 + + @property + def upper(self) -> int: + return len(self.values) - 1 + + def get_limits(self) -> List[str]: + # We convert to integer strings for compatibility reasons + return [str(i) for i in range(len(self.values))] + + def __str__(self): + return f"Ord {self.values}" + + def __repr__(self): + return f"{self.get_typename()}({self.values})" + + +class CategoricalVariable(DesignVariable): + """A categorical variable that can take any of the given values, and where order does not matter""" + + def __init__(self, values: List[Union[str, int, float]]): + if len(values) < 2: + raise ValueError(f"There should at least be 2 values: {values}") + self.values = values + + @property + def lower(self) -> int: + return 0 + + @property + def upper(self) -> int: + return len(self.values) - 1 + + @property + def n_values(self): + return len(self.values) + + def get_limits(self) -> List[Union[str, int, float]]: + # We convert to strings for compatibility reasons + return [str(value) for value in self.values] + + def __str__(self): + return f"Cat {self.values}" + + def __repr__(self): + return f"{self.get_typename()}({self.values})" + + +class BaseDesignSpace: + """ + Interface for specifying (hierarchical) design spaces. + + This class itself only specifies the functionality that any design space definition should implement: + - a way to specify the design variables, their types, and their bounds or options + - a way to correct a set of design vectors such that they satisfy all design space hierarchy constraints + - a way to query which design variables are acting for a set of design vectors + - a way to impute a set of design vectors such that non-acting design variables are assigned some default value + - a way to sample n valid design vectors from the design space + + If you want to actually define a design space, use the `DesignSpace` class! + + Note that the correction, querying, and imputation mechanisms should all be implemented in one function + (`correct_get_acting`), as usually these operations are tightly related. + """ + + def __init__( + self, design_variables: List[DesignVariable] = None, random_state=None + ): + self._design_variables = design_variables + self._is_cat_mask = None + self._is_conditionally_acting_mask = None + self.seed = random_state + self.has_valcons_ord_int = False + + @property + def design_variables(self) -> List[DesignVariable]: + if self._design_variables is None: + self._design_variables = dvs = self._get_design_variables() + if dvs is None: + raise RuntimeError( + "Design space should either specify the design variables upon initialization " + "or as output from _get_design_variables!" + ) + return self._design_variables + + @property + def is_cat_mask(self) -> np.ndarray: + """Boolean mask specifying for each design variable whether it is a categorical variable""" + if self._is_cat_mask is None: + self._is_cat_mask = np.array( + [isinstance(dv, CategoricalVariable) for dv in self.design_variables] + ) + return self._is_cat_mask + + @property + def is_all_cont(self) -> bool: + """Whether or not the space is continuous""" + is_continuous = all( + isinstance(dv, FloatVariable) for dv in self.design_variables + ) + return is_continuous + + @property + def is_conditionally_acting(self) -> np.ndarray: + """Boolean mask specifying for each design variable whether it is conditionally acting (can be non-acting)""" + if self._is_conditionally_acting_mask is None: + self._is_conditionally_acting_mask = self._is_conditionally_acting() + return self._is_conditionally_acting_mask + + @property + def n_dv(self) -> int: + """Get the number of design variables""" + return len(self.design_variables) + + def correct_get_acting(self, x: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + """ + Correct the given matrix of design vectors and return the corrected vectors and the is_acting matrix. + It is automatically detected whether input is provided in unfolded space or not. + + Parameters + ---------- + x: np.ndarray [n_obs, dim] + - Input variables + + Returns + ------- + x_corrected: np.ndarray [n_obs, dim] + - Corrected and imputed input variables + is_acting: np.ndarray [n_obs, dim] + - Boolean matrix specifying for each variable whether it is acting or non-acting + """ + + # Detect whether input is provided in unfolded space + x = np.atleast_2d(x) + if x.shape[1] == self.n_dv: + x_is_unfolded = False + elif x.shape[1] == self._get_n_dim_unfolded(): + x_is_unfolded = True + else: + raise ValueError(f"Incorrect shape, expecting {self.n_dv} columns!") + + # If needed, fold before correcting + if x_is_unfolded: + x, _ = self.fold_x(x) + + indi = 0 + for i in self.design_variables: + if not (isinstance(i, FloatVariable)): + x[:, indi] = np.int64(np.round(x[:, indi], 0)) + indi += 1 + + # Correct and get the is_acting matrix + x_corrected, is_acting = self._correct_get_acting(x) + + # Check conditionally-acting status + if np.any(~is_acting[:, ~self.is_conditionally_acting]): + raise RuntimeError("Unconditionally acting variables cannot be non-acting!") + + # Unfold if needed + if x_is_unfolded: + x_corrected, is_acting = self.unfold_x(x_corrected, is_acting) + + return x_corrected, is_acting + + def decode_values( + self, x: np.ndarray, i_dv: int = None + ) -> List[Union[str, int, float, list]]: + """ + Return decoded values: converts ordinal and categorical back to their original values. + + If i_dv is given, decoding is done for one specific design variable only. + If i_dv=None, decoding will be done for all design variables: 1d input is interpreted as a design vector, + 2d input is interpreted as a set of design vectors. + """ + + def _decode_dv(x_encoded: np.ndarray, i_dv_decode): + dv = self.design_variables[i_dv_decode] + if isinstance(dv, (OrdinalVariable, CategoricalVariable)): + values = dv.values + decoded_values = [values[int(x_ij)] for x_ij in x_encoded] + return decoded_values + + # No need to decode integer or float variables + return list(x_encoded) + + # Decode one design variable + if i_dv is not None: + if len(x.shape) == 2: + x_i = x[:, i_dv] + elif len(x.shape) == 1: + x_i = x + else: + raise ValueError("Expected either 1 or 2-dimensional matrix!") + + # No need to decode for integer or float variable + return _decode_dv(x_i, i_dv_decode=i_dv) + + # Decode design vectors + n_dv = self.n_dv + is_1d = len(x.shape) == 1 + x_mat = np.atleast_2d(x) + if x_mat.shape[1] != n_dv: + raise ValueError( + f"Incorrect number of inputs, expected {n_dv} design variables, received {x_mat.shape[1]}" + ) + + decoded_des_vars = [_decode_dv(x_mat[:, i], i_dv_decode=i) for i in range(n_dv)] + decoded_des_vectors = [ + [decoded_des_vars[i][ix] for i in range(n_dv)] + for ix in range(x_mat.shape[0]) + ] + return decoded_des_vectors[0] if is_1d else decoded_des_vectors + + def sample_valid_x( + self, n: int, unfolded=False, random_state=None + ) -> Tuple[np.ndarray, np.ndarray]: + """ + Sample n design vectors and additionally return the is_acting matrix. + + Parameters + ---------- + n: int + - Number of samples to generate + unfolded: bool + - Whether to return the samples in unfolded space (each categorical level gets its own dimension) + + Returns + ------- + x: np.ndarray [n, dim] + - Valid design vectors + is_acting: np.ndarray [n, dim] + - Boolean matrix specifying for each variable whether it is acting or non-acting + """ + + # Sample from the design space + + x, is_acting = self._sample_valid_x(n, random_state=random_state) + + # Check conditionally-acting status + if np.any(~is_acting[:, ~self.is_conditionally_acting]): + raise RuntimeError("Unconditionally acting variables cannot be non-acting!") + + # Unfold if needed + if unfolded: + x, is_acting = self.unfold_x(x, is_acting) + + return x, is_acting + + def get_x_limits(self) -> list: + """Returns the variable limit definitions in SMT < 2.0 style""" + return [dv.get_limits() for dv in self.design_variables] + + def get_num_bounds(self): + """ + Get bounds for the design space. + + Returns + ------- + np.ndarray [nx, 2] + - Bounds of each dimension + """ + return np.array([(dv.lower, dv.upper) for dv in self.design_variables]) + + def get_unfolded_num_bounds(self): + """ + Get bounds for the unfolded continuous space. + + Returns + ------- + np.ndarray [nx cont, 2] + - Bounds of each dimension where limits for categorical variables are expanded to [0, 1] + """ + unfolded_x_limits = [] + for dv in self.design_variables: + if isinstance(dv, CategoricalVariable): + unfolded_x_limits += [[0, 1]] * dv.n_values + + elif isinstance(dv, OrdinalVariable): + # Note that this interpretation is slightly different from the original mixed_integer implementation in + # smt: we simply map ordinal values to integers, instead of converting them to integer literals + # This ensures that each ordinal value gets sampled evenly, also if the values themselves represent + # unevenly spaced (e.g. log-spaced) values + unfolded_x_limits.append([dv.lower, dv.upper]) + + else: + unfolded_x_limits.append(dv.get_limits()) + + return np.array(unfolded_x_limits).astype(float) + + def fold_x( + self, + x: np.ndarray, + is_acting: np.ndarray = None, + fold_mask: np.ndarray = None, + ) -> Tuple[np.ndarray, Optional[np.ndarray]]: + """ + Fold x and optionally is_acting. Folding reverses the one-hot encoding of categorical variables applied by + unfolding. + + Parameters + ---------- + x: np.ndarray [n, dim_unfolded] + - Unfolded samples + is_acting: np.ndarray [n, dim_unfolded] + - Boolean matrix specifying for each unfolded variable whether it is acting or non-acting + fold_mask: np.ndarray [dim_folded] + - Mask specifying which design variables to apply folding for + + Returns + ------- + x_folded: np.ndarray [n, dim] + - Folded samples + is_acting_folded: np.ndarray [n, dim] + - (Optional) boolean matrix specifying for each folded variable whether it is acting or non-acting + """ + + # Get number of unfolded dimension + x = np.atleast_2d(x) + x_folded = np.zeros((x.shape[0], len(self.design_variables))) + is_acting_folded = ( + np.ones(x_folded.shape, dtype=bool) if is_acting is not None else None + ) + + i_x_unfold = 0 + for i, dv in enumerate(self.design_variables): + if (isinstance(dv, CategoricalVariable)) and ( + fold_mask is None or fold_mask[i] + ): + n_dim_cat = dv.n_values + + # Categorical values are folded by reversed one-hot encoding: + # [[1, 0, 0], [0, 1, 0], [0, 0, 1]] --> [0, 1, 2].T + x_cat_unfolded = x[:, i_x_unfold : i_x_unfold + n_dim_cat] + value_index = np.argmax(x_cat_unfolded, axis=1) + x_folded[:, i] = value_index + + # The is_acting matrix is repeated column-wise, so we can just take the first column + if is_acting is not None: + is_acting_folded[:, i] = is_acting[:, i_x_unfold] + + i_x_unfold += n_dim_cat + + else: + x_folded[:, i] = x[:, i_x_unfold] + if is_acting is not None: + is_acting_folded[:, i] = is_acting[:, i_x_unfold] + i_x_unfold += 1 + + return x_folded, is_acting_folded + + def unfold_x( + self, x: np.ndarray, is_acting: np.ndarray = None, fold_mask: np.ndarray = None + ) -> Tuple[np.ndarray, Optional[np.ndarray]]: + """ + Unfold x and optionally is_acting. Unfolding creates one extra dimension for each categorical variable using + one-hot encoding. + + Parameters + ---------- + x: np.ndarray [n, dim] + - Folded samples + is_acting: np.ndarray [n, dim] + - Boolean matrix specifying for each variable whether it is acting or non-acting + fold_mask: np.ndarray [dim_folded] + - Mask specifying which design variables to apply folding for + + Returns + ------- + x_unfolded: np.ndarray [n, dim_unfolded] + - Unfolded samples + is_acting_unfolded: np.ndarray [n, dim_unfolded] + - (Optional) boolean matrix specifying for each unfolded variable whether it is acting or non-acting + """ + + # Get number of unfolded dimension + n_dim_unfolded = self._get_n_dim_unfolded() + x = np.atleast_2d(x) + x_unfolded = np.zeros((x.shape[0], n_dim_unfolded)) + is_acting_unfolded = ( + np.ones(x_unfolded.shape, dtype=bool) if is_acting is not None else None + ) + + i_x_unfold = 0 + for i, dv in enumerate(self.design_variables): + if isinstance(dv, CategoricalVariable) and ( + fold_mask is None or fold_mask[i] + ): + n_dim_cat = dv.n_values + x_cat = x_unfolded[:, i_x_unfold : i_x_unfold + n_dim_cat] + + # Categorical values are unfolded by one-hot encoding: + # [0, 1, 2].T --> [[1, 0, 0], [0, 1, 0], [0, 0, 1]] + x_i_int = x[:, i].astype(int) + for i_level in range(n_dim_cat): + has_value_mask = x_i_int == i_level + x_cat[has_value_mask, i_level] = 1 + + # The is_acting matrix is simply repeated column-wise + if is_acting is not None: + is_acting_unfolded[:, i_x_unfold : i_x_unfold + n_dim_cat] = ( + np.tile(is_acting[:, [i]], (1, n_dim_cat)) + ) + + i_x_unfold += n_dim_cat + + else: + x_unfolded[:, i_x_unfold] = x[:, i] + if is_acting is not None: + is_acting_unfolded[:, i_x_unfold] = is_acting[:, i] + i_x_unfold += 1 + + x_unfolded = x_unfolded[:, :i_x_unfold] + if is_acting is not None: + is_acting_unfolded = is_acting_unfolded[:, :i_x_unfold] + + return x_unfolded, is_acting_unfolded + + def _get_n_dim_unfolded(self) -> int: + return sum( + [ + dv.n_values if isinstance(dv, CategoricalVariable) else 1 + for dv in self.design_variables + ] + ) + + @staticmethod + def _round_equally_distributed(x_cont, lower: int, upper: int): + """ + To ensure equal distribution of continuous values to discrete values, we first stretch-out the continuous values + to extend to 0.5 beyond the integer limits and then round. This ensures that the values at the limits get a + large-enough share of the continuous values. + """ + + x_cont[x_cont < lower] = lower + x_cont[x_cont > upper] = upper + + diff = upper - lower + x_stretched = (x_cont - lower) * ((diff + 0.9999) / (diff + 1e-16)) - 0.5 + return np.round(x_stretched) + lower + + def _to_seed(self, random_state=None): + seed = None + if isinstance(random_state, int): + seed = random_state + elif isinstance(random_state, np.random.RandomState): + seed = random_state.get_state()[1][0] + return seed + + def _get_design_variables(self) -> List[DesignVariable]: + """Return the design variables defined in this design space if not provided upon initialization of the class""" + + """IMPLEMENT FUNCTIONS BELOW""" + + def _is_conditionally_acting(self) -> np.ndarray: + """ + Return for each design variable whether it is conditionally acting or not. A design variable is conditionally + acting if it MAY be non-acting. + + Returns + ------- + is_conditionally_acting: np.ndarray [dim] + - Boolean vector specifying for each design variable whether it is conditionally acting + """ + raise NotImplementedError + + def _correct_get_acting(self, x: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + """ + Correct the given matrix of design vectors and return the corrected vectors and the is_acting matrix. + + Parameters + ---------- + x: np.ndarray [n_obs, dim] + - Input variables + + Returns + ------- + x_corrected: np.ndarray [n_obs, dim] + - Corrected and imputed input variables + is_acting: np.ndarray [n_obs, dim] + - Boolean matrix specifying for each variable whether it is acting or non-acting + """ + raise NotImplementedError + + def _sample_valid_x( + self, + n: int, + random_state=None, + ) -> Tuple[np.ndarray, np.ndarray]: + """ + Sample n design vectors and additionally return the is_acting matrix. + + Returns + ------- + x: np.ndarray [n, dim] + - Valid design vectors + is_acting: np.ndarray [n, dim] + - Boolean matrix specifying for each variable whether it is acting or non-acting + """ + raise NotImplementedError + + def __str__(self): + raise NotImplementedError + + def __repr__(self): + raise NotImplementedError From 97b737837d1173e85741e2176fa2cf2b8a0c62fd Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 16:17:30 +0200 Subject: [PATCH 30/77] add base design space --- smt/utils/design_space.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index cf6927aaa..77310905c 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -623,3 +623,5 @@ def __str__(self): def __repr__(self): raise NotImplementedError +class DesignSpace(BaseDesignSpace): + pass From cad8d89a8232351ea22486dabc918454c653dbd8 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 16:22:54 +0200 Subject: [PATCH 31/77] fix adsg import --- smt/utils/design_space.py | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index 77310905c..61bea12eb 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -13,9 +13,12 @@ from SMTDesignSpace import * HAS_SMTDesignSpace = True - + HAS_CONFIG_SPACE = True + HAS_ADSG = True except ImportError: HAS_SMTDesignSpace = False + HAS_CONFIG_SPACE = False + HAS_ADSG = False class Configuration: @@ -35,8 +38,6 @@ def ensure_design_space(xt=None, xlimits=None, design_space=None) -> "BaseDesign if design_space is not None and isinstance(design_space, BaseDesignSpace): return design_space - if HAS_ADSG and design_space is not None and isinstance(design_space, ADSG): - return _convert_adsg_to_legacy(design_space) if xlimits is not None: return DesignSpace(xlimits) @@ -623,5 +624,7 @@ def __str__(self): def __repr__(self): raise NotImplementedError + + class DesignSpace(BaseDesignSpace): pass From 27e06ea169ac9c8000fd2de6d0b20938fdbec5ba Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 20:06:05 +0200 Subject: [PATCH 32/77] update design_space --- setup.py | 4 +- smt/utils/design_space.py | 320 +++++++++++++++++++++++++++++++++++++- 2 files changed, 321 insertions(+), 3 deletions(-) diff --git a/setup.py b/setup.py index ae1eeb0eb..7742f0bf0 100644 --- a/setup.py +++ b/setup.py @@ -118,8 +118,8 @@ "numba": [ # pip install smt[numba] "numba~=0.56.4", ], - "cs": [ # pip install smt[cs] - "ConfigSpace~=0.6.1", + "SMTDesignSpace": [ # pip install smt[SMTDesignSpace] + " git+https://github.com/SMTorg/smt-design-space", ], "gpx": ["egobox~=0.20"], # pip install smt[gpx] }, diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index 61bea12eb..ea428c1a5 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -626,5 +626,323 @@ def __repr__(self): raise NotImplementedError +VarValueType = Union[int, str, List[Union[int, str]]] + + +def raise_config_space(): + raise RuntimeError( + "Dependencies are not installed, run: pip install smt[SMTDesignSpace]" + ) + + class DesignSpace(BaseDesignSpace): - pass + """ + Class for defining a (hierarchical) design space by defining design variables, defining decreed variables + (optional), and adding value constraints (optional). + + Numerical bounds can be requested using `get_num_bounds()`. + If needed, it is possible to get the legacy SMT < 2.0 `xlimits` format using `get_x_limits()`. + + Parameters + ---------- + design_variables: list[DesignVariable] + - The list of design variables: FloatVariable, IntegerVariable, OrdinalVariable, or CategoricalVariable + + Examples + -------- + Instantiate the design space with all its design variables: + + >>> from smt.utils.design_space import * + >>> ds = DesignSpace([ + >>> CategoricalVariable(['A', 'B']), # x0 categorical: A or B; order is not relevant + >>> OrdinalVariable(['C', 'D', 'E']), # x1 ordinal: C, D or E; order is relevant + >>> IntegerVariable(0, 2), # x2 integer between 0 and 2 (inclusive): 0, 1, 2 + >>> FloatVariable(0, 1), # c3 continuous between 0 and 1 + >>> ]) + >>> assert len(ds.design_variables) == 4 + + You can define decreed variables (conditional activation): + + >>> ds.declare_decreed_var(decreed_var=1, meta_var=0, meta_value='A') # Activate x1 if x0 == A + + + After defining everything correctly, you can then use the design space object to correct design vectors and get + information about which design variables are acting: + + >>> x_corr, is_acting = ds.correct_get_acting(np.array([ + >>> [0, 0, 2, .25], + >>> [0, 2, 1, .75], + >>> ])) + >>> assert np.all(x_corr == np.array([ + >>> [0, 0, 2, .25], + >>> [0, 2, 0, .75], + >>> ])) + >>> assert np.all(is_acting == np.array([ + >>> [True, True, True, True], + >>> [True, True, False, True], # x2 is not acting if x1 != C or D (0 or 1) + >>> ])) + + It is also possible to randomly sample design vectors conforming to the constraints: + + >>> x_sampled, is_acting_sampled = ds.sample_valid_x(100) + + You can also instantiate a purely-continuous design space from bounds directly: + + >>> continuous_design_space = DesignSpace([(0, 1), (0, 2), (.5, 5.5)]) + >>> assert continuous_design_space.n_dv == 3 + + If needed, it is possible to get the legacy design space definition format: + + >>> xlimits = ds.get_x_limits() + >>> cont_bounds = ds.get_num_bounds() + >>> unfolded_cont_bounds = ds.get_unfolded_num_bounds() + + """ + + def __init__( + self, + design_variables: Union[List[DesignVariable], list, np.ndarray], + random_state=None, + ): + self.sampler = None + + # Assume float variable bounds as inputs + def _is_num(val): + try: + float(val) + return True + except ValueError: + return False + + if len(design_variables) > 0 and not isinstance( + design_variables[0], DesignVariable + ): + converted_dvs = [] + for bounds in design_variables: + if len(bounds) != 2 or not _is_num(bounds[0]) or not _is_num(bounds[1]): + raise RuntimeError( + f"Expecting either a list of DesignVariable objects or float variable " + f"bounds! Unrecognized: {bounds!r}" + ) + converted_dvs.append(FloatVariable(bounds[0], bounds[1])) + design_variables = converted_dvs + + self.random_state = random_state # For testing + seed = self.random_state + # dict[int, dict[any, list[int]]]: {meta_var_idx: {value: [decreed_var_idx, ...], ...}, ...} + self._meta_vars = {} + self._is_decreed = np.zeros((len(design_variables),), dtype=bool) + + super().__init__(design_variables=design_variables, random_state=seed) + + def declare_decreed_var( + self, decreed_var: int, meta_var: int, meta_value: VarValueType + ): + """ + Define a conditional (decreed) variable to be active when the meta variable has (one of) the provided values. + + Parameters + ---------- + decreed_var: int + - Index of the conditional variable (the variable that is conditionally active) + meta_var: int + - Index of the meta variable (the variable that determines whether the conditional var is active) + meta_value: int | str | list[int|str] + - The value or list of values that the meta variable can have to activate the decreed var + """ + + # Variables cannot be both meta and decreed at the same time + if self._is_decreed[meta_var]: + raise RuntimeError( + f"Variable cannot be both meta and decreed ({meta_var})!" + ) + + # Variables can only be decreed by one meta var + if self._is_decreed[decreed_var]: + raise RuntimeError(f"Variable is already decreed: {decreed_var}") + + # Define meta-decreed relationship + if meta_var not in self._meta_vars: + self._meta_vars[meta_var] = {} + + meta_var_obj = self.design_variables[meta_var] + for value in meta_value if isinstance(meta_value, Sequence) else [meta_value]: + encoded_value = value + if isinstance(meta_var_obj, (OrdinalVariable, CategoricalVariable)): + if value in meta_var_obj.values: + encoded_value = meta_var_obj.values.index(value) + + if encoded_value not in self._meta_vars[meta_var]: + self._meta_vars[meta_var][encoded_value] = [] + self._meta_vars[meta_var][encoded_value].append(decreed_var) + + # Mark as decreed (conditionally acting) + self._is_decreed[decreed_var] = True + + def add_value_constraint( + self, var1: int, value1: VarValueType, var2: int, value2: VarValueType + ): + """ + Define a constraint where two variables cannot have the given values at the same time. + + Parameters + ---------- + var1: int + - Index of the first variable + value1: int | str | list[int|str] + - Value or values that the first variable is checked against + var2: int + - Index of the second variable + value2: int | str | list[int|str] + - Value or values that the second variable is checked against + """ + raise_config_space() + + def _get_param(self, idx): + raise KeyError(f"Variable not found: {idx}") + + def _get_param2(self, idx): + raise KeyError(f"Variable not found: {idx}") + + @property + def _cs_var_idx(self): + """ + ConfigurationSpace applies topological sort when adding conditions, so compared to what we expect the order of + parameters might have changed. + + This property contains the indices of the params in the ConfigurationSpace. + """ + raise_config_space() + + @property + def _inv_cs_var_idx(self): + """ + See _cs_var_idx. This function returns the opposite mapping: the positions of our design variables for each + param. + """ + raise_config_space() + + def _is_conditionally_acting(self) -> np.ndarray: + # Decreed variables are the conditionally acting variables + return self._is_decreed + + def _correct_get_acting(self, x: np.ndarray) -> Tuple[np.ndarray, np.ndarray]: + """Correct and impute design vectors""" + x = x.astype(float) + # Simplified implementation + # Correct discrete variables + x_corr = x.copy() + self._normalize_x(x_corr, cs_normalize=False) + + # Determine which variables are acting + is_acting = np.ones(x_corr.shape, dtype=bool) + is_acting[:, self._is_decreed] = False + for i, xi in enumerate(x_corr): + for i_meta, decrees in self._meta_vars.items(): + meta_var_value = xi[i_meta] + if meta_var_value in decrees: + i_decreed_vars = decrees[meta_var_value] + is_acting[i, i_decreed_vars] = True + + # Impute non-acting variables + self._impute_non_acting(x_corr, is_acting) + + return x_corr, is_acting + + def _sample_valid_x( + self, n: int, random_state=None + ) -> Tuple[np.ndarray, np.ndarray]: + """Sample design vectors""" + # Simplified implementation: sample design vectors in unfolded space + x_limits_unfolded = self.get_unfolded_num_bounds() + if self.random_state is None: + self.random_state = random_state + + if self.sampler is None: + self.sampler = LHS( + xlimits=x_limits_unfolded, + random_state=random_state, + criterion="ese", + ) + x = self.sampler(n) + # Fold and cast to discrete + x, _ = self.fold_x(x) + self._normalize_x(x, cs_normalize=False) + # Get acting information and impute + return self.correct_get_acting(x) + + def _get_correct_config(self, vector: np.ndarray) -> Configuration: + raise_config_space() + + def _configs_to_x( + self, configs: List["Configuration"] + ) -> Tuple[np.ndarray, np.ndarray]: + raise_config_space() + + def _impute_non_acting(self, x: np.ndarray, is_acting: np.ndarray): + for i, dv in enumerate(self.design_variables): + if isinstance(dv, FloatVariable): + # Impute continuous variables to the mid of their bounds + x[~is_acting[:, i], i] = 0.5 * (dv.upper - dv.lower) + dv.lower + + else: + # Impute discrete variables to their lower bounds + lower = 0 + if isinstance(dv, (IntegerVariable, OrdinalVariable)): + lower = dv.lower + + x[~is_acting[:, i], i] = lower + + def _normalize_x(self, x: np.ndarray, cs_normalize=True): + for i, dv in enumerate(self.design_variables): + if isinstance(dv, FloatVariable): + if cs_normalize: + dv.lower = min(np.min(x[:, i]), dv.lower) + dv.upper = max(np.max(x[:, i]), dv.upper) + x[:, i] = np.clip( + (x[:, i] - dv.lower) / (dv.upper - dv.lower + 1e-16), 0, 1 + ) + + elif isinstance(dv, IntegerVariable): + x[:, i] = self._round_equally_distributed(x[:, i], dv.lower, dv.upper) + + if cs_normalize: + # After rounding, normalize between 0 and 1, where 0 and 1 represent the stretched bounds + x[:, i] = (x[:, i] - dv.lower + 0.49999) / ( + dv.upper - dv.lower + 0.9999 + ) + + def _normalize_x_no_integer(self, x: np.ndarray, cs_normalize=True): + raise_config_space() + + def _cs_denormalize_x(self, x: np.ndarray): + for i, dv in enumerate(self.design_variables): + if isinstance(dv, FloatVariable): + x[:, i] = x[:, i] * (dv.upper - dv.lower) + dv.lower + + elif isinstance(dv, IntegerVariable): + # Integer values are normalized similarly to what is done in _round_equally_distributed + x[:, i] = np.round( + x[:, i] * (dv.upper - dv.lower + 0.9999) + dv.lower - 0.49999 + ) + + def _cs_denormalize_x_ordered(self, x: np.ndarray): + ordereddesign_variables = [ + self.design_variables[i] for i in self._inv_cs_var_idx + ] + for i, dv in enumerate(ordereddesign_variables): + if isinstance(dv, FloatVariable): + x[:, i] = x[:, i] * (dv.upper - dv.lower) + dv.lower + + elif isinstance(dv, IntegerVariable): + # Integer values are normalized similarly to what is done in _round_equally_distributed + x[:, i] = np.round( + x[:, i] * (dv.upper - dv.lower + 0.9999) + dv.lower - 0.49999 + ) + + def __str__(self): + dvs = "\n".join([f"x{i}: {dv!s}" for i, dv in enumerate(self.design_variables)]) + return f"Design space:\n{dvs}" + + def __repr__(self): + return f"{self.__class__.__name__}({self.design_variables!r})" From 46ff9bc7919d25a1e19933a298060ddb8164d608 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 20:14:24 +0200 Subject: [PATCH 33/77] update setup --- setup.py | 3 --- smt/utils/design_space.py | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/setup.py b/setup.py index 7742f0bf0..ae462c220 100644 --- a/setup.py +++ b/setup.py @@ -118,9 +118,6 @@ "numba": [ # pip install smt[numba] "numba~=0.56.4", ], - "SMTDesignSpace": [ # pip install smt[SMTDesignSpace] - " git+https://github.com/SMTorg/smt-design-space", - ], "gpx": ["egobox~=0.20"], # pip install smt[gpx] }, python_requires=">=3.8", diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index ea428c1a5..03296c6c0 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -631,7 +631,7 @@ def __repr__(self): def raise_config_space(): raise RuntimeError( - "Dependencies are not installed, run: pip install smt[SMTDesignSpace]" + "Dependencies are not installed, please install SMTDesignSpace." ) From ef48563ac2e33e05c70867b5457e42a3c60be2a9 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 20:30:22 +0200 Subject: [PATCH 34/77] restore lhs --- smt/applications/tests/test_ego.py | 13 +++---------- smt/utils/design_space.py | 2 +- 2 files changed, 4 insertions(+), 11 deletions(-) diff --git a/smt/applications/tests/test_ego.py b/smt/applications/tests/test_ego.py index 0bf325c16..c15bafaa7 100644 --- a/smt/applications/tests/test_ego.py +++ b/smt/applications/tests/test_ego.py @@ -1139,10 +1139,7 @@ def f_obj(X): LHS, design_space, criterion="ese", random_state=random_state ) Xt = sampling(n_doe) - if ds.HAS_CONFIG_SPACE: # results differs wrt config_space impl - self.assertAlmostEqual(np.sum(Xt), 24.811925491708156, delta=1e-4) - else: - self.assertAlmostEqual(np.sum(Xt), 28.568852027679586, delta=1e-4) + self.assertAlmostEqual(np.sum(Xt), 28.568852027679586, delta=1e-4) Xt = np.array( [ [0.37454012, 1.0], @@ -1174,12 +1171,8 @@ def f_obj(X): n_start=25, ) x_opt, y_opt, dnk, x_data, y_data = ego.optimize(fun=f_obj) - if ds.HAS_CONFIG_SPACE: # results differs wrt config_space impl - self.assertAlmostEqual(np.sum(y_data), 8.846225704750577, delta=1e-4) - self.assertAlmostEqual(np.sum(x_data), 41.811925504901374, delta=1e-4) - else: - self.assertAlmostEqual(np.sum(y_data), 7.8471910288712, delta=1e-4) - self.assertAlmostEqual(np.sum(x_data), 34.81192549, delta=1e-4) + self.assertAlmostEqual(np.sum(y_data), 7.8471910288712, delta=1e-4) + self.assertAlmostEqual(np.sum(x_data), 34.81192549, delta=1e-4) def test_ego_gek(self): ego, fun = self.initialize_ego_gek() diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index 03296c6c0..92a531ada 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -7,7 +7,7 @@ from typing import List, Optional, Tuple, Union import numpy as np - +from smt.sampling_methods.lhs import LHS try: from SMTDesignSpace import * From bf52800a88e3927b52fb86a2052db52e0773940f Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 20:44:52 +0200 Subject: [PATCH 35/77] restore ego' --- smt/applications/tests/test_ego.py | 13 ++++++++++--- .../tests/test_surrogate_model_examples.py | 14 ++++++++++++-- smt/utils/design_space.py | 4 +--- 3 files changed, 23 insertions(+), 8 deletions(-) diff --git a/smt/applications/tests/test_ego.py b/smt/applications/tests/test_ego.py index c15bafaa7..0bf325c16 100644 --- a/smt/applications/tests/test_ego.py +++ b/smt/applications/tests/test_ego.py @@ -1139,7 +1139,10 @@ def f_obj(X): LHS, design_space, criterion="ese", random_state=random_state ) Xt = sampling(n_doe) - self.assertAlmostEqual(np.sum(Xt), 28.568852027679586, delta=1e-4) + if ds.HAS_CONFIG_SPACE: # results differs wrt config_space impl + self.assertAlmostEqual(np.sum(Xt), 24.811925491708156, delta=1e-4) + else: + self.assertAlmostEqual(np.sum(Xt), 28.568852027679586, delta=1e-4) Xt = np.array( [ [0.37454012, 1.0], @@ -1171,8 +1174,12 @@ def f_obj(X): n_start=25, ) x_opt, y_opt, dnk, x_data, y_data = ego.optimize(fun=f_obj) - self.assertAlmostEqual(np.sum(y_data), 7.8471910288712, delta=1e-4) - self.assertAlmostEqual(np.sum(x_data), 34.81192549, delta=1e-4) + if ds.HAS_CONFIG_SPACE: # results differs wrt config_space impl + self.assertAlmostEqual(np.sum(y_data), 8.846225704750577, delta=1e-4) + self.assertAlmostEqual(np.sum(x_data), 41.811925504901374, delta=1e-4) + else: + self.assertAlmostEqual(np.sum(y_data), 7.8471910288712, delta=1e-4) + self.assertAlmostEqual(np.sum(x_data), 34.81192549, delta=1e-4) def test_ego_gek(self): ego, fun = self.initialize_ego_gek() diff --git a/smt/surrogate_models/tests/test_surrogate_model_examples.py b/smt/surrogate_models/tests/test_surrogate_model_examples.py index 10ae60f43..f9746518a 100644 --- a/smt/surrogate_models/tests/test_surrogate_model_examples.py +++ b/smt/surrogate_models/tests/test_surrogate_model_examples.py @@ -249,8 +249,18 @@ def test_mixed_int_krg(self): from smt.applications.mixed_integer import MixedIntegerKrigingModel from smt.surrogate_models import KRG - from SMTDesignSpace.design_space import DesignSpace, IntegerVariable - + from smt.utils.design_space import HAS_SMTDesignSpace + + if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + DesignSpace, + IntegerVariable + ) + else: + from smt.utils.design_space import ( + DesignSpace, + IntegerVariable + ) xt = np.array([0.0, 2.0, 3.0]) yt = np.array([0.0, 1.5, 0.9]) diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index 92a531ada..dee92a817 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -630,9 +630,7 @@ def __repr__(self): def raise_config_space(): - raise RuntimeError( - "Dependencies are not installed, please install SMTDesignSpace." - ) + raise RuntimeError("Dependencies are not installed, please install SMTDesignSpace.") class DesignSpace(BaseDesignSpace): From 50108e7c067a18d00a2582ebd826bcb00b6ef29e Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 21:07:16 +0200 Subject: [PATCH 36/77] update tests --- smt/applications/tests/test_mixed_integer.py | 81 +++++++++++++++----- smt/problems/tests/test_problem_examples.py | 1 + 2 files changed, 64 insertions(+), 18 deletions(-) diff --git a/smt/applications/tests/test_mixed_integer.py b/smt/applications/tests/test_mixed_integer.py index d95293837..0329fa6ba 100644 --- a/smt/applications/tests/test_mixed_integer.py +++ b/smt/applications/tests/test_mixed_integer.py @@ -55,6 +55,7 @@ MixHrcKernelType, MixIntKernelType, ) +from typing import List, Optional, Sequence, Tuple, Union class TestMixedInteger(unittest.TestCase): @@ -488,11 +489,27 @@ def run_mixed_integer_lhs_example(self): from smt.applications.mixed_integer import MixedIntegerSamplingMethod from smt.sampling_methods import LHS - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) + + if HAS_SMTDesignSpace: + from SMTDesignSpace import design_space as ds + from SMTDesignSpace.design_space import ( + HAS_CONFIG_SPACE, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) + else: + from smt.utils import design_space as ds + from smt.utils.design_space import ( + HAS_CONFIG_SPACE, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) float_var = FloatVariable(0, 4) cat_var = CategoricalVariable(["blue", "red"]) @@ -553,12 +570,27 @@ def run_mixed_integer_context_example(self): from smt.applications.mixed_integer import MixedIntegerContext from smt.surrogate_models import KRG - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - ) + if HAS_SMTDesignSpace: + from SMTDesignSpace import design_space as ds + from SMTDesignSpace.design_space import ( + HAS_CONFIG_SPACE, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) + else: + from smt.utils import design_space as ds + from smt.utils.design_space import ( + HAS_CONFIG_SPACE, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) + design_space = DesignSpace( [ @@ -813,13 +845,26 @@ def run_hierarchical_design_space_example(self): ) from smt.sampling_methods import LHS from smt.surrogate_models import KRG, MixHrcKernelType, MixIntKernelType - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) + if HAS_SMTDesignSpace: + from SMTDesignSpace import design_space as ds + from SMTDesignSpace.design_space import ( + HAS_CONFIG_SPACE, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) + else: + from smt.utils import design_space as ds + from smt.utils.design_space import ( + HAS_CONFIG_SPACE, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) ds = DesignSpace( [ diff --git a/smt/problems/tests/test_problem_examples.py b/smt/problems/tests/test_problem_examples.py index dc6237406..f7932deb1 100644 --- a/smt/problems/tests/test_problem_examples.py +++ b/smt/problems/tests/test_problem_examples.py @@ -8,6 +8,7 @@ except ImportError: NO_MATPLOTLIB = True +from typing import List, Optional, Sequence, Tuple, Union class Test(unittest.TestCase): @unittest.skipIf(NO_MATPLOTLIB, "Matplotlib not installed") From bf0ddf41236d04bb6b0f13790e92a69055791494 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 21:27:26 +0200 Subject: [PATCH 37/77] ruff --- smt/applications/tests/test_mixed_integer.py | 22 +++---------------- smt/problems/tests/test_problem_examples.py | 2 +- .../tests/test_surrogate_model_examples.py | 12 +++------- smt/utils/design_space.py | 3 +-- 4 files changed, 8 insertions(+), 31 deletions(-) diff --git a/smt/applications/tests/test_mixed_integer.py b/smt/applications/tests/test_mixed_integer.py index 0329fa6ba..612f54111 100644 --- a/smt/applications/tests/test_mixed_integer.py +++ b/smt/applications/tests/test_mixed_integer.py @@ -55,7 +55,6 @@ MixHrcKernelType, MixIntKernelType, ) -from typing import List, Optional, Sequence, Tuple, Union class TestMixedInteger(unittest.TestCase): @@ -489,26 +488,18 @@ def run_mixed_integer_lhs_example(self): from smt.applications.mixed_integer import MixedIntegerSamplingMethod from smt.sampling_methods import LHS - + if HAS_SMTDesignSpace: - from SMTDesignSpace import design_space as ds from SMTDesignSpace.design_space import ( - HAS_CONFIG_SPACE, CategoricalVariable, DesignSpace, FloatVariable, - IntegerVariable, - OrdinalVariable, ) else: - from smt.utils import design_space as ds from smt.utils.design_space import ( - HAS_CONFIG_SPACE, CategoricalVariable, DesignSpace, FloatVariable, - IntegerVariable, - OrdinalVariable, ) float_var = FloatVariable(0, 4) @@ -570,28 +561,22 @@ def run_mixed_integer_context_example(self): from smt.applications.mixed_integer import MixedIntegerContext from smt.surrogate_models import KRG + if HAS_SMTDesignSpace: - from SMTDesignSpace import design_space as ds from SMTDesignSpace.design_space import ( - HAS_CONFIG_SPACE, CategoricalVariable, DesignSpace, FloatVariable, IntegerVariable, - OrdinalVariable, ) else: - from smt.utils import design_space as ds from smt.utils.design_space import ( - HAS_CONFIG_SPACE, CategoricalVariable, DesignSpace, FloatVariable, IntegerVariable, - OrdinalVariable, ) - design_space = DesignSpace( [ IntegerVariable(0, 5), @@ -845,10 +830,10 @@ def run_hierarchical_design_space_example(self): ) from smt.sampling_methods import LHS from smt.surrogate_models import KRG, MixHrcKernelType, MixIntKernelType + if HAS_SMTDesignSpace: from SMTDesignSpace import design_space as ds from SMTDesignSpace.design_space import ( - HAS_CONFIG_SPACE, CategoricalVariable, DesignSpace, FloatVariable, @@ -858,7 +843,6 @@ def run_hierarchical_design_space_example(self): else: from smt.utils import design_space as ds from smt.utils.design_space import ( - HAS_CONFIG_SPACE, CategoricalVariable, DesignSpace, FloatVariable, diff --git a/smt/problems/tests/test_problem_examples.py b/smt/problems/tests/test_problem_examples.py index f7932deb1..b01cccd34 100644 --- a/smt/problems/tests/test_problem_examples.py +++ b/smt/problems/tests/test_problem_examples.py @@ -8,7 +8,7 @@ except ImportError: NO_MATPLOTLIB = True -from typing import List, Optional, Sequence, Tuple, Union + class Test(unittest.TestCase): @unittest.skipIf(NO_MATPLOTLIB, "Matplotlib not installed") diff --git a/smt/surrogate_models/tests/test_surrogate_model_examples.py b/smt/surrogate_models/tests/test_surrogate_model_examples.py index f9746518a..2e6862632 100644 --- a/smt/surrogate_models/tests/test_surrogate_model_examples.py +++ b/smt/surrogate_models/tests/test_surrogate_model_examples.py @@ -250,17 +250,11 @@ def test_mixed_int_krg(self): from smt.applications.mixed_integer import MixedIntegerKrigingModel from smt.surrogate_models import KRG from smt.utils.design_space import HAS_SMTDesignSpace - + if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - DesignSpace, - IntegerVariable - ) + from SMTDesignSpace.design_space import DesignSpace, IntegerVariable else: - from smt.utils.design_space import ( - DesignSpace, - IntegerVariable - ) + from smt.utils.design_space import DesignSpace, IntegerVariable xt = np.array([0.0, 2.0, 3.0]) yt = np.array([0.0, 1.5, 0.9]) diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index dee92a817..c45b8944f 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -4,10 +4,9 @@ This package is distributed under New BSD license. """ -from typing import List, Optional, Tuple, Union - import numpy as np from smt.sampling_methods.lhs import LHS +from typing import List, Optional, Sequence, Tuple, Union try: from SMTDesignSpace import * From 37790f13efaf263d85ec665919fdcf326c74934a Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 22:03:28 +0200 Subject: [PATCH 38/77] ruff --- smt/problems/tests/test_problem_examples.py | 1 - smt/surrogate_models/__init__.py | 8 -------- smt/utils/design_space.py | 2 +- 3 files changed, 1 insertion(+), 10 deletions(-) diff --git a/smt/problems/tests/test_problem_examples.py b/smt/problems/tests/test_problem_examples.py index b01cccd34..dc6237406 100644 --- a/smt/problems/tests/test_problem_examples.py +++ b/smt/problems/tests/test_problem_examples.py @@ -9,7 +9,6 @@ NO_MATPLOTLIB = True - class Test(unittest.TestCase): @unittest.skipIf(NO_MATPLOTLIB, "Matplotlib not installed") def test_cantilever_beam(self): diff --git a/smt/surrogate_models/__init__.py b/smt/surrogate_models/__init__.py index 63bef148b..49b444de9 100644 --- a/smt/surrogate_models/__init__.py +++ b/smt/surrogate_models/__init__.py @@ -13,28 +13,20 @@ from smt.utils.design_space import HAS_SMTDesignSpace if HAS_SMTDesignSpace: - from SMTDesignSpace import design_space as ds from SMTDesignSpace.design_space import ( - HAS_CONFIG_SPACE, CategoricalVariable, - BaseDesignSpace, DesignSpace, FloatVariable, IntegerVariable, OrdinalVariable, - ensure_design_space, ) else: - from smt.utils import design_space as ds from smt.utils.design_space import ( - HAS_CONFIG_SPACE, CategoricalVariable, DesignSpace, - BaseDesignSpace, FloatVariable, IntegerVariable, OrdinalVariable, - ensure_design_space, ) from smt.utils.kriging import MixHrcKernelType diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index c45b8944f..ab55222ab 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -9,7 +9,7 @@ from typing import List, Optional, Sequence, Tuple, Union try: - from SMTDesignSpace import * + import SMTDesignSpace HAS_SMTDesignSpace = True HAS_CONFIG_SPACE = True From e353487f6bdba248bcfea05e3ecb4e02f7ffae10 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 22:13:06 +0200 Subject: [PATCH 39/77] restore tests --- smt/utils/test/test_design_space.py | 862 ++++++++++++++++++++++++++++ 1 file changed, 862 insertions(+) create mode 100644 smt/utils/test/test_design_space.py diff --git a/smt/utils/test/test_design_space.py b/smt/utils/test/test_design_space.py new file mode 100644 index 000000000..976454c7e --- /dev/null +++ b/smt/utils/test/test_design_space.py @@ -0,0 +1,862 @@ +""" +Author: Jasper Bussemaker +""" + +import contextlib +import itertools +import unittest + +import numpy as np + +from smt.sampling_methods import LHS + +from smt.utils.design_space import HAS_SMTDesignSpace + +if HAS_SMTDesignSpace: + from SMTDesignSpace import design_space as ds + from SMTDesignSpace.design_space import ( + HAS_CONFIG_SPACE, + HAS_ADSG, + ArchDesignSpaceGraph, + BaseDesignSpace, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) + +else: + from smt.utils import design_space as ds + from smt.utils.design_space import ( + HAS_CONFIG_SPACE, + HAS_ADSG, + BaseDesignSpace, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) + + +@contextlib.contextmanager +def simulate_no_config_space(do_simulate=True): + if ds.HAS_CONFIG_SPACE and do_simulate: + ds.HAS_CONFIG_SPACE = False + yield + ds.HAS_CONFIG_SPACE = True + else: + yield + + +class Test(unittest.TestCase): + def test_design_variables(self): + with self.assertRaises(ValueError): + FloatVariable(1, 0) + + float_var = FloatVariable(0, 1) + self.assertEqual(float_var.lower, 0) + self.assertEqual(float_var.upper, 1) + self.assertEqual(float_var.get_limits(), (0, 1)) + self.assertTrue(str(float_var)) + self.assertTrue(repr(float_var)) + self.assertEqual("FloatVariable", float_var.get_typename()) + + with self.assertRaises(ValueError): + IntegerVariable(1, 0) + + int_var = IntegerVariable(0, 1) + self.assertEqual(int_var.lower, 0) + self.assertEqual(int_var.upper, 1) + self.assertEqual(int_var.get_limits(), (0, 1)) + self.assertTrue(str(int_var)) + self.assertTrue(repr(int_var)) + self.assertEqual("IntegerVariable", int_var.get_typename()) + + with self.assertRaises(ValueError): + OrdinalVariable([]) + with self.assertRaises(ValueError): + OrdinalVariable(["1"]) + + ord_var = OrdinalVariable(["A", "B", "C"]) + self.assertEqual(ord_var.values, ["A", "B", "C"]) + self.assertEqual(ord_var.get_limits(), ["0", "1", "2"]) + self.assertEqual(ord_var.lower, 0) + self.assertEqual(ord_var.upper, 2) + self.assertTrue(str(ord_var)) + self.assertTrue(repr(ord_var)) + self.assertEqual("OrdinalVariable", ord_var.get_typename()) + + with self.assertRaises(ValueError): + CategoricalVariable([]) + with self.assertRaises(ValueError): + CategoricalVariable(["A"]) + + cat_var = CategoricalVariable(["A", "B", "C"]) + self.assertEqual(cat_var.values, ["A", "B", "C"]) + self.assertEqual(cat_var.get_limits(), ["A", "B", "C"]) + self.assertEqual(cat_var.lower, 0) + self.assertEqual(cat_var.upper, 2) + self.assertTrue(str(cat_var)) + self.assertTrue(repr(cat_var)) + self.assertEqual("CategoricalVariable", cat_var.get_typename()) + + def test_rounding(self): + ds = BaseDesignSpace( + [ + IntegerVariable(0, 5), + IntegerVariable(-1, 1), + IntegerVariable(2, 4), + ] + ) + + x = np.array( + list( + itertools.product( + np.linspace(0, 5, 20), np.linspace(-1, 1, 20), np.linspace(2, 4, 20) + ) + ) + ) + for i, dv in enumerate(ds.design_variables): + self.assertIsInstance(dv, IntegerVariable) + x[:, i] = ds._round_equally_distributed(x[:, i], dv.lower, dv.upper) + + x1, x1_counts = np.unique(x[:, 0], return_counts=True) + self.assertTrue(np.all(x1 == [0, 1, 2, 3, 4, 5])) + x1_counts = x1_counts / np.sum(x1_counts) + self.assertTrue(np.all(np.abs(x1_counts - np.mean(x1_counts)) <= 0.05)) + + x2, x2_counts = np.unique(x[:, 1], return_counts=True) + self.assertTrue(np.all(x2 == [-1, 0, 1])) + x2_counts = x2_counts / np.sum(x2_counts) + self.assertTrue(np.all(np.abs(x2_counts - np.mean(x2_counts)) <= 0.05)) + + x3, x3_counts = np.unique(x[:, 2], return_counts=True) + self.assertTrue(np.all(x3 == [2, 3, 4])) + x3_counts = x3_counts / np.sum(x3_counts) + self.assertTrue(np.all(np.abs(x3_counts - np.mean(x3_counts)) <= 0.05)) + + def test_base_design_space(self): + ds = BaseDesignSpace( + [ + CategoricalVariable(["A", "B"]), + IntegerVariable(0, 3), + FloatVariable(-0.5, 0.5), + ] + ) + self.assertEqual(ds.get_x_limits(), [["A", "B"], (0, 3), (-0.5, 0.5)]) + self.assertTrue(np.all(ds.get_num_bounds() == [[0, 1], [0, 3], [-0.5, 0.5]])) + self.assertTrue( + np.all( + ds.get_unfolded_num_bounds() == [[0, 1], [0, 1], [0, 3], [-0.5, 0.5]] + ) + ) + + x = np.array( + [ + [0, 0, 0], + [1, 2, 0.5], + [0, 3, 0.5], + ] + ) + is_acting = np.array( + [ + [True, True, False], + [True, False, True], + [False, True, True], + ] + ) + + x_unfolded, is_acting_unfolded = ds.unfold_x(x, is_acting) + self.assertTrue( + np.all( + x_unfolded + == [ + [1, 0, 0, 0], + [0, 1, 2, 0.5], + [1, 0, 3, 0.5], + ] + ) + ) + self.assertEqual(is_acting_unfolded.dtype, bool) + np.testing.assert_array_equal( + is_acting_unfolded, + [ + [True, True, True, False], + [True, True, False, True], + [False, False, True, True], + ], + ) + + x_folded, is_acting_folded = ds.fold_x(x_unfolded, is_acting_unfolded) + np.testing.assert_array_equal(x_folded, x) + np.testing.assert_array_equal(is_acting_folded, is_acting) + + x_unfold_mask, is_act_unfold_mask = ds.unfold_x( + x, is_acting, fold_mask=np.array([False] * 3) + ) + np.testing.assert_array_equal(x_unfold_mask, x) + np.testing.assert_array_equal(is_act_unfold_mask, is_acting) + + x_fold_mask, is_act_fold_mask = ds.fold_x( + x, is_acting, fold_mask=np.array([False] * 3) + ) + np.testing.assert_array_equal(x_fold_mask, x) + + np.testing.assert_array_equal(is_act_fold_mask, is_acting) + + def test_create_design_space(self): + DesignSpace([FloatVariable(0, 1)]) + with simulate_no_config_space(): + DesignSpace([FloatVariable(0, 1)]) + + def test_design_space(self): + ds = DesignSpace( + [ + CategoricalVariable(["A", "B", "C"]), + OrdinalVariable(["0", "1"]), + IntegerVariable(-1, 2), + FloatVariable(0.5, 1.5), + ], + random_state=42, + ) + self.assertEqual(len(ds.design_variables), 4) + if HAS_CONFIG_SPACE: + self.assertEqual(len(list(ds._cs.values())), 4) + self.assertTrue(np.all(~ds.is_conditionally_acting)) + if HAS_CONFIG_SPACE: + x, is_acting = ds.sample_valid_x(3, random_state=42) + self.assertEqual(x.shape, (3, 4)) + np.testing.assert_allclose( + x, + np.array( + [ + [1.0, 0.0, -0.0, 0.83370861], + [2.0, 0.0, -1.0, 0.64286682], + [2.0, 0.0, -0.0, 1.15088847], + ] + ), + atol=1e-8, + ) + else: + ds.sample_valid_x(3, random_state=42) + x = np.array( + [ + [1, 0, 0, 0.834], + [2, 0, -1, 0.6434], + [2, 0, 0, 1.151], + ] + ) + x, is_acting = ds.correct_get_acting(x) + + self.assertEqual(x.shape, (3, 4)) + self.assertEqual(is_acting.shape, x.shape) + + self.assertEqual(ds.decode_values(x, i_dv=0), ["B", "C", "C"]) + self.assertEqual(ds.decode_values(x, i_dv=1), ["0", "0", "0"]) + self.assertEqual(ds.decode_values(np.array([0, 1, 2]), i_dv=0), ["A", "B", "C"]) + self.assertEqual(ds.decode_values(np.array([0, 1]), i_dv=1), ["0", "1"]) + + self.assertEqual(ds.decode_values(x[0, :]), ["B", "0", 0, x[0, 3]]) + self.assertEqual(ds.decode_values(x[[0], :]), [["B", "0", 0, x[0, 3]]]) + self.assertEqual( + ds.decode_values(x), + [ + ["B", "0", 0, x[0, 3]], + ["C", "0", -1, x[1, 3]], + ["C", "0", 0, x[2, 3]], + ], + ) + + x_corr, is_act_corr = ds.correct_get_acting(x) + self.assertTrue(np.all(x_corr == x)) + self.assertTrue(np.all(is_act_corr == is_acting)) + + x_sampled_externally = LHS( + xlimits=ds.get_unfolded_num_bounds(), criterion="ese", random_state=42 + )(3) + x_corr, is_acting_corr = ds.correct_get_acting(x_sampled_externally) + x_corr, is_acting_corr = ds.fold_x(x_corr, is_acting_corr) + np.testing.assert_allclose( + x_corr, + np.array( + [ + [2.0, 0.0, -1.0, 1.34158548], + [0.0, 1.0, -0.0, 0.55199817], + [1.0, 1.0, 1.0, 1.15663662], + ] + ), + atol=1e-8, + ) + self.assertTrue(np.all(is_acting_corr)) + + x_unfolded, is_acting_unfolded = ds.sample_valid_x( + 3, unfolded=True, random_state=42 + ) + self.assertEqual(x_unfolded.shape, (3, 6)) + if HAS_CONFIG_SPACE: + np.testing.assert_allclose( + x_unfolded, + np.array( + [ + [1.0, 0.0, 0.0, 0.0, 2.0, 1.11213215], + [0.0, 1.0, 0.0, 1.0, -1.0, 1.09482857], + [1.0, 0.0, 0.0, 1.0, -1.0, 0.75061044], + ] + ), + atol=1e-8, + ) + + self.assertTrue(str(ds)) + self.assertTrue(repr(ds)) + + ds.correct_get_acting(np.array([[0, 0, 0, 1.6]])) + + def test_folding_mask(self): + ds = DesignSpace( + [ + CategoricalVariable(["A", "B", "C"]), + CategoricalVariable(["A", "B", "C"]), + ] + ) + x = np.array([[1, 2]]) + is_act = np.array([[True, False]]) + + self.assertEqual(ds._get_n_dim_unfolded(), 6) + + x_unfolded, is_act_unfolded = ds.unfold_x(x, is_act, np.array([True, False])) + self.assertTrue(np.all(x_unfolded == np.array([[0, 1, 0, 2]]))) + self.assertTrue( + np.all(is_act_unfolded == np.array([[True, True, True, False]])) + ) + + x_folded, is_act_folded = ds.fold_x( + x_unfolded, is_act_unfolded, np.array([True, False]) + ) + self.assertTrue(np.all(x_folded == x)) + self.assertTrue(np.all(is_act_folded == is_act)) + + def test_float_design_space(self): + ds = DesignSpace([(0, 1), (0.5, 2.5), (-0.4, 10)]) + assert ds.n_dv == 3 + assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) + assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) + + ds = DesignSpace([[0, 1], [0.5, 2.5], [-0.4, 10]]) + assert ds.n_dv == 3 + assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) + assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) + + ds = DesignSpace(np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) + assert ds.n_dv == 3 + assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) + assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) + + def test_design_space_hierarchical(self): + ds = DesignSpace( + [ + CategoricalVariable(["A", "B", "C"]), # x0 + CategoricalVariable(["E", "F"]), # x1 + IntegerVariable(0, 1), # x2 + FloatVariable(0.1, 1), # x3 + ], + random_state=42, + ) + ds.declare_decreed_var( + decreed_var=3, meta_var=0, meta_value="A" + ) # Activate x3 if x0 == A + + x_cartesian = np.array( + list(itertools.product([0, 1, 2], [0, 1], [0, 1], [0.25, 0.75])) + ) + self.assertEqual(x_cartesian.shape, (24, 4)) + + self.assertTrue( + np.all(ds.is_conditionally_acting == [False, False, False, True]) + ) + + x, is_acting = ds.correct_get_acting(x_cartesian) + _, is_unique = np.unique(x, axis=0, return_index=True) + self.assertEqual(len(is_unique), 16) + np.testing.assert_allclose( + x[is_unique, :], + np.array( + [ + [0, 0, 0, 0.25], + [0, 0, 0, 0.75], + [0, 0, 1, 0.25], + [0, 0, 1, 0.75], + [0, 1, 0, 0.25], + [0, 1, 0, 0.75], + [0, 1, 1, 0.25], + [0, 1, 1, 0.75], + [1, 0, 0, 0.55], + [1, 0, 1, 0.55], + [1, 1, 0, 0.55], + [1, 1, 1, 0.55], + [2, 0, 0, 0.55], + [2, 0, 1, 0.55], + [2, 1, 0, 0.55], + [2, 1, 1, 0.55], + ] + ), + ) + np.testing.assert_array_equal( + is_acting[is_unique, :], + np.array( + [ + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + ] + ), + ) + + x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) + assert x_sampled.shape == (100, 4) + x_sampled[is_acting_sampled[:, 3], 3] = np.round( + x_sampled[is_acting_sampled[:, 3], 3], 4 + ) + + x_corr, is_acting_corr = ds.correct_get_acting(x_sampled) + self.assertTrue(np.sum(np.abs(x_corr - x_sampled)) < 1e-12) + self.assertTrue(np.all(is_acting_corr == is_acting_sampled)) + + seen_x = set() + seen_is_acting = set() + for i, xi in enumerate(x_sampled): + seen_x.add(tuple(xi)) + seen_is_acting.add(tuple(is_acting_sampled[i, :])) + if HAS_ADSG: + assert len(seen_x) == 49 + else: + assert len(seen_x) == 42 + assert len(seen_is_acting) == 2 + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_design_space_hierarchical_config_space(self): + ds = DesignSpace( + [ + CategoricalVariable(["A", "B", "Cc"]), # x0 + CategoricalVariable(["E", "F"]), # x1 + IntegerVariable(0, 1), # x2 + FloatVariable(0, 1), # x3 + ], + random_state=42, + ) + ds.declare_decreed_var( + decreed_var=3, meta_var=0, meta_value="A" + ) # Activate x3 if x0 == A + ds.add_value_constraint( + var1=0, value1=["Cc"], var2=1, value2="F" + ) # Prevent a == C and b == F + + x_cartesian = np.array( + list(itertools.product([0, 1, 2], [0, 1], [0, 1], [0.25, 0.75])) + ) + self.assertEqual(x_cartesian.shape, (24, 4)) + + self.assertTrue( + np.all(ds.is_conditionally_acting == [False, False, False, True]) + ) + + x, is_acting = ds.correct_get_acting(x_cartesian) + _, is_unique = np.unique(x, axis=0, return_index=True) + self.assertEqual(len(is_unique), 14) + np.testing.assert_array_equal( + x[is_unique, :], + np.array( + [ + [0, 0, 0, 0.25], + [0, 0, 0, 0.75], + [0, 0, 1, 0.25], + [0, 0, 1, 0.75], + [0, 1, 0, 0.25], + [0, 1, 0, 0.75], + [0, 1, 1, 0.25], + [0, 1, 1, 0.75], + [1, 0, 0, 0.5], + [1, 0, 1, 0.5], + [1, 1, 0, 0.5], + [1, 1, 1, 0.5], + [2, 0, 0, 0.5], + [2, 0, 1, 0.5], + ] + ), + ) + np.testing.assert_array_equal( + is_acting[is_unique, :], + np.array( + [ + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + ] + ), + ) + + x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) + assert x_sampled.shape == (100, 4) + x_sampled[is_acting_sampled[:, 3], 3] = np.round( + x_sampled[is_acting_sampled[:, 3], 3] + ) + + x_corr, is_acting_corr = ds.correct_get_acting(x_sampled) + self.assertTrue(np.all(x_corr == x_sampled)) + self.assertTrue(np.all(is_acting_corr == is_acting_sampled)) + + seen_x = set() + seen_is_acting = set() + for i, xi in enumerate(x_sampled): + seen_x.add(tuple(xi)) + seen_is_acting.add(tuple(is_acting_sampled[i, :])) + assert len(seen_x) == 14 + assert len(seen_is_acting) == 2 + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_design_space_continuous(self): + ds = DesignSpace( + [ + FloatVariable(0, 1), # x0 + FloatVariable(0, 1), # x1 + FloatVariable(0, 1), # x2 + ], + random_state=42, + ) + ds.add_value_constraint( + var1=0, value1="<", var2=1, value2=">" + ) # Prevent x0 < x1 + ds.add_value_constraint( + var1=1, value1="<", var2=2, value2=">" + ) # Prevent x1 < x2 + + # correct_get_acting + x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) + self.assertTrue(np.min(x_sampled[:, 0] - x_sampled[:, 1]) > 0) + self.assertTrue(np.min(x_sampled[:, 1] - x_sampled[:, 2]) > 0) + ds = DesignSpace( + [ + IntegerVariable(0, 2), # x0 + FloatVariable(0, 2), # x1 + IntegerVariable(0, 2), # x2 + ], + random_state=42, + ) + ds.add_value_constraint( + var1=0, value1="<", var2=1, value2=">" + ) # Prevent x0 < x1 + ds.add_value_constraint( + var1=1, value1="<", var2=2, value2=">" + ) # Prevent x0 < x1 + + # correct_get_acting + x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) + self.assertTrue(np.min(x_sampled[:, 0] - x_sampled[:, 1]) > 0) + self.assertTrue(np.min(x_sampled[:, 1] - x_sampled[:, 2]) > 0) + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_check_conditionally_acting(self): + class WrongDesignSpace(DesignSpace): + def _is_conditionally_acting(self) -> np.ndarray: + return np.zeros((self.n_dv,), dtype=bool) + + for simulate_no_cs in [True, False]: + with simulate_no_config_space(simulate_no_cs): + ds = WrongDesignSpace( + [ + CategoricalVariable(["A", "B", "C"]), # x0 + CategoricalVariable(["E", "F"]), # x1 + IntegerVariable(0, 1), # x2 + FloatVariable(0, 1), # x3 + ], + random_state=42, + ) + ds.declare_decreed_var( + decreed_var=3, meta_var=0, meta_value="A" + ) # Activate x3 if x0 == A + self.assertRaises( + RuntimeError, lambda: ds.sample_valid_x(10, random_state=42) + ) + + def test_check_conditionally_acting_2(self): + for simulate_no_cs in [True, False]: + with simulate_no_config_space(simulate_no_cs): + ds = DesignSpace( + [ + CategoricalVariable(["A", "B", "C"]), # x0 + CategoricalVariable(["E", "F"]), # x1 + IntegerVariable(0, 1), # x2 + FloatVariable(0, 1), # x3 + ], + random_state=42, + ) + ds.declare_decreed_var( + decreed_var=0, meta_var=1, meta_value="E" + ) # Activate x3 if x0 == A + + ds.sample_valid_x(10, random_state=42) + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_restrictive_value_constraint_ordinal(self): + ds = DesignSpace( + [ + OrdinalVariable(["0", "1", "2"]), + OrdinalVariable(["0", "1", "2"]), + ] + ) + assert list(ds._cs.values())[0].default_value == "0" + + ds.add_value_constraint(var1=0, value1="1", var2=1, value2="1") + ds.sample_valid_x(100, random_state=42) + + x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) + x_cartesian2, _ = ds.correct_get_acting(x_cartesian) + np.testing.assert_array_equal( + np.array( + [[0, 0], [0, 1], [0, 2], [1, 0], [0, 1], [1, 2], [2, 0], [2, 1], [2, 2]] + ), + x_cartesian2, + ) + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_restrictive_value_constraint_integer(self): + ds = DesignSpace( + [ + IntegerVariable(0, 2), + IntegerVariable(0, 2), + ] + ) + assert list(ds._cs.values())[0].default_value == 1 + + ds.add_value_constraint(var1=0, value1=1, var2=1, value2=1) + ds.sample_valid_x(100, random_state=42) + + x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) + ds.correct_get_acting(x_cartesian) + x_cartesian2, _ = ds.correct_get_acting(x_cartesian) + np.testing.assert_array_equal( + np.array( + [[0, 0], [0, 1], [0, 2], [1, 0], [2, 0], [1, 2], [2, 0], [2, 1], [2, 2]] + ), + x_cartesian2, + ) + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_restrictive_value_constraint_categorical(self): + ds = DesignSpace( + [ + CategoricalVariable(["a", "b", "c"]), + CategoricalVariable(["a", "b", "c"]), + ] + ) + assert list(ds._cs.values())[0].default_value == "a" + + ds.add_value_constraint(var1=0, value1="b", var2=1, value2="b") + ds.sample_valid_x(100, random_state=42) + + x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) + ds.correct_get_acting(x_cartesian) + x_cartesian2, _ = ds.correct_get_acting(x_cartesian) + np.testing.assert_array_equal( + np.array( + [[0, 0], [0, 1], [0, 2], [1, 0], [0, 1], [1, 2], [2, 0], [2, 1], [2, 2]] + ), + x_cartesian2, + ) + + @unittest.skipIf( + not (HAS_CONFIG_SPACE and HAS_ADSG), + "Architecture Design Space Graph or ConfigSpace not installed.", + ) + def test_adsg_to_legacy(self): + from adsg_core import BasicADSG, NamedNode, DesignVariableNode + from SMTDesignSpace.design_space import ensure_design_space + from adsg_core import GraphProcessor + + # Create the ADSG + adsg = BasicADSG() + ndv = 13 + # Create nodes + n = [NamedNode(f"N{i}") for i in range(ndv)] + n = [ + NamedNode("MLP"), + NamedNode("Learning_rate"), + NamedNode("Activation_function"), + NamedNode("Optimizer"), + NamedNode("Decay"), + NamedNode("Power_update"), + NamedNode("Average_start"), + NamedNode("Running_Average_1"), + NamedNode("Running_Average_2"), + NamedNode("Numerical_Stability"), + NamedNode("Nb_layers"), + NamedNode("Layer_1"), + NamedNode("Layer_2"), + NamedNode("Layer_3"), # NamedNode("Dropout"), + NamedNode("ASGD"), + NamedNode("Adam"), + NamedNode("20...40"), + NamedNode("40"), + NamedNode("45"), + NamedNode("20...40"), + NamedNode("40"), + NamedNode("45"), + NamedNode("20...40"), + NamedNode("40"), + NamedNode("45"), + ] + adsg.add_node(n[1]) + adsg.add_node(n[2]) + adsg.add_edges( + [ + (n[3], n[10]), + (n[14], n[4]), + (n[14], n[5]), + (n[14], n[6]), + (n[15], n[7]), + (n[15], n[8]), + (n[15], n[9]), + ] + ) + adsg.add_selection_choice("Optimizer_Choice", n[3], [n[14], n[15]]) + adsg.add_selection_choice("#layers", n[10], [n[11], n[12], n[13]]) + a = [] + for i in range(3): + a.append(NamedNode(str(25 + 5 * i))) + b = a.copy() + b.append(n[17]) + b.append(n[18]) + choicel1 = adsg.add_selection_choice("#neurons_1", n[11], b) + adsg.add_edges([(n[12], choicel1), (n[13], choicel1)]) + + a = [] + for i in range(3): + a.append(NamedNode(str(25 + 5 * i))) + b = a.copy() + b.append(n[20]) + b.append(n[21]) + choicel1 = adsg.add_selection_choice("#neurons_2", n[12], b) + adsg.add_edges([(n[13], choicel1)]) + + a = [] + for i in range(3): + a.append(NamedNode(str(25 + 5 * i))) + b = a.copy() + b.append(n[23]) + b.append(n[24]) + choicel1 = adsg.add_selection_choice("#neurons_3", n[13], b) + + adsg.add_incompatibility_constraint([n[15], n[13]]) + adsg.add_incompatibility_constraint([n[14], n[17]]) + adsg.add_incompatibility_constraint([n[14], n[18]]) + adsg.add_incompatibility_constraint([n[14], n[20]]) + adsg.add_incompatibility_constraint([n[14], n[21]]) + adsg.add_incompatibility_constraint([n[14], n[23]]) + adsg.add_incompatibility_constraint([n[14], n[24]]) + start_nodes = set() + start_nodes.add(n[3]) + start_nodes.add(n[2]) + start_nodes.add(n[1]) + adsg.add_edges( + [ + (n[1], DesignVariableNode("x0", bounds=(0, 1))), + (n[4], DesignVariableNode("x1", bounds=(0, 1))), + (n[5], DesignVariableNode("x2", bounds=(0, 1))), + (n[6], DesignVariableNode("x3", bounds=(0, 1))), + (n[7], DesignVariableNode("x4", bounds=(0, 1))), + (n[8], DesignVariableNode("x5", bounds=(0, 1))), + (n[9], DesignVariableNode("x6", bounds=(0, 1))), + ] + ) + adsg.add_selection_choice( + "Activation_Choice", + n[2], + [NamedNode("ReLU"), NamedNode("Sigmoid"), NamedNode("Tanh")], + ) + adsg = adsg.set_start_nodes(start_nodes) + adsg.render() + gp = GraphProcessor(adsg) + gp.get_statistics() + design_space = ensure_design_space(design_space=adsg) + np.testing.assert_array_equal( + np.array( + [ + False, + False, + False, + True, + True, + True, + False, + True, + True, + True, + True, + True, + True, + ] + ), + design_space.is_conditionally_acting, + ) + design_space2 = ArchDesignSpaceGraph(adsg=adsg) + np.testing.assert_array_equal( + np.array( + [ + False, + False, + False, + True, + True, + True, + False, + True, + True, + True, + True, + True, + True, + ] + ), + design_space2.is_conditionally_acting, + ) + + +if __name__ == "__main__": + unittest.main() From 3e15411af8009688f329f3a5a850bc6566028d78 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 17 Sep 2024 22:17:06 +0200 Subject: [PATCH 40/77] ruff' --- smt/utils/design_space.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index ab55222ab..5e3094858 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -9,7 +9,7 @@ from typing import List, Optional, Sequence, Tuple, Union try: - import SMTDesignSpace + from SMTDesignSpace import BaseDesignSpace HAS_SMTDesignSpace = True HAS_CONFIG_SPACE = True From 3b11c09fe14404b8a3efc132df52a47fcbb5c45a Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Wed, 18 Sep 2024 07:49:37 +0200 Subject: [PATCH 41/77] add adsg 1.1.1 --- .github/workflows/tests_coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests_coverage.yml b/.github/workflows/tests_coverage.yml index 71dec8c5f..559d13413 100644 --- a/.github/workflows/tests_coverage.yml +++ b/.github/workflows/tests_coverage.yml @@ -27,7 +27,7 @@ jobs: - name: Install dependencies run: | pip install --upgrade pip - pip install -r requirements.txt numpy==1.26.4 git+https://github.com/SMTorg/smt-design-space + pip install -r requirements.txt numpy==1.26.4 ConfigSpace==0.6.1 adsg-core==1.1.1 git+https://github.com/SMTorg/smt-design-space pip list pip install -e . From 14f6a65ca082844609d634cdf58b3af09ab8c55e Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Thu, 19 Sep 2024 16:15:02 +0200 Subject: [PATCH 42/77] ruff --- smt/utils/design_space.py | 2 +- smt/utils/test/test_design_space.py | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/smt/utils/design_space.py b/smt/utils/design_space.py index 5e3094858..125c03952 100644 --- a/smt/utils/design_space.py +++ b/smt/utils/design_space.py @@ -9,7 +9,7 @@ from typing import List, Optional, Sequence, Tuple, Union try: - from SMTDesignSpace import BaseDesignSpace + from SMTDesignSpace.design_space import BaseDesignSpace HAS_SMTDesignSpace = True HAS_CONFIG_SPACE = True diff --git a/smt/utils/test/test_design_space.py b/smt/utils/test/test_design_space.py index 976454c7e..8fb9ef024 100644 --- a/smt/utils/test/test_design_space.py +++ b/smt/utils/test/test_design_space.py @@ -12,6 +12,7 @@ from smt.utils.design_space import HAS_SMTDesignSpace + if HAS_SMTDesignSpace: from SMTDesignSpace import design_space as ds from SMTDesignSpace.design_space import ( From d9f818869dc8db7bb3d2cd2d54b9e1c8063fc00e Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Thu, 19 Sep 2024 17:01:30 +0200 Subject: [PATCH 43/77] fix --- smt/applications/tests/test_mixed_integer.py | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/smt/applications/tests/test_mixed_integer.py b/smt/applications/tests/test_mixed_integer.py index a90aff565..231f169a1 100644 --- a/smt/applications/tests/test_mixed_integer.py +++ b/smt/applications/tests/test_mixed_integer.py @@ -529,7 +529,12 @@ def run_mixed_integer_qp_example(self): from smt.applications.mixed_integer import MixedIntegerSurrogateModel from smt.surrogate_models import QP - from smt.utils.design_space import DesignSpace, IntegerVariable + from smt.utils.design_space import HAS_SMTDesignSpace + + if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import DesignSpace, IntegerVariable + else: + from smt.utils.design_space import HAS_SMTDesignSpace xt = np.array([0.0, 1.0, 2.0, 3.0, 4.0]) yt = np.array([0.0, 1.0, 1.5, 0.5, 1.0]) From c949d55e38d59ba0f498c9ec21557d193c1c07fb Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Thu, 19 Sep 2024 17:18:05 +0200 Subject: [PATCH 44/77] fix --- smt/applications/tests/test_mixed_integer.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smt/applications/tests/test_mixed_integer.py b/smt/applications/tests/test_mixed_integer.py index 231f169a1..80ba8009e 100644 --- a/smt/applications/tests/test_mixed_integer.py +++ b/smt/applications/tests/test_mixed_integer.py @@ -534,7 +534,7 @@ def run_mixed_integer_qp_example(self): if HAS_SMTDesignSpace: from SMTDesignSpace.design_space import DesignSpace, IntegerVariable else: - from smt.utils.design_space import HAS_SMTDesignSpace + from smt.utils.design_space import DesignSpace, IntegerVariable xt = np.array([0.0, 1.0, 2.0, 3.0, 4.0]) yt = np.array([0.0, 1.0, 1.5, 0.5, 1.0]) From 6c621e8f7859bdb39b6e7c6b63cd3b11e0319d77 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Thu, 19 Sep 2024 17:47:06 +0200 Subject: [PATCH 45/77] add test --- smt/applications/tests/test_mixed_integer.py | 115 +++++++++++++------ 1 file changed, 82 insertions(+), 33 deletions(-) diff --git a/smt/applications/tests/test_mixed_integer.py b/smt/applications/tests/test_mixed_integer.py index 80ba8009e..ed1a8bf3c 100644 --- a/smt/applications/tests/test_mixed_integer.py +++ b/smt/applications/tests/test_mixed_integer.py @@ -783,13 +783,23 @@ def run_mixed_discrete_design_space_example(self): from smt.applications.mixed_integer import MixedIntegerSamplingMethod from smt.sampling_methods import LHS - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) + + if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) + else: + from smt.utils.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) ds = DesignSpace( [ @@ -1147,12 +1157,21 @@ def run_hierarchical_variables_Goldstein(self): ) from smt.sampling_methods import LHS from smt.surrogate_models import KRG, MixHrcKernelType, MixIntKernelType - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - ) + + if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + ) + else: + from smt.utils.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + ) def f_hv(X): import numpy as np @@ -2053,12 +2072,19 @@ def run_mixed_gower_example(self): MixedIntegerKrigingModel, ) from smt.surrogate_models import KRG, MixIntKernelType - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) + if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) + else: + from smt.utils.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) xt1 = np.array([[0, 0.0], [0, 2.0], [0, 4.0]]) xt2 = np.array([[1, 0.0], [1, 2.0], [1, 3.0]]) xt3 = np.array([[2, 1.0], [2, 2.0], [2, 4.0]]) @@ -2184,12 +2210,19 @@ def run_mixed_cs_example(self): MixedIntegerKrigingModel, ) from smt.surrogate_models import KRG, MixIntKernelType - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) + if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) + else: + from smt.utils.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) xt1 = np.array([[0, 0.0], [0, 2.0], [0, 4.0]]) xt2 = np.array([[1, 0.0], [1, 2.0], [1, 3.0]]) xt3 = np.array([[2, 1.0], [2, 2.0], [2, 4.0]]) @@ -2313,11 +2346,19 @@ def run_mixed_homo_gaussian_example(self): from smt.applications.mixed_integer import MixedIntegerKrigingModel from smt.surrogate_models import KRG, MixIntKernelType - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) + + if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) + else: + from smt.utils.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) xt1 = np.array([[0, 0.0], [0, 2.0], [0, 4.0]]) xt2 = np.array([[1, 0.0], [1, 2.0], [1, 3.0]]) @@ -2442,11 +2483,19 @@ def run_mixed_homo_hyp_example(self): from smt.applications.mixed_integer import MixedIntegerKrigingModel from smt.surrogate_models import KRG, MixIntKernelType - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) + + if HAS_SMTDesignSpace: + from SMTDesignSpace.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) + else: + from smt.utils.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) xt1 = np.array([[0, 0.0], [0, 2.0], [0, 4.0]]) xt2 = np.array([[1, 0.0], [1, 2.0], [1, 3.0]]) From 4b386cac1055467b2e20947abcbea9836f7313b6 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 13:34:02 +0200 Subject: [PATCH 46/77] move ds --- smt/design_space/__init__.py | 0 smt/{utils => design_space}/design_space.py | 0 smt/{utils => design_space}/test/test_design_space.py | 0 3 files changed, 0 insertions(+), 0 deletions(-) create mode 100644 smt/design_space/__init__.py rename smt/{utils => design_space}/design_space.py (100%) rename smt/{utils => design_space}/test/test_design_space.py (100%) diff --git a/smt/design_space/__init__.py b/smt/design_space/__init__.py new file mode 100644 index 000000000..e69de29bb diff --git a/smt/utils/design_space.py b/smt/design_space/design_space.py similarity index 100% rename from smt/utils/design_space.py rename to smt/design_space/design_space.py diff --git a/smt/utils/test/test_design_space.py b/smt/design_space/test/test_design_space.py similarity index 100% rename from smt/utils/test/test_design_space.py rename to smt/design_space/test/test_design_space.py From ede2089b33c90bc85cc903d6cff0c8121f68f307 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 14:16:06 +0200 Subject: [PATCH 47/77] change imports --- smt/applications/ego.py | 13 +---- smt/applications/mfk.py | 13 +---- smt/applications/mixed_integer.py | 20 ++----- smt/applications/tests/test_ego.py | 26 ++------- .../tests/test_mfk_mfkpls_mixed.py | 23 +++----- smt/applications/tests/test_mixed_integer.py | 50 ++++++----------- smt/design_space/__init__.py | 55 +++++++++++++++++++ smt/design_space/test/test_design_space.py | 43 +++++---------- smt/problems/hierarchical_goldstein.py | 26 +++------ smt/problems/mixed_cantilever_beam.py | 19 ++----- smt/problems/neural_network.py | 25 +++------ smt/problems/problem.py | 17 ++---- smt/surrogate_models/__init__.py | 25 +++------ smt/surrogate_models/gpx.py | 17 ++---- smt/surrogate_models/krg_based.py | 19 ++----- .../tests/test_surrogate_model_examples.py | 9 ++- smt/tests/test_derivs.py | 13 ++--- smt/tests/test_extrap.py | 14 ++--- smt/tests/test_low_dim.py | 14 ++--- smt/tests/test_output_derivs.py | 14 ++--- smt/tests/test_training_derivs.py | 12 +--- smt/utils/kriging.py | 12 +--- tutorial/Misc/SMT_CoopCompKRG.ipynb | 23 ++++---- 23 files changed, 186 insertions(+), 316 deletions(-) diff --git a/smt/applications/ego.py b/smt/applications/ego.py index 5cc163c40..4e0c9c612 100644 --- a/smt/applications/ego.py +++ b/smt/applications/ego.py @@ -20,18 +20,7 @@ from smt.sampling_methods import LHS from smt.surrogate_models import GEKPLS, GPX, KPLS, KPLSK, KRG, MGP -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - BaseDesignSpace, - DesignSpace, - ) -else: - from smt.utils.design_space import ( - DesignSpace, - BaseDesignSpace, - ) +from smt.design_space import BaseDesignSpace, DesignSpace class Evaluator(object): diff --git a/smt/applications/mfk.py b/smt/applications/mfk.py index d7ee2cb05..db83eca66 100644 --- a/smt/applications/mfk.py +++ b/smt/applications/mfk.py @@ -23,17 +23,10 @@ MixIntKernelType, compute_n_param, ) -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - ensure_design_space, - ) -else: - from smt.utils.design_space import ( - ensure_design_space, - ) +from smt.design_space import ( + ensure_design_space, +) from smt.utils.kriging import ( componentwise_distance, diff --git a/smt/applications/mixed_integer.py b/smt/applications/mixed_integer.py index 7175c0152..bb083e5e0 100644 --- a/smt/applications/mixed_integer.py +++ b/smt/applications/mixed_integer.py @@ -12,20 +12,12 @@ from smt.surrogate_models.krg_based import KrgBased, MixIntKernelType from smt.surrogate_models.surrogate_model import SurrogateModel from smt.utils.checks import ensure_2d_array -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - BaseDesignSpace, - ensure_design_space, - ) -else: - from smt.utils.design_space import ( - CategoricalVariable, - BaseDesignSpace, - ensure_design_space, - ) + +from smt.design_space import ( + BaseDesignSpace, + CategoricalVariable, + ensure_design_space, +) class MixedIntegerSamplingMethod(SamplingMethod): diff --git a/smt/applications/tests/test_ego.py b/smt/applications/tests/test_ego.py index 0bf325c16..fa31dd19a 100644 --- a/smt/applications/tests/test_ego.py +++ b/smt/applications/tests/test_ego.py @@ -11,26 +11,12 @@ import numpy as np -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace import design_space as ds - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) -else: - from smt.utils import design_space as ds - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) +import smt.design_space as ds +from smt.design_space import ( + DesignSpace, + CategoricalVariable, +) + from smt.applications import EGO from smt.applications.ego import Evaluator from smt.applications.mixed_integer import ( diff --git a/smt/applications/tests/test_mfk_mfkpls_mixed.py b/smt/applications/tests/test_mfk_mfkpls_mixed.py index 9a12eac3a..916fc79b2 100644 --- a/smt/applications/tests/test_mfk_mfkpls_mixed.py +++ b/smt/applications/tests/test_mfk_mfkpls_mixed.py @@ -32,22 +32,13 @@ KRG, MixIntKernelType, ) -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - ) -else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - ) + +from smt.design_space import ( + DesignSpace, + CategoricalVariable, + FloatVariable, + IntegerVariable, +) class TestMFKmixed(unittest.TestCase): diff --git a/smt/applications/tests/test_mixed_integer.py b/smt/applications/tests/test_mixed_integer.py index ed1a8bf3c..f8d82f294 100644 --- a/smt/applications/tests/test_mixed_integer.py +++ b/smt/applications/tests/test_mixed_integer.py @@ -17,28 +17,17 @@ except ImportError: NO_MATPLOTLIB = True -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace import design_space as ds - from SMTDesignSpace.design_space import ( - HAS_CONFIG_SPACE, - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) -else: - from smt.utils import design_space as ds - from smt.utils.design_space import ( - HAS_CONFIG_SPACE, - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) +import smt.design_space as ds +from smt.design_space import ( + HAS_SMTDesignSpace, + HAS_CONFIG_SPACE, + DesignSpace, + CategoricalVariable, + FloatVariable, + IntegerVariable, + OrdinalVariable, +) + from smt.applications.mixed_integer import ( MixedIntegerContext, @@ -489,18 +478,11 @@ def run_mixed_integer_lhs_example(self): from smt.applications.mixed_integer import MixedIntegerSamplingMethod from smt.sampling_methods import LHS - if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) - else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) + from smt.design_space import ( + FloatVariable, + DesignSpace, + CategoricalVariable, + ) float_var = FloatVariable(0, 4) cat_var = CategoricalVariable(["blue", "red"]) diff --git a/smt/design_space/__init__.py b/smt/design_space/__init__.py index e69de29bb..a199a711f 100644 --- a/smt/design_space/__init__.py +++ b/smt/design_space/__init__.py @@ -0,0 +1,55 @@ +try: + from SMTDesignSpace.design_space import BaseDesignSpace + + HAS_SMTDesignSpace = True + HAS_CONFIG_SPACE = True + HAS_ADSG = True +except ImportError: + HAS_SMTDesignSpace = False + HAS_CONFIG_SPACE = False + HAS_ADSG = False + + +if HAS_SMTDesignSpace: + from SMTDesignSpace import design_space as ds + from SMTDesignSpace.design_space import ( + HAS_CONFIG_SPACE, + HAS_ADSG, + ArchDesignSpaceGraph, + BaseDesignSpace, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ensure_design_space, + _convert_adsg_to_legacy, + ) + +else: + from smt.utils import design_space as ds + from smt.utils.design_space import ( + HAS_CONFIG_SPACE, + HAS_ADSG, + BaseDesignSpace, + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ensure_design_space, + ) + + +__all__ = [ + "HAS_SMTDesignSpace", + "HAS_CONFIG_SPACE", + "HAS_ADSG", + "BaseDesignSpace", + "DesignSpace", + "FloatVariable", + "IntegerVariable", + "OrdinalVariable", + "CategoricalVariable", + "ensure_design_space", +] diff --git a/smt/design_space/test/test_design_space.py b/smt/design_space/test/test_design_space.py index 8fb9ef024..961a7e0cb 100644 --- a/smt/design_space/test/test_design_space.py +++ b/smt/design_space/test/test_design_space.py @@ -10,35 +10,20 @@ from smt.sampling_methods import LHS -from smt.utils.design_space import HAS_SMTDesignSpace - - -if HAS_SMTDesignSpace: - from SMTDesignSpace import design_space as ds - from SMTDesignSpace.design_space import ( - HAS_CONFIG_SPACE, - HAS_ADSG, - ArchDesignSpaceGraph, - BaseDesignSpace, - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) - -else: - from smt.utils import design_space as ds - from smt.utils.design_space import ( - HAS_CONFIG_SPACE, - HAS_ADSG, - BaseDesignSpace, - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) +import smt.design_space as ds +from smt.design_space import ( + HAS_CONFIG_SPACE, + HAS_ADSG, + BaseDesignSpace, + CategoricalVariable, + FloatVariable, + IntegerVariable, + OrdinalVariable, + DesignSpace, +) + +if ds.HAS_CONFIG_SPACE: + from smt.design_space import ArchDesignSpaceGraph @contextlib.contextmanager diff --git a/smt/problems/hierarchical_goldstein.py b/smt/problems/hierarchical_goldstein.py index c8ada8c94..301cb6055 100644 --- a/smt/problems/hierarchical_goldstein.py +++ b/smt/problems/hierarchical_goldstein.py @@ -10,24 +10,14 @@ import numpy as np from smt.problems.problem import Problem -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) -else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) + +from smt.design_space import ( + OrdinalVariable, + FloatVariable, + IntegerVariable, + DesignSpace, + CategoricalVariable, +) class HierarchicalGoldstein(Problem): diff --git a/smt/problems/mixed_cantilever_beam.py b/smt/problems/mixed_cantilever_beam.py index 9bdd9fa73..1e3ae91f1 100644 --- a/smt/problems/mixed_cantilever_beam.py +++ b/smt/problems/mixed_cantilever_beam.py @@ -10,20 +10,11 @@ import numpy as np from smt.problems.problem import Problem -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) -else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) +from smt.design_space import ( + FloatVariable, + DesignSpace, + CategoricalVariable, +) class MixedCantileverBeam(Problem): diff --git a/smt/problems/neural_network.py b/smt/problems/neural_network.py index cebba9c87..a78323cf2 100644 --- a/smt/problems/neural_network.py +++ b/smt/problems/neural_network.py @@ -11,24 +11,13 @@ import numpy as np from smt.problems.problem import Problem -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) -else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) +from smt.design_space import ( + OrdinalVariable, + FloatVariable, + IntegerVariable, + DesignSpace, + CategoricalVariable, +) class HierarchicalNeuralNetwork(Problem): diff --git a/smt/problems/problem.py b/smt/problems/problem.py index f278a8be0..799413101 100644 --- a/smt/problems/problem.py +++ b/smt/problems/problem.py @@ -11,18 +11,11 @@ import numpy as np from smt.utils.checks import ensure_2d_array -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - BaseDesignSpace, - DesignSpace, - ) -else: - from smt.utils.design_space import ( - DesignSpace, - BaseDesignSpace, - ) + +from smt.design_space import ( + BaseDesignSpace, + DesignSpace, +) from smt.utils.options_dictionary import OptionsDictionary diff --git a/smt/surrogate_models/__init__.py b/smt/surrogate_models/__init__.py index 49b444de9..6f26b6cd4 100644 --- a/smt/surrogate_models/__init__.py +++ b/smt/surrogate_models/__init__.py @@ -10,25 +10,14 @@ from .sgp import SGP from .krg_based import MixIntKernelType -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) -else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) +from smt.design_space import ( + HAS_SMTDesignSpace, + BaseDesignSpace, + DesignSpace, + CategoricalVariable, + ensure_design_space, +) from smt.utils.kriging import MixHrcKernelType __all__ = [ diff --git a/smt/surrogate_models/gpx.py b/smt/surrogate_models/gpx.py index 96ca09733..fc2a1aa85 100644 --- a/smt/surrogate_models/gpx.py +++ b/smt/surrogate_models/gpx.py @@ -1,18 +1,11 @@ import numpy as np from smt.surrogate_models.surrogate_model import SurrogateModel -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - BaseDesignSpace, - ensure_design_space, - ) -else: - from smt.utils.design_space import ( - BaseDesignSpace, - ensure_design_space, - ) + +from smt.design_space import ( + BaseDesignSpace, + ensure_design_space, +) try: import egobox as egx diff --git a/smt/surrogate_models/krg_based.py b/smt/surrogate_models/krg_based.py index bbd96df13..778657775 100644 --- a/smt/surrogate_models/krg_based.py +++ b/smt/surrogate_models/krg_based.py @@ -23,20 +23,11 @@ ActExp, ) from smt.utils.checks import check_support, ensure_2d_array -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - BaseDesignSpace, - ensure_design_space, - ) -else: - from smt.utils.design_space import ( - CategoricalVariable, - BaseDesignSpace, - ensure_design_space, - ) +from smt.design_space import ( + BaseDesignSpace, + CategoricalVariable, + ensure_design_space, +) from smt.utils.kriging import ( MixHrcKernelType, diff --git a/smt/surrogate_models/tests/test_surrogate_model_examples.py b/smt/surrogate_models/tests/test_surrogate_model_examples.py index 2e6862632..90cd49232 100644 --- a/smt/surrogate_models/tests/test_surrogate_model_examples.py +++ b/smt/surrogate_models/tests/test_surrogate_model_examples.py @@ -249,12 +249,11 @@ def test_mixed_int_krg(self): from smt.applications.mixed_integer import MixedIntegerKrigingModel from smt.surrogate_models import KRG - from smt.utils.design_space import HAS_SMTDesignSpace + from smt.design_space import ( + DesignSpace, + IntegerVariable, + ) - if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import DesignSpace, IntegerVariable - else: - from smt.utils.design_space import DesignSpace, IntegerVariable xt = np.array([0.0, 2.0, 3.0]) yt = np.array([0.0, 1.5, 0.9]) diff --git a/smt/tests/test_derivs.py b/smt/tests/test_derivs.py index 47cdc89c1..72a6b9886 100644 --- a/smt/tests/test_derivs.py +++ b/smt/tests/test_derivs.py @@ -13,16 +13,11 @@ from smt.applications import MFK from smt.problems import Sphere from smt.sampling_methods import LHS -from smt.utils.design_space import HAS_SMTDesignSpace -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - DesignSpace, - ) -else: - from smt.utils.design_space import ( - DesignSpace, - ) +from smt.design_space import ( + DesignSpace, +) + from smt.utils.misc import compute_rms_error from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_extrap.py b/smt/tests/test_extrap.py index ecc489e2b..452163b26 100644 --- a/smt/tests/test_extrap.py +++ b/smt/tests/test_extrap.py @@ -11,16 +11,10 @@ from smt.problems import Sphere from smt.sampling_methods import LHS -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - DesignSpace, - ) -else: - from smt.utils.design_space import ( - DesignSpace, - ) + +from smt.design_space import ( + DesignSpace, +) from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_low_dim.py b/smt/tests/test_low_dim.py index 27619faba..6caa9fc65 100644 --- a/smt/tests/test_low_dim.py +++ b/smt/tests/test_low_dim.py @@ -13,16 +13,10 @@ from smt.problems import Sphere, TensorProduct from smt.sampling_methods import LHS from smt.surrogate_models import LS, QP -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - DesignSpace, - ) -else: - from smt.utils.design_space import ( - DesignSpace, - ) + +from smt.design_space import ( + DesignSpace, +) from smt.utils.misc import compute_rms_error from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_output_derivs.py b/smt/tests/test_output_derivs.py index 9591fc75c..f200150cd 100644 --- a/smt/tests/test_output_derivs.py +++ b/smt/tests/test_output_derivs.py @@ -12,16 +12,10 @@ from smt.problems import Sphere from smt.sampling_methods import FullFactorial -from smt.utils.design_space import HAS_SMTDesignSpace - -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - DesignSpace, - ) -else: - from smt.utils.design_space import ( - DesignSpace, - ) + +from smt.design_space import ( + DesignSpace, +) from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/tests/test_training_derivs.py b/smt/tests/test_training_derivs.py index 77448f84a..e47a7a298 100644 --- a/smt/tests/test_training_derivs.py +++ b/smt/tests/test_training_derivs.py @@ -12,16 +12,10 @@ from smt.problems import Sphere, TensorProduct from smt.sampling_methods import FullFactorial -from smt.utils.design_space import HAS_SMTDesignSpace -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - DesignSpace, - ) -else: - from smt.utils.design_space import ( - DesignSpace, - ) +from smt.design_space import ( + DesignSpace, +) from smt.utils.misc import compute_rms_error from smt.utils.silence import Silence from smt.utils.sm_test_case import SMTestCase diff --git a/smt/utils/kriging.py b/smt/utils/kriging.py index 01fd4dc26..3bc7bfbb0 100644 --- a/smt/utils/kriging.py +++ b/smt/utils/kriging.py @@ -12,16 +12,10 @@ from sklearn.cross_decomposition import PLSRegression as pls from sklearn.metrics.pairwise import check_pairwise_arrays -from smt.utils.design_space import HAS_SMTDesignSpace -if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - ) -else: - from smt.utils.design_space import ( - CategoricalVariable, - ) +from smt.design_space import ( + CategoricalVariable, +) USE_NUMBA_JIT = int(os.getenv("USE_NUMBA_JIT", 0)) prange = range diff --git a/tutorial/Misc/SMT_CoopCompKRG.ipynb b/tutorial/Misc/SMT_CoopCompKRG.ipynb index 65d1e3a1c..9c0b22918 100644 --- a/tutorial/Misc/SMT_CoopCompKRG.ipynb +++ b/tutorial/Misc/SMT_CoopCompKRG.ipynb @@ -83,10 +83,10 @@ "yt = prob(xt)\n", "np.random.seed(1)\n", "\n", - "#Chosen point to compare the different models\n", - "xpoint = (-5 + np.array([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]]))/10.\n", + "# Chosen point to compare the different models\n", + "xpoint = (-5 + np.array([[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]])) / 10.0\n", "ypoint = prob(xpoint)\n", - "print('Exact value of the point', ypoint)" + "print(\"Exact value of the point\", ypoint)" ] }, { @@ -192,12 +192,9 @@ " sm1.train(active_coop_comp, comp_var)\n", "\n", "\n", - "\n", "# Prediction as for ordinary Kriging at the chosen point\n", - "print('Value at the chosen point', sm1.predict_values(xpoint))\n", - "print('Variance at the chosen point', sm1.predict_variances(xpoint))\n", - "\n", - "\n" + "print(\"Value at the chosen point\", sm1.predict_values(xpoint))\n", + "print(\"Variance at the chosen point\", sm1.predict_variances(xpoint))" ] }, { @@ -253,8 +250,8 @@ "sm2.train()\n", "\n", "# Prediction for ordinary Kriging\n", - "print('Value at the chosen point', sm2.predict_values(xpoint))\n", - "print('Variance at the chosen point', sm2.predict_variances(xpoint))\n" + "print(\"Value at the chosen point\", sm2.predict_values(xpoint))\n", + "print(\"Variance at the chosen point\", sm2.predict_variances(xpoint))" ] }, { @@ -316,8 +313,8 @@ "print(\"\\n The model automatically choose \" + str(ncomp) + \" components.\")\n", "\n", "## You can predict a 10-dimension point from the 3-dimensional model\n", - "print('Value at the chosen point', sm3.predict_values(xpoint))\n", - "print('Variance at the chosen point', sm3.predict_variances(xpoint))" + "print(\"Value at the chosen point\", sm3.predict_values(xpoint))\n", + "print(\"Variance at the chosen point\", sm3.predict_variances(xpoint))" ] }, { @@ -427,7 +424,7 @@ "source": [ "# Construction of the validation points to plot the different model predictions\n", "ntest = 200\n", - "sampling = LHS(xlimits=prob.xlimits, random_state=41)\n", + "sampling = LHS(xlimits=prob.xlimits, random_state=41)\n", "xtest = sampling(ntest)\n", "ytest = prob(xtest)\n", "\n", From f3cfda81c89834a4614de3d06fad806918daf1f2 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 14:19:24 +0200 Subject: [PATCH 48/77] change imports --- smt/design_space/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smt/design_space/__init__.py b/smt/design_space/__init__.py index a199a711f..f433c7dff 100644 --- a/smt/design_space/__init__.py +++ b/smt/design_space/__init__.py @@ -27,8 +27,8 @@ ) else: - from smt.utils import design_space as ds - from smt.utils.design_space import ( + from smt.design_space import design_space as ds + from smt.design_space.design_space import ( HAS_CONFIG_SPACE, HAS_ADSG, BaseDesignSpace, From 82424158f245737d81273c84d9829acb2c94be42 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 15:23:29 +0200 Subject: [PATCH 49/77] add import --- smt/surrogate_models/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/smt/surrogate_models/__init__.py b/smt/surrogate_models/__init__.py index 6f26b6cd4..f9dc09e88 100644 --- a/smt/surrogate_models/__init__.py +++ b/smt/surrogate_models/__init__.py @@ -16,6 +16,9 @@ BaseDesignSpace, DesignSpace, CategoricalVariable, + FloatVariable, + IntegerVariable, + OrdinalVariable, ensure_design_space, ) from smt.utils.kriging import MixHrcKernelType From d58050df900696e1d45c0f4e7deb4564e0d314d5 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 15:34:10 +0200 Subject: [PATCH 50/77] fix mi test --- smt/applications/tests/test_mixed_integer.py | 172 +++++-------------- 1 file changed, 47 insertions(+), 125 deletions(-) diff --git a/smt/applications/tests/test_mixed_integer.py b/smt/applications/tests/test_mixed_integer.py index f8d82f294..112d290de 100644 --- a/smt/applications/tests/test_mixed_integer.py +++ b/smt/applications/tests/test_mixed_integer.py @@ -19,7 +19,6 @@ import smt.design_space as ds from smt.design_space import ( - HAS_SMTDesignSpace, HAS_CONFIG_SPACE, DesignSpace, CategoricalVariable, @@ -28,7 +27,6 @@ OrdinalVariable, ) - from smt.applications.mixed_integer import ( MixedIntegerContext, MixedIntegerKrigingModel, @@ -477,7 +475,6 @@ def run_mixed_integer_lhs_example(self): from smt.applications.mixed_integer import MixedIntegerSamplingMethod from smt.sampling_methods import LHS - from smt.design_space import ( FloatVariable, DesignSpace, @@ -511,12 +508,7 @@ def run_mixed_integer_qp_example(self): from smt.applications.mixed_integer import MixedIntegerSurrogateModel from smt.surrogate_models import QP - from smt.utils.design_space import HAS_SMTDesignSpace - - if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import DesignSpace, IntegerVariable - else: - from smt.utils.design_space import DesignSpace, IntegerVariable + from smt.design_space import DesignSpace, IntegerVariable xt = np.array([0.0, 1.0, 2.0, 3.0, 4.0]) yt = np.array([0.0, 1.0, 1.5, 0.5, 1.0]) @@ -548,21 +540,12 @@ def run_mixed_integer_context_example(self): from smt.applications.mixed_integer import MixedIntegerContext from smt.surrogate_models import KRG - - if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - ) - else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - ) + from smt.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + ) design_space = DesignSpace( [ @@ -765,23 +748,13 @@ def run_mixed_discrete_design_space_example(self): from smt.applications.mixed_integer import MixedIntegerSamplingMethod from smt.sampling_methods import LHS - - if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) - else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) + from smt.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) ds = DesignSpace( [ @@ -826,25 +799,13 @@ def run_hierarchical_design_space_example(self): ) from smt.sampling_methods import LHS from smt.surrogate_models import KRG, MixHrcKernelType, MixIntKernelType - - if HAS_SMTDesignSpace: - from SMTDesignSpace import design_space as ds - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) - else: - from smt.utils import design_space as ds - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - OrdinalVariable, - ) + from smt.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + OrdinalVariable, + ) ds = DesignSpace( [ @@ -1139,21 +1100,12 @@ def run_hierarchical_variables_Goldstein(self): ) from smt.sampling_methods import LHS from smt.surrogate_models import KRG, MixHrcKernelType, MixIntKernelType - - if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - ) - else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - IntegerVariable, - ) + from smt.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + IntegerVariable, + ) def f_hv(X): import numpy as np @@ -2054,19 +2006,12 @@ def run_mixed_gower_example(self): MixedIntegerKrigingModel, ) from smt.surrogate_models import KRG, MixIntKernelType + from smt.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) - if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) - else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) xt1 = np.array([[0, 0.0], [0, 2.0], [0, 4.0]]) xt2 = np.array([[1, 0.0], [1, 2.0], [1, 3.0]]) xt3 = np.array([[2, 1.0], [2, 2.0], [2, 4.0]]) @@ -2192,19 +2137,12 @@ def run_mixed_cs_example(self): MixedIntegerKrigingModel, ) from smt.surrogate_models import KRG, MixIntKernelType + from smt.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) - if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) - else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) xt1 = np.array([[0, 0.0], [0, 2.0], [0, 4.0]]) xt2 = np.array([[1, 0.0], [1, 2.0], [1, 3.0]]) xt3 = np.array([[2, 1.0], [2, 2.0], [2, 4.0]]) @@ -2328,19 +2266,11 @@ def run_mixed_homo_gaussian_example(self): from smt.applications.mixed_integer import MixedIntegerKrigingModel from smt.surrogate_models import KRG, MixIntKernelType - - if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) - else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) + from smt.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) xt1 = np.array([[0, 0.0], [0, 2.0], [0, 4.0]]) xt2 = np.array([[1, 0.0], [1, 2.0], [1, 3.0]]) @@ -2465,19 +2395,11 @@ def run_mixed_homo_hyp_example(self): from smt.applications.mixed_integer import MixedIntegerKrigingModel from smt.surrogate_models import KRG, MixIntKernelType - - if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) - else: - from smt.utils.design_space import ( - CategoricalVariable, - DesignSpace, - FloatVariable, - ) + from smt.design_space import ( + CategoricalVariable, + DesignSpace, + FloatVariable, + ) xt1 = np.array([[0, 0.0], [0, 2.0], [0, 4.0]]) xt2 = np.array([[1, 0.0], [1, 2.0], [1, 3.0]]) From 5ec3737b30807c181ba901298a58cbeefb11936e Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 15:59:29 +0200 Subject: [PATCH 51/77] ruff --- smt/applications/ego.py | 1 - smt/applications/mfk.py | 6 +----- smt/applications/tests/test_ego.py | 5 ----- .../tests/test_mfk_mfkpls_mixed.py | 1 - smt/design_space/__init__.py | 21 ++++++++++--------- smt/design_space/test/test_design_space.py | 7 +++---- smt/surrogate_models/__init__.py | 3 --- 7 files changed, 15 insertions(+), 29 deletions(-) diff --git a/smt/applications/ego.py b/smt/applications/ego.py index 4e0c9c612..e1cc6e694 100644 --- a/smt/applications/ego.py +++ b/smt/applications/ego.py @@ -19,7 +19,6 @@ ) from smt.sampling_methods import LHS from smt.surrogate_models import GEKPLS, GPX, KPLS, KPLSK, KRG, MGP - from smt.design_space import BaseDesignSpace, DesignSpace diff --git a/smt/applications/mfk.py b/smt/applications/mfk.py index db83eca66..9baba0c39 100644 --- a/smt/applications/mfk.py +++ b/smt/applications/mfk.py @@ -23,11 +23,7 @@ MixIntKernelType, compute_n_param, ) - -from smt.design_space import ( - ensure_design_space, -) - +from smt.design_space import ensure_design_space from smt.utils.kriging import ( componentwise_distance, compute_X_cont, diff --git a/smt/applications/tests/test_ego.py b/smt/applications/tests/test_ego.py index fa31dd19a..d34133d39 100644 --- a/smt/applications/tests/test_ego.py +++ b/smt/applications/tests/test_ego.py @@ -12,11 +12,6 @@ import numpy as np import smt.design_space as ds -from smt.design_space import ( - DesignSpace, - CategoricalVariable, -) - from smt.applications import EGO from smt.applications.ego import Evaluator from smt.applications.mixed_integer import ( diff --git a/smt/applications/tests/test_mfk_mfkpls_mixed.py b/smt/applications/tests/test_mfk_mfkpls_mixed.py index 916fc79b2..bed656d01 100644 --- a/smt/applications/tests/test_mfk_mfkpls_mixed.py +++ b/smt/applications/tests/test_mfk_mfkpls_mixed.py @@ -32,7 +32,6 @@ KRG, MixIntKernelType, ) - from smt.design_space import ( DesignSpace, CategoricalVariable, diff --git a/smt/design_space/__init__.py b/smt/design_space/__init__.py index f433c7dff..00bb51b79 100644 --- a/smt/design_space/__init__.py +++ b/smt/design_space/__init__.py @@ -1,45 +1,46 @@ -try: - from SMTDesignSpace.design_space import BaseDesignSpace - +import importlib +spec = importlib.util.find_spec('SMTDesignSpace') +if spec : HAS_SMTDesignSpace = True HAS_CONFIG_SPACE = True HAS_ADSG = True -except ImportError: +else: HAS_SMTDesignSpace = False HAS_CONFIG_SPACE = False HAS_ADSG = False if HAS_SMTDesignSpace: - from SMTDesignSpace import design_space as ds from SMTDesignSpace.design_space import ( HAS_CONFIG_SPACE, HAS_ADSG, - ArchDesignSpaceGraph, - BaseDesignSpace, CategoricalVariable, DesignSpace, + BaseDesignSpace, FloatVariable, IntegerVariable, OrdinalVariable, ensure_design_space, - _convert_adsg_to_legacy, ) else: - from smt.design_space import design_space as ds from smt.design_space.design_space import ( HAS_CONFIG_SPACE, HAS_ADSG, - BaseDesignSpace, CategoricalVariable, DesignSpace, FloatVariable, IntegerVariable, OrdinalVariable, ensure_design_space, + BaseDesignSpace, ) +if HAS_SMTDesignSpace : + from SMTDesignSpace.design_space import ArchDesignSpaceGraph +else : + class ArchDesignSpaceGraph : + pass __all__ = [ "HAS_SMTDesignSpace", diff --git a/smt/design_space/test/test_design_space.py b/smt/design_space/test/test_design_space.py index 961a7e0cb..c3cb41fdd 100644 --- a/smt/design_space/test/test_design_space.py +++ b/smt/design_space/test/test_design_space.py @@ -14,17 +14,16 @@ from smt.design_space import ( HAS_CONFIG_SPACE, HAS_ADSG, + HAS_SMTDesignSpace, BaseDesignSpace, CategoricalVariable, FloatVariable, IntegerVariable, OrdinalVariable, DesignSpace, + ArchDesignSpaceGraph, ) -if ds.HAS_CONFIG_SPACE: - from smt.design_space import ArchDesignSpaceGraph - @contextlib.contextmanager def simulate_no_config_space(do_simulate=True): @@ -688,7 +687,7 @@ def test_restrictive_value_constraint_categorical(self): ) @unittest.skipIf( - not (HAS_CONFIG_SPACE and HAS_ADSG), + not (HAS_SMTDesignSpace), "Architecture Design Space Graph or ConfigSpace not installed.", ) def test_adsg_to_legacy(self): diff --git a/smt/surrogate_models/__init__.py b/smt/surrogate_models/__init__.py index f9dc09e88..8b774a6e6 100644 --- a/smt/surrogate_models/__init__.py +++ b/smt/surrogate_models/__init__.py @@ -12,14 +12,11 @@ from .krg_based import MixIntKernelType from smt.design_space import ( - HAS_SMTDesignSpace, - BaseDesignSpace, DesignSpace, CategoricalVariable, FloatVariable, IntegerVariable, OrdinalVariable, - ensure_design_space, ) from smt.utils.kriging import MixHrcKernelType From bb1a99e779c32041c0a603ce4496ab124506765c Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 16:02:25 +0200 Subject: [PATCH 52/77] ruff --- smt/design_space/__init__.py | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/smt/design_space/__init__.py b/smt/design_space/__init__.py index 00bb51b79..14ebaf1b5 100644 --- a/smt/design_space/__init__.py +++ b/smt/design_space/__init__.py @@ -1,6 +1,7 @@ import importlib -spec = importlib.util.find_spec('SMTDesignSpace') -if spec : + +spec = importlib.util.find_spec("SMTDesignSpace") +if spec: HAS_SMTDesignSpace = True HAS_CONFIG_SPACE = True HAS_ADSG = True @@ -36,12 +37,14 @@ BaseDesignSpace, ) -if HAS_SMTDesignSpace : +if HAS_SMTDesignSpace: from SMTDesignSpace.design_space import ArchDesignSpaceGraph -else : - class ArchDesignSpaceGraph : +else: + + class ArchDesignSpaceGraph: pass + __all__ = [ "HAS_SMTDesignSpace", "HAS_CONFIG_SPACE", From 5a4f45ba89828f86210755bcb1fdb5b972330c58 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 17:13:08 +0200 Subject: [PATCH 53/77] add tests --- smt/design_space/test/test_design_space.py | 43 +++++++++++++------ .../test/test_design_space_local.py | 18 ++++++++ 2 files changed, 47 insertions(+), 14 deletions(-) create mode 100644 smt/design_space/test/test_design_space_local.py diff --git a/smt/design_space/test/test_design_space.py b/smt/design_space/test/test_design_space.py index c3cb41fdd..cd9ae3e16 100644 --- a/smt/design_space/test/test_design_space.py +++ b/smt/design_space/test/test_design_space.py @@ -9,20 +9,35 @@ import numpy as np from smt.sampling_methods import LHS - -import smt.design_space as ds -from smt.design_space import ( - HAS_CONFIG_SPACE, - HAS_ADSG, - HAS_SMTDesignSpace, - BaseDesignSpace, - CategoricalVariable, - FloatVariable, - IntegerVariable, - OrdinalVariable, - DesignSpace, - ArchDesignSpaceGraph, -) +import os + +if os.getenv("FORCE_RUN_LOCAL"): + HAS_ADSG = False + HAS_SMTDesignSpace = False + HAS_CONFIG_SPACE = False + import smt.design_space.design_space as ds + from smt.design_space.design_space import ( + BaseDesignSpace, + CategoricalVariable, + FloatVariable, + IntegerVariable, + OrdinalVariable, + DesignSpace, + ) +else: + import smt.design_space as ds + from smt.design_space import ( + HAS_CONFIG_SPACE, + HAS_ADSG, + HAS_SMTDesignSpace, + BaseDesignSpace, + CategoricalVariable, + FloatVariable, + IntegerVariable, + OrdinalVariable, + DesignSpace, + ArchDesignSpaceGraph, + ) @contextlib.contextmanager diff --git a/smt/design_space/test/test_design_space_local.py b/smt/design_space/test/test_design_space_local.py new file mode 100644 index 000000000..a88d22835 --- /dev/null +++ b/smt/design_space/test/test_design_space_local.py @@ -0,0 +1,18 @@ +import unittest +import os + +# Load all tests from test_design_space.py +loader = unittest.TestLoader() +suite = loader.discover(start_dir=".", pattern="test_design_space.py") +os.environ["FORCE_RUN_LOCAL"] = "1" + + +class TestDSLocal(unittest.TestCase): + def test_design_variables(self): + # Run the tests + runner = unittest.TextTestRunner() + runner.run(suite) + + +if __name__ == "__main__": + unittest.main() From d8d0e6ec418ec9733f7c4ca2a31bc87786aeff3e Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 17:55:18 +0200 Subject: [PATCH 54/77] try to fix --- smt/design_space/test/test_design_space_local.py | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/smt/design_space/test/test_design_space_local.py b/smt/design_space/test/test_design_space_local.py index a88d22835..83b73b9b2 100644 --- a/smt/design_space/test/test_design_space_local.py +++ b/smt/design_space/test/test_design_space_local.py @@ -1,14 +1,15 @@ import unittest import os -# Load all tests from test_design_space.py -loader = unittest.TestLoader() -suite = loader.discover(start_dir=".", pattern="test_design_space.py") os.environ["FORCE_RUN_LOCAL"] = "1" class TestDSLocal(unittest.TestCase): def test_design_variables(self): + os.environ["FORCE_RUN_LOCAL"] = "1" + # Load all tests from test_design_space.py + loader = unittest.TestLoader() + suite = loader.discover(start_dir=".", pattern="test_design_space.py") # Run the tests runner = unittest.TextTestRunner() runner.run(suite) From db0365485078fac478b22ef88f82a1a07eaef985 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 17:58:14 +0200 Subject: [PATCH 55/77] try to fix --- smt/design_space/design_space.py | 12 ++---------- 1 file changed, 2 insertions(+), 10 deletions(-) diff --git a/smt/design_space/design_space.py b/smt/design_space/design_space.py index 125c03952..ee69ecc7a 100644 --- a/smt/design_space/design_space.py +++ b/smt/design_space/design_space.py @@ -8,17 +8,9 @@ from smt.sampling_methods.lhs import LHS from typing import List, Optional, Sequence, Tuple, Union -try: - from SMTDesignSpace.design_space import BaseDesignSpace - - HAS_SMTDesignSpace = True - HAS_CONFIG_SPACE = True - HAS_ADSG = True -except ImportError: - HAS_SMTDesignSpace = False - HAS_CONFIG_SPACE = False - HAS_ADSG = False +from smt.design_space import BaseDesignSpace,HAS_SMTDesignSpace,HAS_CONFIG_SPACE, HAS_ADSG + class Configuration: pass From 096e276f43f38c24562580f163b464549bcc01fa Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 17:59:21 +0200 Subject: [PATCH 56/77] try to fix --- smt/design_space/design_space.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/smt/design_space/design_space.py b/smt/design_space/design_space.py index ee69ecc7a..bde5555d0 100644 --- a/smt/design_space/design_space.py +++ b/smt/design_space/design_space.py @@ -7,10 +7,7 @@ import numpy as np from smt.sampling_methods.lhs import LHS from typing import List, Optional, Sequence, Tuple, Union - -from smt.design_space import BaseDesignSpace,HAS_SMTDesignSpace,HAS_CONFIG_SPACE, HAS_ADSG - - + class Configuration: pass From 3c61802e322d719712899cf48e5fe82517f6c811 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 18:02:38 +0200 Subject: [PATCH 57/77] fix import --- smt/design_space/__init__.py | 4 ---- smt/design_space/design_space.py | 2 +- 2 files changed, 1 insertion(+), 5 deletions(-) diff --git a/smt/design_space/__init__.py b/smt/design_space/__init__.py index 14ebaf1b5..e59c1503c 100644 --- a/smt/design_space/__init__.py +++ b/smt/design_space/__init__.py @@ -13,8 +13,6 @@ if HAS_SMTDesignSpace: from SMTDesignSpace.design_space import ( - HAS_CONFIG_SPACE, - HAS_ADSG, CategoricalVariable, DesignSpace, BaseDesignSpace, @@ -26,8 +24,6 @@ else: from smt.design_space.design_space import ( - HAS_CONFIG_SPACE, - HAS_ADSG, CategoricalVariable, DesignSpace, FloatVariable, diff --git a/smt/design_space/design_space.py b/smt/design_space/design_space.py index bde5555d0..8a07acca1 100644 --- a/smt/design_space/design_space.py +++ b/smt/design_space/design_space.py @@ -7,7 +7,7 @@ import numpy as np from smt.sampling_methods.lhs import LHS from typing import List, Optional, Sequence, Tuple, Union - + class Configuration: pass From 5d1cb5b472ada55651914f1ab5b9737a29014f41 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 18:23:27 +0200 Subject: [PATCH 58/77] update test --- smt/design_space/design_space.py | 23 +++++++++++++++++++ .../test/test_design_space_local.py | 3 ++- 2 files changed, 25 insertions(+), 1 deletion(-) diff --git a/smt/design_space/design_space.py b/smt/design_space/design_space.py index 8a07acca1..3a2648416 100644 --- a/smt/design_space/design_space.py +++ b/smt/design_space/design_space.py @@ -4,6 +4,29 @@ This package is distributed under New BSD license. """ +import importlib + +spec = importlib.util.find_spec("SMTDesignSpace") +if spec: + HAS_SMTDesignSpace = True + HAS_CONFIG_SPACE = True + HAS_ADSG = True +else: + HAS_SMTDesignSpace = False + HAS_CONFIG_SPACE = False + HAS_ADSG = False +spec = importlib.util.find_spec("adsg-core") +if spec: + HAS_ADSG = True +else: + HAS_ADSG = False +spec = importlib.util.find_spec("configspace") +if spec: + HAS_CONFIG_SPACE = True +else: + HAS_CONFIG_SPACE = False + + import numpy as np from smt.sampling_methods.lhs import LHS from typing import List, Optional, Sequence, Tuple, Union diff --git a/smt/design_space/test/test_design_space_local.py b/smt/design_space/test/test_design_space_local.py index 83b73b9b2..f69e186ea 100644 --- a/smt/design_space/test/test_design_space_local.py +++ b/smt/design_space/test/test_design_space_local.py @@ -2,9 +2,10 @@ import os os.environ["FORCE_RUN_LOCAL"] = "1" +from test_design_space import Test # Import the existing test class -class TestDSLocal(unittest.TestCase): +class TestDSLocal(Test): def test_design_variables(self): os.environ["FORCE_RUN_LOCAL"] = "1" # Load all tests from test_design_space.py From 5b0b5bee908423dd53b66dd7380254a02e73171d Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 18:26:28 +0200 Subject: [PATCH 59/77] update test --- smt/design_space/design_space.py | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/smt/design_space/design_space.py b/smt/design_space/design_space.py index 3a2648416..d7ea25ced 100644 --- a/smt/design_space/design_space.py +++ b/smt/design_space/design_space.py @@ -5,6 +5,9 @@ """ import importlib +import numpy as np +from smt.sampling_methods.lhs import LHS +from typing import List, Optional, Sequence, Tuple, Union spec = importlib.util.find_spec("SMTDesignSpace") if spec: @@ -27,11 +30,6 @@ HAS_CONFIG_SPACE = False -import numpy as np -from smt.sampling_methods.lhs import LHS -from typing import List, Optional, Sequence, Tuple, Union - - class Configuration: pass From aadb8299d42d7fc4a9fb08cf1c0569fcd669cf61 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 19:09:47 +0200 Subject: [PATCH 60/77] fix files --- .coveragerc | 5 ++++- smt/design_space/test/test_design_space.py | 22 +++++++++---------- .../test/test_design_space_local.py | 1 + 3 files changed, 16 insertions(+), 12 deletions(-) diff --git a/.coveragerc b/.coveragerc index ae1312cf6..b53ea88bf 100644 --- a/.coveragerc +++ b/.coveragerc @@ -11,4 +11,7 @@ omit = */tests/* */examples/* */__init__.py - */setup.py \ No newline at end of file + */setup.py + +[report] +show_missing = True \ No newline at end of file diff --git a/smt/design_space/test/test_design_space.py b/smt/design_space/test/test_design_space.py index cd9ae3e16..a325d5123 100644 --- a/smt/design_space/test/test_design_space.py +++ b/smt/design_space/test/test_design_space.py @@ -12,31 +12,31 @@ import os if os.getenv("FORCE_RUN_LOCAL"): - HAS_ADSG = False - HAS_SMTDesignSpace = False - HAS_CONFIG_SPACE = False - import smt.design_space.design_space as ds - from smt.design_space.design_space import ( + import smt.design_space as ds + from smt.design_space import ( + HAS_CONFIG_SPACE, + HAS_ADSG, + HAS_SMTDesignSpace, BaseDesignSpace, CategoricalVariable, FloatVariable, IntegerVariable, OrdinalVariable, DesignSpace, + ArchDesignSpaceGraph, ) else: - import smt.design_space as ds - from smt.design_space import ( - HAS_CONFIG_SPACE, - HAS_ADSG, - HAS_SMTDesignSpace, + HAS_ADSG = False + HAS_SMTDesignSpace = False + HAS_CONFIG_SPACE = False + import smt.design_space.design_space as ds + from smt.design_space.design_space import ( BaseDesignSpace, CategoricalVariable, FloatVariable, IntegerVariable, OrdinalVariable, DesignSpace, - ArchDesignSpaceGraph, ) diff --git a/smt/design_space/test/test_design_space_local.py b/smt/design_space/test/test_design_space_local.py index f69e186ea..0a8173cac 100644 --- a/smt/design_space/test/test_design_space_local.py +++ b/smt/design_space/test/test_design_space_local.py @@ -14,6 +14,7 @@ def test_design_variables(self): # Run the tests runner = unittest.TextTestRunner() runner.run(suite) + del os.environ["FORCE_RUN_LOCAL"] if __name__ == "__main__": From 686d1348a97461b9da128862ac3fc7eac5c3f74a Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 20:51:23 +0200 Subject: [PATCH 61/77] test to tests --- smt/design_space/test/test_design_space.py | 862 ------------------ .../test/test_design_space_local.py | 21 - 2 files changed, 883 deletions(-) delete mode 100644 smt/design_space/test/test_design_space.py delete mode 100644 smt/design_space/test/test_design_space_local.py diff --git a/smt/design_space/test/test_design_space.py b/smt/design_space/test/test_design_space.py deleted file mode 100644 index a325d5123..000000000 --- a/smt/design_space/test/test_design_space.py +++ /dev/null @@ -1,862 +0,0 @@ -""" -Author: Jasper Bussemaker -""" - -import contextlib -import itertools -import unittest - -import numpy as np - -from smt.sampling_methods import LHS -import os - -if os.getenv("FORCE_RUN_LOCAL"): - import smt.design_space as ds - from smt.design_space import ( - HAS_CONFIG_SPACE, - HAS_ADSG, - HAS_SMTDesignSpace, - BaseDesignSpace, - CategoricalVariable, - FloatVariable, - IntegerVariable, - OrdinalVariable, - DesignSpace, - ArchDesignSpaceGraph, - ) -else: - HAS_ADSG = False - HAS_SMTDesignSpace = False - HAS_CONFIG_SPACE = False - import smt.design_space.design_space as ds - from smt.design_space.design_space import ( - BaseDesignSpace, - CategoricalVariable, - FloatVariable, - IntegerVariable, - OrdinalVariable, - DesignSpace, - ) - - -@contextlib.contextmanager -def simulate_no_config_space(do_simulate=True): - if ds.HAS_CONFIG_SPACE and do_simulate: - ds.HAS_CONFIG_SPACE = False - yield - ds.HAS_CONFIG_SPACE = True - else: - yield - - -class Test(unittest.TestCase): - def test_design_variables(self): - with self.assertRaises(ValueError): - FloatVariable(1, 0) - - float_var = FloatVariable(0, 1) - self.assertEqual(float_var.lower, 0) - self.assertEqual(float_var.upper, 1) - self.assertEqual(float_var.get_limits(), (0, 1)) - self.assertTrue(str(float_var)) - self.assertTrue(repr(float_var)) - self.assertEqual("FloatVariable", float_var.get_typename()) - - with self.assertRaises(ValueError): - IntegerVariable(1, 0) - - int_var = IntegerVariable(0, 1) - self.assertEqual(int_var.lower, 0) - self.assertEqual(int_var.upper, 1) - self.assertEqual(int_var.get_limits(), (0, 1)) - self.assertTrue(str(int_var)) - self.assertTrue(repr(int_var)) - self.assertEqual("IntegerVariable", int_var.get_typename()) - - with self.assertRaises(ValueError): - OrdinalVariable([]) - with self.assertRaises(ValueError): - OrdinalVariable(["1"]) - - ord_var = OrdinalVariable(["A", "B", "C"]) - self.assertEqual(ord_var.values, ["A", "B", "C"]) - self.assertEqual(ord_var.get_limits(), ["0", "1", "2"]) - self.assertEqual(ord_var.lower, 0) - self.assertEqual(ord_var.upper, 2) - self.assertTrue(str(ord_var)) - self.assertTrue(repr(ord_var)) - self.assertEqual("OrdinalVariable", ord_var.get_typename()) - - with self.assertRaises(ValueError): - CategoricalVariable([]) - with self.assertRaises(ValueError): - CategoricalVariable(["A"]) - - cat_var = CategoricalVariable(["A", "B", "C"]) - self.assertEqual(cat_var.values, ["A", "B", "C"]) - self.assertEqual(cat_var.get_limits(), ["A", "B", "C"]) - self.assertEqual(cat_var.lower, 0) - self.assertEqual(cat_var.upper, 2) - self.assertTrue(str(cat_var)) - self.assertTrue(repr(cat_var)) - self.assertEqual("CategoricalVariable", cat_var.get_typename()) - - def test_rounding(self): - ds = BaseDesignSpace( - [ - IntegerVariable(0, 5), - IntegerVariable(-1, 1), - IntegerVariable(2, 4), - ] - ) - - x = np.array( - list( - itertools.product( - np.linspace(0, 5, 20), np.linspace(-1, 1, 20), np.linspace(2, 4, 20) - ) - ) - ) - for i, dv in enumerate(ds.design_variables): - self.assertIsInstance(dv, IntegerVariable) - x[:, i] = ds._round_equally_distributed(x[:, i], dv.lower, dv.upper) - - x1, x1_counts = np.unique(x[:, 0], return_counts=True) - self.assertTrue(np.all(x1 == [0, 1, 2, 3, 4, 5])) - x1_counts = x1_counts / np.sum(x1_counts) - self.assertTrue(np.all(np.abs(x1_counts - np.mean(x1_counts)) <= 0.05)) - - x2, x2_counts = np.unique(x[:, 1], return_counts=True) - self.assertTrue(np.all(x2 == [-1, 0, 1])) - x2_counts = x2_counts / np.sum(x2_counts) - self.assertTrue(np.all(np.abs(x2_counts - np.mean(x2_counts)) <= 0.05)) - - x3, x3_counts = np.unique(x[:, 2], return_counts=True) - self.assertTrue(np.all(x3 == [2, 3, 4])) - x3_counts = x3_counts / np.sum(x3_counts) - self.assertTrue(np.all(np.abs(x3_counts - np.mean(x3_counts)) <= 0.05)) - - def test_base_design_space(self): - ds = BaseDesignSpace( - [ - CategoricalVariable(["A", "B"]), - IntegerVariable(0, 3), - FloatVariable(-0.5, 0.5), - ] - ) - self.assertEqual(ds.get_x_limits(), [["A", "B"], (0, 3), (-0.5, 0.5)]) - self.assertTrue(np.all(ds.get_num_bounds() == [[0, 1], [0, 3], [-0.5, 0.5]])) - self.assertTrue( - np.all( - ds.get_unfolded_num_bounds() == [[0, 1], [0, 1], [0, 3], [-0.5, 0.5]] - ) - ) - - x = np.array( - [ - [0, 0, 0], - [1, 2, 0.5], - [0, 3, 0.5], - ] - ) - is_acting = np.array( - [ - [True, True, False], - [True, False, True], - [False, True, True], - ] - ) - - x_unfolded, is_acting_unfolded = ds.unfold_x(x, is_acting) - self.assertTrue( - np.all( - x_unfolded - == [ - [1, 0, 0, 0], - [0, 1, 2, 0.5], - [1, 0, 3, 0.5], - ] - ) - ) - self.assertEqual(is_acting_unfolded.dtype, bool) - np.testing.assert_array_equal( - is_acting_unfolded, - [ - [True, True, True, False], - [True, True, False, True], - [False, False, True, True], - ], - ) - - x_folded, is_acting_folded = ds.fold_x(x_unfolded, is_acting_unfolded) - np.testing.assert_array_equal(x_folded, x) - np.testing.assert_array_equal(is_acting_folded, is_acting) - - x_unfold_mask, is_act_unfold_mask = ds.unfold_x( - x, is_acting, fold_mask=np.array([False] * 3) - ) - np.testing.assert_array_equal(x_unfold_mask, x) - np.testing.assert_array_equal(is_act_unfold_mask, is_acting) - - x_fold_mask, is_act_fold_mask = ds.fold_x( - x, is_acting, fold_mask=np.array([False] * 3) - ) - np.testing.assert_array_equal(x_fold_mask, x) - - np.testing.assert_array_equal(is_act_fold_mask, is_acting) - - def test_create_design_space(self): - DesignSpace([FloatVariable(0, 1)]) - with simulate_no_config_space(): - DesignSpace([FloatVariable(0, 1)]) - - def test_design_space(self): - ds = DesignSpace( - [ - CategoricalVariable(["A", "B", "C"]), - OrdinalVariable(["0", "1"]), - IntegerVariable(-1, 2), - FloatVariable(0.5, 1.5), - ], - random_state=42, - ) - self.assertEqual(len(ds.design_variables), 4) - if HAS_CONFIG_SPACE: - self.assertEqual(len(list(ds._cs.values())), 4) - self.assertTrue(np.all(~ds.is_conditionally_acting)) - if HAS_CONFIG_SPACE: - x, is_acting = ds.sample_valid_x(3, random_state=42) - self.assertEqual(x.shape, (3, 4)) - np.testing.assert_allclose( - x, - np.array( - [ - [1.0, 0.0, -0.0, 0.83370861], - [2.0, 0.0, -1.0, 0.64286682], - [2.0, 0.0, -0.0, 1.15088847], - ] - ), - atol=1e-8, - ) - else: - ds.sample_valid_x(3, random_state=42) - x = np.array( - [ - [1, 0, 0, 0.834], - [2, 0, -1, 0.6434], - [2, 0, 0, 1.151], - ] - ) - x, is_acting = ds.correct_get_acting(x) - - self.assertEqual(x.shape, (3, 4)) - self.assertEqual(is_acting.shape, x.shape) - - self.assertEqual(ds.decode_values(x, i_dv=0), ["B", "C", "C"]) - self.assertEqual(ds.decode_values(x, i_dv=1), ["0", "0", "0"]) - self.assertEqual(ds.decode_values(np.array([0, 1, 2]), i_dv=0), ["A", "B", "C"]) - self.assertEqual(ds.decode_values(np.array([0, 1]), i_dv=1), ["0", "1"]) - - self.assertEqual(ds.decode_values(x[0, :]), ["B", "0", 0, x[0, 3]]) - self.assertEqual(ds.decode_values(x[[0], :]), [["B", "0", 0, x[0, 3]]]) - self.assertEqual( - ds.decode_values(x), - [ - ["B", "0", 0, x[0, 3]], - ["C", "0", -1, x[1, 3]], - ["C", "0", 0, x[2, 3]], - ], - ) - - x_corr, is_act_corr = ds.correct_get_acting(x) - self.assertTrue(np.all(x_corr == x)) - self.assertTrue(np.all(is_act_corr == is_acting)) - - x_sampled_externally = LHS( - xlimits=ds.get_unfolded_num_bounds(), criterion="ese", random_state=42 - )(3) - x_corr, is_acting_corr = ds.correct_get_acting(x_sampled_externally) - x_corr, is_acting_corr = ds.fold_x(x_corr, is_acting_corr) - np.testing.assert_allclose( - x_corr, - np.array( - [ - [2.0, 0.0, -1.0, 1.34158548], - [0.0, 1.0, -0.0, 0.55199817], - [1.0, 1.0, 1.0, 1.15663662], - ] - ), - atol=1e-8, - ) - self.assertTrue(np.all(is_acting_corr)) - - x_unfolded, is_acting_unfolded = ds.sample_valid_x( - 3, unfolded=True, random_state=42 - ) - self.assertEqual(x_unfolded.shape, (3, 6)) - if HAS_CONFIG_SPACE: - np.testing.assert_allclose( - x_unfolded, - np.array( - [ - [1.0, 0.0, 0.0, 0.0, 2.0, 1.11213215], - [0.0, 1.0, 0.0, 1.0, -1.0, 1.09482857], - [1.0, 0.0, 0.0, 1.0, -1.0, 0.75061044], - ] - ), - atol=1e-8, - ) - - self.assertTrue(str(ds)) - self.assertTrue(repr(ds)) - - ds.correct_get_acting(np.array([[0, 0, 0, 1.6]])) - - def test_folding_mask(self): - ds = DesignSpace( - [ - CategoricalVariable(["A", "B", "C"]), - CategoricalVariable(["A", "B", "C"]), - ] - ) - x = np.array([[1, 2]]) - is_act = np.array([[True, False]]) - - self.assertEqual(ds._get_n_dim_unfolded(), 6) - - x_unfolded, is_act_unfolded = ds.unfold_x(x, is_act, np.array([True, False])) - self.assertTrue(np.all(x_unfolded == np.array([[0, 1, 0, 2]]))) - self.assertTrue( - np.all(is_act_unfolded == np.array([[True, True, True, False]])) - ) - - x_folded, is_act_folded = ds.fold_x( - x_unfolded, is_act_unfolded, np.array([True, False]) - ) - self.assertTrue(np.all(x_folded == x)) - self.assertTrue(np.all(is_act_folded == is_act)) - - def test_float_design_space(self): - ds = DesignSpace([(0, 1), (0.5, 2.5), (-0.4, 10)]) - assert ds.n_dv == 3 - assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) - assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) - - ds = DesignSpace([[0, 1], [0.5, 2.5], [-0.4, 10]]) - assert ds.n_dv == 3 - assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) - assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) - - ds = DesignSpace(np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) - assert ds.n_dv == 3 - assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) - assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) - - def test_design_space_hierarchical(self): - ds = DesignSpace( - [ - CategoricalVariable(["A", "B", "C"]), # x0 - CategoricalVariable(["E", "F"]), # x1 - IntegerVariable(0, 1), # x2 - FloatVariable(0.1, 1), # x3 - ], - random_state=42, - ) - ds.declare_decreed_var( - decreed_var=3, meta_var=0, meta_value="A" - ) # Activate x3 if x0 == A - - x_cartesian = np.array( - list(itertools.product([0, 1, 2], [0, 1], [0, 1], [0.25, 0.75])) - ) - self.assertEqual(x_cartesian.shape, (24, 4)) - - self.assertTrue( - np.all(ds.is_conditionally_acting == [False, False, False, True]) - ) - - x, is_acting = ds.correct_get_acting(x_cartesian) - _, is_unique = np.unique(x, axis=0, return_index=True) - self.assertEqual(len(is_unique), 16) - np.testing.assert_allclose( - x[is_unique, :], - np.array( - [ - [0, 0, 0, 0.25], - [0, 0, 0, 0.75], - [0, 0, 1, 0.25], - [0, 0, 1, 0.75], - [0, 1, 0, 0.25], - [0, 1, 0, 0.75], - [0, 1, 1, 0.25], - [0, 1, 1, 0.75], - [1, 0, 0, 0.55], - [1, 0, 1, 0.55], - [1, 1, 0, 0.55], - [1, 1, 1, 0.55], - [2, 0, 0, 0.55], - [2, 0, 1, 0.55], - [2, 1, 0, 0.55], - [2, 1, 1, 0.55], - ] - ), - ) - np.testing.assert_array_equal( - is_acting[is_unique, :], - np.array( - [ - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - ] - ), - ) - - x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) - assert x_sampled.shape == (100, 4) - x_sampled[is_acting_sampled[:, 3], 3] = np.round( - x_sampled[is_acting_sampled[:, 3], 3], 4 - ) - - x_corr, is_acting_corr = ds.correct_get_acting(x_sampled) - self.assertTrue(np.sum(np.abs(x_corr - x_sampled)) < 1e-12) - self.assertTrue(np.all(is_acting_corr == is_acting_sampled)) - - seen_x = set() - seen_is_acting = set() - for i, xi in enumerate(x_sampled): - seen_x.add(tuple(xi)) - seen_is_acting.add(tuple(is_acting_sampled[i, :])) - if HAS_ADSG: - assert len(seen_x) == 49 - else: - assert len(seen_x) == 42 - assert len(seen_is_acting) == 2 - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_design_space_hierarchical_config_space(self): - ds = DesignSpace( - [ - CategoricalVariable(["A", "B", "Cc"]), # x0 - CategoricalVariable(["E", "F"]), # x1 - IntegerVariable(0, 1), # x2 - FloatVariable(0, 1), # x3 - ], - random_state=42, - ) - ds.declare_decreed_var( - decreed_var=3, meta_var=0, meta_value="A" - ) # Activate x3 if x0 == A - ds.add_value_constraint( - var1=0, value1=["Cc"], var2=1, value2="F" - ) # Prevent a == C and b == F - - x_cartesian = np.array( - list(itertools.product([0, 1, 2], [0, 1], [0, 1], [0.25, 0.75])) - ) - self.assertEqual(x_cartesian.shape, (24, 4)) - - self.assertTrue( - np.all(ds.is_conditionally_acting == [False, False, False, True]) - ) - - x, is_acting = ds.correct_get_acting(x_cartesian) - _, is_unique = np.unique(x, axis=0, return_index=True) - self.assertEqual(len(is_unique), 14) - np.testing.assert_array_equal( - x[is_unique, :], - np.array( - [ - [0, 0, 0, 0.25], - [0, 0, 0, 0.75], - [0, 0, 1, 0.25], - [0, 0, 1, 0.75], - [0, 1, 0, 0.25], - [0, 1, 0, 0.75], - [0, 1, 1, 0.25], - [0, 1, 1, 0.75], - [1, 0, 0, 0.5], - [1, 0, 1, 0.5], - [1, 1, 0, 0.5], - [1, 1, 1, 0.5], - [2, 0, 0, 0.5], - [2, 0, 1, 0.5], - ] - ), - ) - np.testing.assert_array_equal( - is_acting[is_unique, :], - np.array( - [ - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, True], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - [True, True, True, False], - ] - ), - ) - - x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) - assert x_sampled.shape == (100, 4) - x_sampled[is_acting_sampled[:, 3], 3] = np.round( - x_sampled[is_acting_sampled[:, 3], 3] - ) - - x_corr, is_acting_corr = ds.correct_get_acting(x_sampled) - self.assertTrue(np.all(x_corr == x_sampled)) - self.assertTrue(np.all(is_acting_corr == is_acting_sampled)) - - seen_x = set() - seen_is_acting = set() - for i, xi in enumerate(x_sampled): - seen_x.add(tuple(xi)) - seen_is_acting.add(tuple(is_acting_sampled[i, :])) - assert len(seen_x) == 14 - assert len(seen_is_acting) == 2 - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_design_space_continuous(self): - ds = DesignSpace( - [ - FloatVariable(0, 1), # x0 - FloatVariable(0, 1), # x1 - FloatVariable(0, 1), # x2 - ], - random_state=42, - ) - ds.add_value_constraint( - var1=0, value1="<", var2=1, value2=">" - ) # Prevent x0 < x1 - ds.add_value_constraint( - var1=1, value1="<", var2=2, value2=">" - ) # Prevent x1 < x2 - - # correct_get_acting - x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) - self.assertTrue(np.min(x_sampled[:, 0] - x_sampled[:, 1]) > 0) - self.assertTrue(np.min(x_sampled[:, 1] - x_sampled[:, 2]) > 0) - ds = DesignSpace( - [ - IntegerVariable(0, 2), # x0 - FloatVariable(0, 2), # x1 - IntegerVariable(0, 2), # x2 - ], - random_state=42, - ) - ds.add_value_constraint( - var1=0, value1="<", var2=1, value2=">" - ) # Prevent x0 < x1 - ds.add_value_constraint( - var1=1, value1="<", var2=2, value2=">" - ) # Prevent x0 < x1 - - # correct_get_acting - x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) - self.assertTrue(np.min(x_sampled[:, 0] - x_sampled[:, 1]) > 0) - self.assertTrue(np.min(x_sampled[:, 1] - x_sampled[:, 2]) > 0) - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_check_conditionally_acting(self): - class WrongDesignSpace(DesignSpace): - def _is_conditionally_acting(self) -> np.ndarray: - return np.zeros((self.n_dv,), dtype=bool) - - for simulate_no_cs in [True, False]: - with simulate_no_config_space(simulate_no_cs): - ds = WrongDesignSpace( - [ - CategoricalVariable(["A", "B", "C"]), # x0 - CategoricalVariable(["E", "F"]), # x1 - IntegerVariable(0, 1), # x2 - FloatVariable(0, 1), # x3 - ], - random_state=42, - ) - ds.declare_decreed_var( - decreed_var=3, meta_var=0, meta_value="A" - ) # Activate x3 if x0 == A - self.assertRaises( - RuntimeError, lambda: ds.sample_valid_x(10, random_state=42) - ) - - def test_check_conditionally_acting_2(self): - for simulate_no_cs in [True, False]: - with simulate_no_config_space(simulate_no_cs): - ds = DesignSpace( - [ - CategoricalVariable(["A", "B", "C"]), # x0 - CategoricalVariable(["E", "F"]), # x1 - IntegerVariable(0, 1), # x2 - FloatVariable(0, 1), # x3 - ], - random_state=42, - ) - ds.declare_decreed_var( - decreed_var=0, meta_var=1, meta_value="E" - ) # Activate x3 if x0 == A - - ds.sample_valid_x(10, random_state=42) - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_restrictive_value_constraint_ordinal(self): - ds = DesignSpace( - [ - OrdinalVariable(["0", "1", "2"]), - OrdinalVariable(["0", "1", "2"]), - ] - ) - assert list(ds._cs.values())[0].default_value == "0" - - ds.add_value_constraint(var1=0, value1="1", var2=1, value2="1") - ds.sample_valid_x(100, random_state=42) - - x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) - x_cartesian2, _ = ds.correct_get_acting(x_cartesian) - np.testing.assert_array_equal( - np.array( - [[0, 0], [0, 1], [0, 2], [1, 0], [0, 1], [1, 2], [2, 0], [2, 1], [2, 2]] - ), - x_cartesian2, - ) - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_restrictive_value_constraint_integer(self): - ds = DesignSpace( - [ - IntegerVariable(0, 2), - IntegerVariable(0, 2), - ] - ) - assert list(ds._cs.values())[0].default_value == 1 - - ds.add_value_constraint(var1=0, value1=1, var2=1, value2=1) - ds.sample_valid_x(100, random_state=42) - - x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) - ds.correct_get_acting(x_cartesian) - x_cartesian2, _ = ds.correct_get_acting(x_cartesian) - np.testing.assert_array_equal( - np.array( - [[0, 0], [0, 1], [0, 2], [1, 0], [2, 0], [1, 2], [2, 0], [2, 1], [2, 2]] - ), - x_cartesian2, - ) - - @unittest.skipIf( - not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" - ) - def test_restrictive_value_constraint_categorical(self): - ds = DesignSpace( - [ - CategoricalVariable(["a", "b", "c"]), - CategoricalVariable(["a", "b", "c"]), - ] - ) - assert list(ds._cs.values())[0].default_value == "a" - - ds.add_value_constraint(var1=0, value1="b", var2=1, value2="b") - ds.sample_valid_x(100, random_state=42) - - x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) - ds.correct_get_acting(x_cartesian) - x_cartesian2, _ = ds.correct_get_acting(x_cartesian) - np.testing.assert_array_equal( - np.array( - [[0, 0], [0, 1], [0, 2], [1, 0], [0, 1], [1, 2], [2, 0], [2, 1], [2, 2]] - ), - x_cartesian2, - ) - - @unittest.skipIf( - not (HAS_SMTDesignSpace), - "Architecture Design Space Graph or ConfigSpace not installed.", - ) - def test_adsg_to_legacy(self): - from adsg_core import BasicADSG, NamedNode, DesignVariableNode - from SMTDesignSpace.design_space import ensure_design_space - from adsg_core import GraphProcessor - - # Create the ADSG - adsg = BasicADSG() - ndv = 13 - # Create nodes - n = [NamedNode(f"N{i}") for i in range(ndv)] - n = [ - NamedNode("MLP"), - NamedNode("Learning_rate"), - NamedNode("Activation_function"), - NamedNode("Optimizer"), - NamedNode("Decay"), - NamedNode("Power_update"), - NamedNode("Average_start"), - NamedNode("Running_Average_1"), - NamedNode("Running_Average_2"), - NamedNode("Numerical_Stability"), - NamedNode("Nb_layers"), - NamedNode("Layer_1"), - NamedNode("Layer_2"), - NamedNode("Layer_3"), # NamedNode("Dropout"), - NamedNode("ASGD"), - NamedNode("Adam"), - NamedNode("20...40"), - NamedNode("40"), - NamedNode("45"), - NamedNode("20...40"), - NamedNode("40"), - NamedNode("45"), - NamedNode("20...40"), - NamedNode("40"), - NamedNode("45"), - ] - adsg.add_node(n[1]) - adsg.add_node(n[2]) - adsg.add_edges( - [ - (n[3], n[10]), - (n[14], n[4]), - (n[14], n[5]), - (n[14], n[6]), - (n[15], n[7]), - (n[15], n[8]), - (n[15], n[9]), - ] - ) - adsg.add_selection_choice("Optimizer_Choice", n[3], [n[14], n[15]]) - adsg.add_selection_choice("#layers", n[10], [n[11], n[12], n[13]]) - a = [] - for i in range(3): - a.append(NamedNode(str(25 + 5 * i))) - b = a.copy() - b.append(n[17]) - b.append(n[18]) - choicel1 = adsg.add_selection_choice("#neurons_1", n[11], b) - adsg.add_edges([(n[12], choicel1), (n[13], choicel1)]) - - a = [] - for i in range(3): - a.append(NamedNode(str(25 + 5 * i))) - b = a.copy() - b.append(n[20]) - b.append(n[21]) - choicel1 = adsg.add_selection_choice("#neurons_2", n[12], b) - adsg.add_edges([(n[13], choicel1)]) - - a = [] - for i in range(3): - a.append(NamedNode(str(25 + 5 * i))) - b = a.copy() - b.append(n[23]) - b.append(n[24]) - choicel1 = adsg.add_selection_choice("#neurons_3", n[13], b) - - adsg.add_incompatibility_constraint([n[15], n[13]]) - adsg.add_incompatibility_constraint([n[14], n[17]]) - adsg.add_incompatibility_constraint([n[14], n[18]]) - adsg.add_incompatibility_constraint([n[14], n[20]]) - adsg.add_incompatibility_constraint([n[14], n[21]]) - adsg.add_incompatibility_constraint([n[14], n[23]]) - adsg.add_incompatibility_constraint([n[14], n[24]]) - start_nodes = set() - start_nodes.add(n[3]) - start_nodes.add(n[2]) - start_nodes.add(n[1]) - adsg.add_edges( - [ - (n[1], DesignVariableNode("x0", bounds=(0, 1))), - (n[4], DesignVariableNode("x1", bounds=(0, 1))), - (n[5], DesignVariableNode("x2", bounds=(0, 1))), - (n[6], DesignVariableNode("x3", bounds=(0, 1))), - (n[7], DesignVariableNode("x4", bounds=(0, 1))), - (n[8], DesignVariableNode("x5", bounds=(0, 1))), - (n[9], DesignVariableNode("x6", bounds=(0, 1))), - ] - ) - adsg.add_selection_choice( - "Activation_Choice", - n[2], - [NamedNode("ReLU"), NamedNode("Sigmoid"), NamedNode("Tanh")], - ) - adsg = adsg.set_start_nodes(start_nodes) - adsg.render() - gp = GraphProcessor(adsg) - gp.get_statistics() - design_space = ensure_design_space(design_space=adsg) - np.testing.assert_array_equal( - np.array( - [ - False, - False, - False, - True, - True, - True, - False, - True, - True, - True, - True, - True, - True, - ] - ), - design_space.is_conditionally_acting, - ) - design_space2 = ArchDesignSpaceGraph(adsg=adsg) - np.testing.assert_array_equal( - np.array( - [ - False, - False, - False, - True, - True, - True, - False, - True, - True, - True, - True, - True, - True, - ] - ), - design_space2.is_conditionally_acting, - ) - - -if __name__ == "__main__": - unittest.main() diff --git a/smt/design_space/test/test_design_space_local.py b/smt/design_space/test/test_design_space_local.py deleted file mode 100644 index 0a8173cac..000000000 --- a/smt/design_space/test/test_design_space_local.py +++ /dev/null @@ -1,21 +0,0 @@ -import unittest -import os - -os.environ["FORCE_RUN_LOCAL"] = "1" -from test_design_space import Test # Import the existing test class - - -class TestDSLocal(Test): - def test_design_variables(self): - os.environ["FORCE_RUN_LOCAL"] = "1" - # Load all tests from test_design_space.py - loader = unittest.TestLoader() - suite = loader.discover(start_dir=".", pattern="test_design_space.py") - # Run the tests - runner = unittest.TextTestRunner() - runner.run(suite) - del os.environ["FORCE_RUN_LOCAL"] - - -if __name__ == "__main__": - unittest.main() From 5914e507f85380329fa0b06a42b15b0c7ed227e9 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Sat, 21 Sep 2024 23:39:13 +0200 Subject: [PATCH 62/77] restore tests --- smt/design_space/tests/test_design_space.py | 862 ++++++++++++++++++ .../tests/test_design_space_local.py | 21 + 2 files changed, 883 insertions(+) create mode 100644 smt/design_space/tests/test_design_space.py create mode 100644 smt/design_space/tests/test_design_space_local.py diff --git a/smt/design_space/tests/test_design_space.py b/smt/design_space/tests/test_design_space.py new file mode 100644 index 000000000..a325d5123 --- /dev/null +++ b/smt/design_space/tests/test_design_space.py @@ -0,0 +1,862 @@ +""" +Author: Jasper Bussemaker +""" + +import contextlib +import itertools +import unittest + +import numpy as np + +from smt.sampling_methods import LHS +import os + +if os.getenv("FORCE_RUN_LOCAL"): + import smt.design_space as ds + from smt.design_space import ( + HAS_CONFIG_SPACE, + HAS_ADSG, + HAS_SMTDesignSpace, + BaseDesignSpace, + CategoricalVariable, + FloatVariable, + IntegerVariable, + OrdinalVariable, + DesignSpace, + ArchDesignSpaceGraph, + ) +else: + HAS_ADSG = False + HAS_SMTDesignSpace = False + HAS_CONFIG_SPACE = False + import smt.design_space.design_space as ds + from smt.design_space.design_space import ( + BaseDesignSpace, + CategoricalVariable, + FloatVariable, + IntegerVariable, + OrdinalVariable, + DesignSpace, + ) + + +@contextlib.contextmanager +def simulate_no_config_space(do_simulate=True): + if ds.HAS_CONFIG_SPACE and do_simulate: + ds.HAS_CONFIG_SPACE = False + yield + ds.HAS_CONFIG_SPACE = True + else: + yield + + +class Test(unittest.TestCase): + def test_design_variables(self): + with self.assertRaises(ValueError): + FloatVariable(1, 0) + + float_var = FloatVariable(0, 1) + self.assertEqual(float_var.lower, 0) + self.assertEqual(float_var.upper, 1) + self.assertEqual(float_var.get_limits(), (0, 1)) + self.assertTrue(str(float_var)) + self.assertTrue(repr(float_var)) + self.assertEqual("FloatVariable", float_var.get_typename()) + + with self.assertRaises(ValueError): + IntegerVariable(1, 0) + + int_var = IntegerVariable(0, 1) + self.assertEqual(int_var.lower, 0) + self.assertEqual(int_var.upper, 1) + self.assertEqual(int_var.get_limits(), (0, 1)) + self.assertTrue(str(int_var)) + self.assertTrue(repr(int_var)) + self.assertEqual("IntegerVariable", int_var.get_typename()) + + with self.assertRaises(ValueError): + OrdinalVariable([]) + with self.assertRaises(ValueError): + OrdinalVariable(["1"]) + + ord_var = OrdinalVariable(["A", "B", "C"]) + self.assertEqual(ord_var.values, ["A", "B", "C"]) + self.assertEqual(ord_var.get_limits(), ["0", "1", "2"]) + self.assertEqual(ord_var.lower, 0) + self.assertEqual(ord_var.upper, 2) + self.assertTrue(str(ord_var)) + self.assertTrue(repr(ord_var)) + self.assertEqual("OrdinalVariable", ord_var.get_typename()) + + with self.assertRaises(ValueError): + CategoricalVariable([]) + with self.assertRaises(ValueError): + CategoricalVariable(["A"]) + + cat_var = CategoricalVariable(["A", "B", "C"]) + self.assertEqual(cat_var.values, ["A", "B", "C"]) + self.assertEqual(cat_var.get_limits(), ["A", "B", "C"]) + self.assertEqual(cat_var.lower, 0) + self.assertEqual(cat_var.upper, 2) + self.assertTrue(str(cat_var)) + self.assertTrue(repr(cat_var)) + self.assertEqual("CategoricalVariable", cat_var.get_typename()) + + def test_rounding(self): + ds = BaseDesignSpace( + [ + IntegerVariable(0, 5), + IntegerVariable(-1, 1), + IntegerVariable(2, 4), + ] + ) + + x = np.array( + list( + itertools.product( + np.linspace(0, 5, 20), np.linspace(-1, 1, 20), np.linspace(2, 4, 20) + ) + ) + ) + for i, dv in enumerate(ds.design_variables): + self.assertIsInstance(dv, IntegerVariable) + x[:, i] = ds._round_equally_distributed(x[:, i], dv.lower, dv.upper) + + x1, x1_counts = np.unique(x[:, 0], return_counts=True) + self.assertTrue(np.all(x1 == [0, 1, 2, 3, 4, 5])) + x1_counts = x1_counts / np.sum(x1_counts) + self.assertTrue(np.all(np.abs(x1_counts - np.mean(x1_counts)) <= 0.05)) + + x2, x2_counts = np.unique(x[:, 1], return_counts=True) + self.assertTrue(np.all(x2 == [-1, 0, 1])) + x2_counts = x2_counts / np.sum(x2_counts) + self.assertTrue(np.all(np.abs(x2_counts - np.mean(x2_counts)) <= 0.05)) + + x3, x3_counts = np.unique(x[:, 2], return_counts=True) + self.assertTrue(np.all(x3 == [2, 3, 4])) + x3_counts = x3_counts / np.sum(x3_counts) + self.assertTrue(np.all(np.abs(x3_counts - np.mean(x3_counts)) <= 0.05)) + + def test_base_design_space(self): + ds = BaseDesignSpace( + [ + CategoricalVariable(["A", "B"]), + IntegerVariable(0, 3), + FloatVariable(-0.5, 0.5), + ] + ) + self.assertEqual(ds.get_x_limits(), [["A", "B"], (0, 3), (-0.5, 0.5)]) + self.assertTrue(np.all(ds.get_num_bounds() == [[0, 1], [0, 3], [-0.5, 0.5]])) + self.assertTrue( + np.all( + ds.get_unfolded_num_bounds() == [[0, 1], [0, 1], [0, 3], [-0.5, 0.5]] + ) + ) + + x = np.array( + [ + [0, 0, 0], + [1, 2, 0.5], + [0, 3, 0.5], + ] + ) + is_acting = np.array( + [ + [True, True, False], + [True, False, True], + [False, True, True], + ] + ) + + x_unfolded, is_acting_unfolded = ds.unfold_x(x, is_acting) + self.assertTrue( + np.all( + x_unfolded + == [ + [1, 0, 0, 0], + [0, 1, 2, 0.5], + [1, 0, 3, 0.5], + ] + ) + ) + self.assertEqual(is_acting_unfolded.dtype, bool) + np.testing.assert_array_equal( + is_acting_unfolded, + [ + [True, True, True, False], + [True, True, False, True], + [False, False, True, True], + ], + ) + + x_folded, is_acting_folded = ds.fold_x(x_unfolded, is_acting_unfolded) + np.testing.assert_array_equal(x_folded, x) + np.testing.assert_array_equal(is_acting_folded, is_acting) + + x_unfold_mask, is_act_unfold_mask = ds.unfold_x( + x, is_acting, fold_mask=np.array([False] * 3) + ) + np.testing.assert_array_equal(x_unfold_mask, x) + np.testing.assert_array_equal(is_act_unfold_mask, is_acting) + + x_fold_mask, is_act_fold_mask = ds.fold_x( + x, is_acting, fold_mask=np.array([False] * 3) + ) + np.testing.assert_array_equal(x_fold_mask, x) + + np.testing.assert_array_equal(is_act_fold_mask, is_acting) + + def test_create_design_space(self): + DesignSpace([FloatVariable(0, 1)]) + with simulate_no_config_space(): + DesignSpace([FloatVariable(0, 1)]) + + def test_design_space(self): + ds = DesignSpace( + [ + CategoricalVariable(["A", "B", "C"]), + OrdinalVariable(["0", "1"]), + IntegerVariable(-1, 2), + FloatVariable(0.5, 1.5), + ], + random_state=42, + ) + self.assertEqual(len(ds.design_variables), 4) + if HAS_CONFIG_SPACE: + self.assertEqual(len(list(ds._cs.values())), 4) + self.assertTrue(np.all(~ds.is_conditionally_acting)) + if HAS_CONFIG_SPACE: + x, is_acting = ds.sample_valid_x(3, random_state=42) + self.assertEqual(x.shape, (3, 4)) + np.testing.assert_allclose( + x, + np.array( + [ + [1.0, 0.0, -0.0, 0.83370861], + [2.0, 0.0, -1.0, 0.64286682], + [2.0, 0.0, -0.0, 1.15088847], + ] + ), + atol=1e-8, + ) + else: + ds.sample_valid_x(3, random_state=42) + x = np.array( + [ + [1, 0, 0, 0.834], + [2, 0, -1, 0.6434], + [2, 0, 0, 1.151], + ] + ) + x, is_acting = ds.correct_get_acting(x) + + self.assertEqual(x.shape, (3, 4)) + self.assertEqual(is_acting.shape, x.shape) + + self.assertEqual(ds.decode_values(x, i_dv=0), ["B", "C", "C"]) + self.assertEqual(ds.decode_values(x, i_dv=1), ["0", "0", "0"]) + self.assertEqual(ds.decode_values(np.array([0, 1, 2]), i_dv=0), ["A", "B", "C"]) + self.assertEqual(ds.decode_values(np.array([0, 1]), i_dv=1), ["0", "1"]) + + self.assertEqual(ds.decode_values(x[0, :]), ["B", "0", 0, x[0, 3]]) + self.assertEqual(ds.decode_values(x[[0], :]), [["B", "0", 0, x[0, 3]]]) + self.assertEqual( + ds.decode_values(x), + [ + ["B", "0", 0, x[0, 3]], + ["C", "0", -1, x[1, 3]], + ["C", "0", 0, x[2, 3]], + ], + ) + + x_corr, is_act_corr = ds.correct_get_acting(x) + self.assertTrue(np.all(x_corr == x)) + self.assertTrue(np.all(is_act_corr == is_acting)) + + x_sampled_externally = LHS( + xlimits=ds.get_unfolded_num_bounds(), criterion="ese", random_state=42 + )(3) + x_corr, is_acting_corr = ds.correct_get_acting(x_sampled_externally) + x_corr, is_acting_corr = ds.fold_x(x_corr, is_acting_corr) + np.testing.assert_allclose( + x_corr, + np.array( + [ + [2.0, 0.0, -1.0, 1.34158548], + [0.0, 1.0, -0.0, 0.55199817], + [1.0, 1.0, 1.0, 1.15663662], + ] + ), + atol=1e-8, + ) + self.assertTrue(np.all(is_acting_corr)) + + x_unfolded, is_acting_unfolded = ds.sample_valid_x( + 3, unfolded=True, random_state=42 + ) + self.assertEqual(x_unfolded.shape, (3, 6)) + if HAS_CONFIG_SPACE: + np.testing.assert_allclose( + x_unfolded, + np.array( + [ + [1.0, 0.0, 0.0, 0.0, 2.0, 1.11213215], + [0.0, 1.0, 0.0, 1.0, -1.0, 1.09482857], + [1.0, 0.0, 0.0, 1.0, -1.0, 0.75061044], + ] + ), + atol=1e-8, + ) + + self.assertTrue(str(ds)) + self.assertTrue(repr(ds)) + + ds.correct_get_acting(np.array([[0, 0, 0, 1.6]])) + + def test_folding_mask(self): + ds = DesignSpace( + [ + CategoricalVariable(["A", "B", "C"]), + CategoricalVariable(["A", "B", "C"]), + ] + ) + x = np.array([[1, 2]]) + is_act = np.array([[True, False]]) + + self.assertEqual(ds._get_n_dim_unfolded(), 6) + + x_unfolded, is_act_unfolded = ds.unfold_x(x, is_act, np.array([True, False])) + self.assertTrue(np.all(x_unfolded == np.array([[0, 1, 0, 2]]))) + self.assertTrue( + np.all(is_act_unfolded == np.array([[True, True, True, False]])) + ) + + x_folded, is_act_folded = ds.fold_x( + x_unfolded, is_act_unfolded, np.array([True, False]) + ) + self.assertTrue(np.all(x_folded == x)) + self.assertTrue(np.all(is_act_folded == is_act)) + + def test_float_design_space(self): + ds = DesignSpace([(0, 1), (0.5, 2.5), (-0.4, 10)]) + assert ds.n_dv == 3 + assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) + assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) + + ds = DesignSpace([[0, 1], [0.5, 2.5], [-0.4, 10]]) + assert ds.n_dv == 3 + assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) + assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) + + ds = DesignSpace(np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) + assert ds.n_dv == 3 + assert all(isinstance(dv, FloatVariable) for dv in ds.design_variables) + assert np.all(ds.get_num_bounds() == np.array([[0, 1], [0.5, 2.5], [-0.4, 10]])) + + def test_design_space_hierarchical(self): + ds = DesignSpace( + [ + CategoricalVariable(["A", "B", "C"]), # x0 + CategoricalVariable(["E", "F"]), # x1 + IntegerVariable(0, 1), # x2 + FloatVariable(0.1, 1), # x3 + ], + random_state=42, + ) + ds.declare_decreed_var( + decreed_var=3, meta_var=0, meta_value="A" + ) # Activate x3 if x0 == A + + x_cartesian = np.array( + list(itertools.product([0, 1, 2], [0, 1], [0, 1], [0.25, 0.75])) + ) + self.assertEqual(x_cartesian.shape, (24, 4)) + + self.assertTrue( + np.all(ds.is_conditionally_acting == [False, False, False, True]) + ) + + x, is_acting = ds.correct_get_acting(x_cartesian) + _, is_unique = np.unique(x, axis=0, return_index=True) + self.assertEqual(len(is_unique), 16) + np.testing.assert_allclose( + x[is_unique, :], + np.array( + [ + [0, 0, 0, 0.25], + [0, 0, 0, 0.75], + [0, 0, 1, 0.25], + [0, 0, 1, 0.75], + [0, 1, 0, 0.25], + [0, 1, 0, 0.75], + [0, 1, 1, 0.25], + [0, 1, 1, 0.75], + [1, 0, 0, 0.55], + [1, 0, 1, 0.55], + [1, 1, 0, 0.55], + [1, 1, 1, 0.55], + [2, 0, 0, 0.55], + [2, 0, 1, 0.55], + [2, 1, 0, 0.55], + [2, 1, 1, 0.55], + ] + ), + ) + np.testing.assert_array_equal( + is_acting[is_unique, :], + np.array( + [ + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + ] + ), + ) + + x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) + assert x_sampled.shape == (100, 4) + x_sampled[is_acting_sampled[:, 3], 3] = np.round( + x_sampled[is_acting_sampled[:, 3], 3], 4 + ) + + x_corr, is_acting_corr = ds.correct_get_acting(x_sampled) + self.assertTrue(np.sum(np.abs(x_corr - x_sampled)) < 1e-12) + self.assertTrue(np.all(is_acting_corr == is_acting_sampled)) + + seen_x = set() + seen_is_acting = set() + for i, xi in enumerate(x_sampled): + seen_x.add(tuple(xi)) + seen_is_acting.add(tuple(is_acting_sampled[i, :])) + if HAS_ADSG: + assert len(seen_x) == 49 + else: + assert len(seen_x) == 42 + assert len(seen_is_acting) == 2 + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_design_space_hierarchical_config_space(self): + ds = DesignSpace( + [ + CategoricalVariable(["A", "B", "Cc"]), # x0 + CategoricalVariable(["E", "F"]), # x1 + IntegerVariable(0, 1), # x2 + FloatVariable(0, 1), # x3 + ], + random_state=42, + ) + ds.declare_decreed_var( + decreed_var=3, meta_var=0, meta_value="A" + ) # Activate x3 if x0 == A + ds.add_value_constraint( + var1=0, value1=["Cc"], var2=1, value2="F" + ) # Prevent a == C and b == F + + x_cartesian = np.array( + list(itertools.product([0, 1, 2], [0, 1], [0, 1], [0.25, 0.75])) + ) + self.assertEqual(x_cartesian.shape, (24, 4)) + + self.assertTrue( + np.all(ds.is_conditionally_acting == [False, False, False, True]) + ) + + x, is_acting = ds.correct_get_acting(x_cartesian) + _, is_unique = np.unique(x, axis=0, return_index=True) + self.assertEqual(len(is_unique), 14) + np.testing.assert_array_equal( + x[is_unique, :], + np.array( + [ + [0, 0, 0, 0.25], + [0, 0, 0, 0.75], + [0, 0, 1, 0.25], + [0, 0, 1, 0.75], + [0, 1, 0, 0.25], + [0, 1, 0, 0.75], + [0, 1, 1, 0.25], + [0, 1, 1, 0.75], + [1, 0, 0, 0.5], + [1, 0, 1, 0.5], + [1, 1, 0, 0.5], + [1, 1, 1, 0.5], + [2, 0, 0, 0.5], + [2, 0, 1, 0.5], + ] + ), + ) + np.testing.assert_array_equal( + is_acting[is_unique, :], + np.array( + [ + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, True], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + [True, True, True, False], + ] + ), + ) + + x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) + assert x_sampled.shape == (100, 4) + x_sampled[is_acting_sampled[:, 3], 3] = np.round( + x_sampled[is_acting_sampled[:, 3], 3] + ) + + x_corr, is_acting_corr = ds.correct_get_acting(x_sampled) + self.assertTrue(np.all(x_corr == x_sampled)) + self.assertTrue(np.all(is_acting_corr == is_acting_sampled)) + + seen_x = set() + seen_is_acting = set() + for i, xi in enumerate(x_sampled): + seen_x.add(tuple(xi)) + seen_is_acting.add(tuple(is_acting_sampled[i, :])) + assert len(seen_x) == 14 + assert len(seen_is_acting) == 2 + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_design_space_continuous(self): + ds = DesignSpace( + [ + FloatVariable(0, 1), # x0 + FloatVariable(0, 1), # x1 + FloatVariable(0, 1), # x2 + ], + random_state=42, + ) + ds.add_value_constraint( + var1=0, value1="<", var2=1, value2=">" + ) # Prevent x0 < x1 + ds.add_value_constraint( + var1=1, value1="<", var2=2, value2=">" + ) # Prevent x1 < x2 + + # correct_get_acting + x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) + self.assertTrue(np.min(x_sampled[:, 0] - x_sampled[:, 1]) > 0) + self.assertTrue(np.min(x_sampled[:, 1] - x_sampled[:, 2]) > 0) + ds = DesignSpace( + [ + IntegerVariable(0, 2), # x0 + FloatVariable(0, 2), # x1 + IntegerVariable(0, 2), # x2 + ], + random_state=42, + ) + ds.add_value_constraint( + var1=0, value1="<", var2=1, value2=">" + ) # Prevent x0 < x1 + ds.add_value_constraint( + var1=1, value1="<", var2=2, value2=">" + ) # Prevent x0 < x1 + + # correct_get_acting + x_sampled, is_acting_sampled = ds.sample_valid_x(100, random_state=42) + self.assertTrue(np.min(x_sampled[:, 0] - x_sampled[:, 1]) > 0) + self.assertTrue(np.min(x_sampled[:, 1] - x_sampled[:, 2]) > 0) + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_check_conditionally_acting(self): + class WrongDesignSpace(DesignSpace): + def _is_conditionally_acting(self) -> np.ndarray: + return np.zeros((self.n_dv,), dtype=bool) + + for simulate_no_cs in [True, False]: + with simulate_no_config_space(simulate_no_cs): + ds = WrongDesignSpace( + [ + CategoricalVariable(["A", "B", "C"]), # x0 + CategoricalVariable(["E", "F"]), # x1 + IntegerVariable(0, 1), # x2 + FloatVariable(0, 1), # x3 + ], + random_state=42, + ) + ds.declare_decreed_var( + decreed_var=3, meta_var=0, meta_value="A" + ) # Activate x3 if x0 == A + self.assertRaises( + RuntimeError, lambda: ds.sample_valid_x(10, random_state=42) + ) + + def test_check_conditionally_acting_2(self): + for simulate_no_cs in [True, False]: + with simulate_no_config_space(simulate_no_cs): + ds = DesignSpace( + [ + CategoricalVariable(["A", "B", "C"]), # x0 + CategoricalVariable(["E", "F"]), # x1 + IntegerVariable(0, 1), # x2 + FloatVariable(0, 1), # x3 + ], + random_state=42, + ) + ds.declare_decreed_var( + decreed_var=0, meta_var=1, meta_value="E" + ) # Activate x3 if x0 == A + + ds.sample_valid_x(10, random_state=42) + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_restrictive_value_constraint_ordinal(self): + ds = DesignSpace( + [ + OrdinalVariable(["0", "1", "2"]), + OrdinalVariable(["0", "1", "2"]), + ] + ) + assert list(ds._cs.values())[0].default_value == "0" + + ds.add_value_constraint(var1=0, value1="1", var2=1, value2="1") + ds.sample_valid_x(100, random_state=42) + + x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) + x_cartesian2, _ = ds.correct_get_acting(x_cartesian) + np.testing.assert_array_equal( + np.array( + [[0, 0], [0, 1], [0, 2], [1, 0], [0, 1], [1, 2], [2, 0], [2, 1], [2, 2]] + ), + x_cartesian2, + ) + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_restrictive_value_constraint_integer(self): + ds = DesignSpace( + [ + IntegerVariable(0, 2), + IntegerVariable(0, 2), + ] + ) + assert list(ds._cs.values())[0].default_value == 1 + + ds.add_value_constraint(var1=0, value1=1, var2=1, value2=1) + ds.sample_valid_x(100, random_state=42) + + x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) + ds.correct_get_acting(x_cartesian) + x_cartesian2, _ = ds.correct_get_acting(x_cartesian) + np.testing.assert_array_equal( + np.array( + [[0, 0], [0, 1], [0, 2], [1, 0], [2, 0], [1, 2], [2, 0], [2, 1], [2, 2]] + ), + x_cartesian2, + ) + + @unittest.skipIf( + not HAS_CONFIG_SPACE, "Hierarchy ConfigSpace dependency not installed" + ) + def test_restrictive_value_constraint_categorical(self): + ds = DesignSpace( + [ + CategoricalVariable(["a", "b", "c"]), + CategoricalVariable(["a", "b", "c"]), + ] + ) + assert list(ds._cs.values())[0].default_value == "a" + + ds.add_value_constraint(var1=0, value1="b", var2=1, value2="b") + ds.sample_valid_x(100, random_state=42) + + x_cartesian = np.array(list(itertools.product([0, 1, 2], [0, 1, 2]))) + ds.correct_get_acting(x_cartesian) + x_cartesian2, _ = ds.correct_get_acting(x_cartesian) + np.testing.assert_array_equal( + np.array( + [[0, 0], [0, 1], [0, 2], [1, 0], [0, 1], [1, 2], [2, 0], [2, 1], [2, 2]] + ), + x_cartesian2, + ) + + @unittest.skipIf( + not (HAS_SMTDesignSpace), + "Architecture Design Space Graph or ConfigSpace not installed.", + ) + def test_adsg_to_legacy(self): + from adsg_core import BasicADSG, NamedNode, DesignVariableNode + from SMTDesignSpace.design_space import ensure_design_space + from adsg_core import GraphProcessor + + # Create the ADSG + adsg = BasicADSG() + ndv = 13 + # Create nodes + n = [NamedNode(f"N{i}") for i in range(ndv)] + n = [ + NamedNode("MLP"), + NamedNode("Learning_rate"), + NamedNode("Activation_function"), + NamedNode("Optimizer"), + NamedNode("Decay"), + NamedNode("Power_update"), + NamedNode("Average_start"), + NamedNode("Running_Average_1"), + NamedNode("Running_Average_2"), + NamedNode("Numerical_Stability"), + NamedNode("Nb_layers"), + NamedNode("Layer_1"), + NamedNode("Layer_2"), + NamedNode("Layer_3"), # NamedNode("Dropout"), + NamedNode("ASGD"), + NamedNode("Adam"), + NamedNode("20...40"), + NamedNode("40"), + NamedNode("45"), + NamedNode("20...40"), + NamedNode("40"), + NamedNode("45"), + NamedNode("20...40"), + NamedNode("40"), + NamedNode("45"), + ] + adsg.add_node(n[1]) + adsg.add_node(n[2]) + adsg.add_edges( + [ + (n[3], n[10]), + (n[14], n[4]), + (n[14], n[5]), + (n[14], n[6]), + (n[15], n[7]), + (n[15], n[8]), + (n[15], n[9]), + ] + ) + adsg.add_selection_choice("Optimizer_Choice", n[3], [n[14], n[15]]) + adsg.add_selection_choice("#layers", n[10], [n[11], n[12], n[13]]) + a = [] + for i in range(3): + a.append(NamedNode(str(25 + 5 * i))) + b = a.copy() + b.append(n[17]) + b.append(n[18]) + choicel1 = adsg.add_selection_choice("#neurons_1", n[11], b) + adsg.add_edges([(n[12], choicel1), (n[13], choicel1)]) + + a = [] + for i in range(3): + a.append(NamedNode(str(25 + 5 * i))) + b = a.copy() + b.append(n[20]) + b.append(n[21]) + choicel1 = adsg.add_selection_choice("#neurons_2", n[12], b) + adsg.add_edges([(n[13], choicel1)]) + + a = [] + for i in range(3): + a.append(NamedNode(str(25 + 5 * i))) + b = a.copy() + b.append(n[23]) + b.append(n[24]) + choicel1 = adsg.add_selection_choice("#neurons_3", n[13], b) + + adsg.add_incompatibility_constraint([n[15], n[13]]) + adsg.add_incompatibility_constraint([n[14], n[17]]) + adsg.add_incompatibility_constraint([n[14], n[18]]) + adsg.add_incompatibility_constraint([n[14], n[20]]) + adsg.add_incompatibility_constraint([n[14], n[21]]) + adsg.add_incompatibility_constraint([n[14], n[23]]) + adsg.add_incompatibility_constraint([n[14], n[24]]) + start_nodes = set() + start_nodes.add(n[3]) + start_nodes.add(n[2]) + start_nodes.add(n[1]) + adsg.add_edges( + [ + (n[1], DesignVariableNode("x0", bounds=(0, 1))), + (n[4], DesignVariableNode("x1", bounds=(0, 1))), + (n[5], DesignVariableNode("x2", bounds=(0, 1))), + (n[6], DesignVariableNode("x3", bounds=(0, 1))), + (n[7], DesignVariableNode("x4", bounds=(0, 1))), + (n[8], DesignVariableNode("x5", bounds=(0, 1))), + (n[9], DesignVariableNode("x6", bounds=(0, 1))), + ] + ) + adsg.add_selection_choice( + "Activation_Choice", + n[2], + [NamedNode("ReLU"), NamedNode("Sigmoid"), NamedNode("Tanh")], + ) + adsg = adsg.set_start_nodes(start_nodes) + adsg.render() + gp = GraphProcessor(adsg) + gp.get_statistics() + design_space = ensure_design_space(design_space=adsg) + np.testing.assert_array_equal( + np.array( + [ + False, + False, + False, + True, + True, + True, + False, + True, + True, + True, + True, + True, + True, + ] + ), + design_space.is_conditionally_acting, + ) + design_space2 = ArchDesignSpaceGraph(adsg=adsg) + np.testing.assert_array_equal( + np.array( + [ + False, + False, + False, + True, + True, + True, + False, + True, + True, + True, + True, + True, + True, + ] + ), + design_space2.is_conditionally_acting, + ) + + +if __name__ == "__main__": + unittest.main() diff --git a/smt/design_space/tests/test_design_space_local.py b/smt/design_space/tests/test_design_space_local.py new file mode 100644 index 000000000..0a8173cac --- /dev/null +++ b/smt/design_space/tests/test_design_space_local.py @@ -0,0 +1,21 @@ +import unittest +import os + +os.environ["FORCE_RUN_LOCAL"] = "1" +from test_design_space import Test # Import the existing test class + + +class TestDSLocal(Test): + def test_design_variables(self): + os.environ["FORCE_RUN_LOCAL"] = "1" + # Load all tests from test_design_space.py + loader = unittest.TestLoader() + suite = loader.discover(start_dir=".", pattern="test_design_space.py") + # Run the tests + runner = unittest.TextTestRunner() + runner.run(suite) + del os.environ["FORCE_RUN_LOCAL"] + + +if __name__ == "__main__": + unittest.main() From 6ebeb3f1186583540c7bd2b0c2f03090192eea2e Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Thu, 26 Sep 2024 09:54:09 +0200 Subject: [PATCH 63/77] remove notebook --- .../SMT_DesignSpace_example.ipynb | 395 ------------------ tutorial/README.md | 4 - 2 files changed, 399 deletions(-) delete mode 100644 tutorial/MixedInteger/SMT_DesignSpace_example.ipynb diff --git a/tutorial/MixedInteger/SMT_DesignSpace_example.ipynb b/tutorial/MixedInteger/SMT_DesignSpace_example.ipynb deleted file mode 100644 index 082d8d1bc..000000000 --- a/tutorial/MixedInteger/SMT_DesignSpace_example.ipynb +++ /dev/null @@ -1,395 +0,0 @@ -{ - "cells": [ - { - "cell_type": "markdown", - "metadata": { - "colab_type": "text", - "id": "view-in-github" - }, - "source": [ - "\"Open" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "mDCpNW2-mu3w" - }, - "source": [ - "
\n", - " \n", - "This tutorial describes how to use de DesignSpace within the SMT toolbox. \n", - "
\n", - " \n", - " May 2024 - `SMT version 2.5.1`\n", - " \n", - " Jasper Bussemaker (DLR), Paul Saves, and Nathalie BARTOLI (ONERA/DTIS/M2CI)" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "

Some updates

\n", - "
    - Manipulation of mixed DOE (continuous, integer, categorical and hierarchical variables)
\n", - "
" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "gDeEbi7nmu32" - }, - "source": [ - "

\n", - "To use SMT models, please follow this link : https://github.com/SMTorg/SMT/blob/master/README.md. The documentation is available here: http://smt.readthedocs.io/en/latest/\n", - "

\n", - "\n", - "The reference paper is available \n", - "here https://www.sciencedirect.com/science/article/pii/S0965997818309360?via%3Dihub \n", - "\n", - "or as a preprint: http://mdolab.engin.umich.edu/content/python-surrogate-modeling-framework-derivatives" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "uU32V-7bmu33" - }, - "source": [ - "For mixed integer with continuous relaxation, the reference paper is available here https://www.sciencedirect.com/science/article/pii/S0925231219315619" - ] - }, - { - "cell_type": "code", - "execution_count": 1, - "metadata": { - "colab": { - "base_uri": "https://localhost:8080/", - "height": 1000 - }, - "id": "EweBFT9Ap8Ay", - "outputId": "4c016eb0-6a75-46f7-d2db-c4ff17ec284a" - }, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Requirement already satisfied: smt in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (2.6.2)\n", - "Requirement already satisfied: scikit-learn in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.4.0)\n", - "Requirement already satisfied: pyDOE3 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.0.3)\n", - "Requirement already satisfied: scipy in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.11.3)\n", - "Requirement already satisfied: jenn in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from smt) (1.0.6)\n", - "Requirement already satisfied: jsonpointer>=2.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (3.0.0)\n", - "Requirement already satisfied: jsonschema>=4.22 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (4.22.0)\n", - "Requirement already satisfied: orjson>=3.9 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (3.10.6)\n", - "Requirement already satisfied: numpy>=1.22 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jenn->smt) (1.23.5)\n", - "Requirement already satisfied: joblib>=1.2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from scikit-learn->smt) (1.4.2)\n", - "Requirement already satisfied: threadpoolctl>=2.0.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from scikit-learn->smt) (3.5.0)\n", - "Requirement already satisfied: attrs>=22.2.0 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (23.1.0)\n", - "Requirement already satisfied: jsonschema-specifications>=2023.03.6 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (2023.12.1)\n", - "Requirement already satisfied: referencing>=0.28.4 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.35.1)\n", - "Requirement already satisfied: rpds-py>=0.7.1 in /stck/psaves/miniconda3/envs/newenv1/lib/python3.9/site-packages (from jsonschema>=4.22->jenn->smt) (0.18.1)\n" - ] - } - ], - "source": [ - "# to install smt\n", - "!pip install smt" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "
\n", - "If you use hierarchical variables and the size of your doe greater than 30 points, you may leverage the `numba` JIT compiler to speed up the computation\n", - "To do so:\n", - " \n", - " - install numba library\n", - " \n", - " `pip install numba`\n", - " \n", - " \n", - " - and define the environment variable `USE_NUMBA_JIT = 1` (unset or 0 if you do not want to use numba) \n", - " \n", - " - Linux: export USE_NUMBA_JIT = 1\n", - " \n", - " - Windows: set USE_NUMBA_JIT = 1\n", - "\n", - "
" - ] - }, - { - "cell_type": "code", - "execution_count": 2, - "metadata": {}, - "outputs": [], - "source": [ - "from smt.utils.design_space import (\n", - " DesignSpace,\n", - " FloatVariable,\n", - " IntegerVariable,\n", - " OrdinalVariable,\n", - " CategoricalVariable,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "aggEHXHmmu4I" - }, - "source": [ - "# Manipulate DOE with mixed, categorical & hierarchical variables" - ] - }, - { - "cell_type": "markdown", - "metadata": { - "id": "dvVSDE-omu4I" - }, - "source": [ - "4 variables \n", - " - 1 categorical variable with 2 labels ['A', 'B'] # x0 categorical: A or B; order is not relevant\n", - " - 1 ordinal variable with 3 levels ['C', 'D', 'E']), # x1 ordinal: C, D or E; order is relevant\n", - " - 1 integer variable [0,2]: 3 possibilities: 0, 1, 2\n", - " - 1 continuous variable $\\in [0, 1]$\n", - " \n", - " \n", - " **Posssibility to have hierarchical variable: x1 exists only if x0 = 'A'**" - ] - }, - { - "cell_type": "code", - "execution_count": 3, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of design variables 4\n" - ] - } - ], - "source": [ - "# Instantiate the design space with all its design variables:\n", - "\n", - "ds = DesignSpace(\n", - " [\n", - " CategoricalVariable(\n", - " [\"A\", \"B\"]\n", - " ), # x0 categorical: A or B; order is not relevant\n", - " OrdinalVariable([\"C\", \"D\", \"E\"]), # x1 ordinal: C, D or E; order is relevant\n", - " IntegerVariable(0, 2), # x2 integer between 0 and 2 (inclusive): 0, 1, 2\n", - " FloatVariable(0, 1), # c3 continuous between 0 and 1\n", - " ]\n", - ")\n", - "\n", - "print(\"Number of design variables\", len(ds.design_variables))\n", - "# You can define decreed variables (conditional activation):\n", - "ds.declare_decreed_var(\n", - " decreed_var=1, meta_var=0, meta_value=\"A\"\n", - ") # Activate x1 if x0 == A" - ] - }, - { - "cell_type": "code", - "execution_count": 4, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Data encoded: \n", - " [[0. 2. 1. 0.50141714]\n", - " [1. 0. 1. 0.48517298]\n", - " [0. 1. 2. 0.83539973]\n", - " [0. 0. 1. 0.65900747]\n", - " [0. 2. 1. 0.5664969 ]]\n", - "Data in initial space: \n", - " [['A', 'E', 1.0, 0.5014171417556681], ['B', 'C', 1.0, 0.48517297677504534], ['A', 'D', 2.0, 0.835399731580032], ['A', 'C', 1.0, 0.6590074713239295], ['A', 'E', 1.0, 0.5664968989411066]]\n" - ] - } - ], - "source": [ - "## To give some examples\n", - "# It is also possible to randomly sample design vectors conforming to the constraints:\n", - "n = 5\n", - "x_sampled, is_acting_sampled = ds.sample_valid_x(5)\n", - "\n", - "print(\"Data encoded: \\n\", x_sampled)\n", - "print(\"Data in initial space: \\n\", ds.decode_values(x_sampled))" - ] - }, - { - "cell_type": "code", - "execution_count": 5, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Which variables are active \n", - " [[ True True True True]\n", - " [ True False True True]\n", - " [ True True True True]\n", - " [ True True True True]\n", - " [ True True True True]]\n" - ] - } - ], - "source": [ - "# After defining everything correctly, you can then use the design space object\n", - "# to correct design vectors and get information about which design variables are acting:\n", - "x_corr, is_acting = ds.correct_get_acting(x_sampled)\n", - "print(\"Which variables are active \\n\", is_acting)" - ] - }, - { - "cell_type": "code", - "execution_count": 6, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Limits of each variable \n", - " [['A', 'B'], ['0', '1', '2'], (0, 2), (0, 1)]\n", - "Continuous bounds with the encoding done (4 variables now) \n", - " [[0 1]\n", - " [0 2]\n", - " [0 2]\n", - " [0 1]]\n", - "Continuous bounds with the unfolded encoding done (5 variables now)\n", - " [[0. 1.]\n", - " [0. 1.]\n", - " [0. 2.]\n", - " [0. 2.]\n", - " [0. 1.]]\n" - ] - } - ], - "source": [ - "# If needed, it is possible to get the legacy design space definition format:\n", - "xlimits = ds.get_x_limits()\n", - "cont_bounds = ds.get_num_bounds()\n", - "unfolded_cont_bounds = ds.get_unfolded_num_bounds()\n", - "print(\"Limits of each variable \\n\", xlimits)\n", - "print(\"Continuous bounds with the encoding done (4 variables now) \\n\", cont_bounds)\n", - "print(\n", - " \"Continuous bounds with the unfolded encoding done (5 variables now)\\n\",\n", - " unfolded_cont_bounds,\n", - ")" - ] - }, - { - "cell_type": "markdown", - "metadata": {}, - "source": [ - "# Manipulate DOE with continuous variables" - ] - }, - { - "cell_type": "code", - "execution_count": 7, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Number of design variables = 3 or 3\n" - ] - } - ], - "source": [ - "# You can also instantiate a purely-continuous design space from bounds directly:\n", - "continuous_design_space = DesignSpace([(0, 1), (0, 2), (0.5, 5.5)])\n", - "print(\n", - " \"Number of design variables =\",\n", - " continuous_design_space.n_dv,\n", - " \" or \",\n", - " len(continuous_design_space.design_variables),\n", - ")" - ] - }, - { - "cell_type": "code", - "execution_count": 8, - "metadata": {}, - "outputs": [], - "source": [ - "x_sampled_cont, is_acting_sampled_cont = continuous_design_space.sample_valid_x(5)" - ] - }, - { - "cell_type": "code", - "execution_count": 9, - "metadata": {}, - "outputs": [ - { - "name": "stdout", - "output_type": "stream", - "text": [ - "Data encoded: \n", - " [[0.31711655 0.1616406 2.58306429]\n", - " [0.49960756 0.62928794 2.96869517]\n", - " [0.11611917 0.63034393 2.74785997]\n", - " [0.44327097 0.3821734 3.78969088]\n", - " [0.32158259 1.88724976 1.06429242]]\n", - "Is_acting: \n", - " [[ True True True]\n", - " [ True True True]\n", - " [ True True True]\n", - " [ True True True]\n", - " [ True True True]]\n" - ] - } - ], - "source": [ - "print(\"Data encoded: \\n\", x_sampled_cont)\n", - "print(\"Is_acting: \\n\", is_acting_sampled_cont)" - ] - }, - { - "cell_type": "code", - "execution_count": null, - "metadata": {}, - "outputs": [], - "source": [] - } - ], - "metadata": { - "colab": { - "include_colab_link": true, - "name": "SMT_DesignSpace_example.ipynb", - "provenance": [] - }, - "kernelspec": { - "display_name": "Python 3 (ipykernel)", - "language": "python", - "name": "python3" - }, - "language_info": { - "codemirror_mode": { - "name": "ipython", - "version": 3 - }, - "file_extension": ".py", - "mimetype": "text/x-python", - "name": "python", - "nbconvert_exporter": "python", - "pygments_lexer": "ipython3", - "version": "3.9.18" - } - }, - "nbformat": 4, - "nbformat_minor": 4 -} diff --git a/tutorial/README.md b/tutorial/README.md index 0b930db30..55b104680 100644 --- a/tutorial/README.md +++ b/tutorial/README.md @@ -72,10 +72,6 @@ These tutorials introduce to use the opensource Surrogate Modeling Toolbox where [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/SMTorg/smt/blob/master/tutorial/MixedInteger/RunTestCases_Paper_SMT_v2.ipynb) -### DesignSpace to variables (continuous, discrete, categorical, hierarchical) - -[![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/SMTorg/smt/blob/master/tutorial/MixedInteger/SMT_DesignSpace_example.ipynb) - ### Mixed-Integer Gaussian Process and Bayesian Optimization to solve unconstrained problems with mixed variables (continuous, discrete, categorical) [![Open In Colab](https://colab.research.google.com/assets/colab-badge.svg)](https://colab.research.google.com/github/SMTorg/smt/blob/master/tutorial/MixedInteger/SMT_MixedInteger.ipynb) From 5e471fc54d851e4c4406fe5dd016f04c3b75acea Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Thu, 26 Sep 2024 11:29:27 +0200 Subject: [PATCH 64/77] rename adsg to dsg --- smt/design_space/tests/test_design_space.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smt/design_space/tests/test_design_space.py b/smt/design_space/tests/test_design_space.py index a325d5123..f458ff9c7 100644 --- a/smt/design_space/tests/test_design_space.py +++ b/smt/design_space/tests/test_design_space.py @@ -23,7 +23,7 @@ IntegerVariable, OrdinalVariable, DesignSpace, - ArchDesignSpaceGraph, + DesignSpaceGraph, ) else: HAS_ADSG = False @@ -835,7 +835,7 @@ def test_adsg_to_legacy(self): ), design_space.is_conditionally_acting, ) - design_space2 = ArchDesignSpaceGraph(adsg=adsg) + design_space2 = DesignSpaceGraph(adsg=adsg) np.testing.assert_array_equal( np.array( [ From 75d797b79d9e333f026be92c33e5705ed3c87226 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Thu, 26 Sep 2024 17:10:47 +0200 Subject: [PATCH 65/77] update init --- smt/design_space/__init__.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/smt/design_space/__init__.py b/smt/design_space/__init__.py index e59c1503c..2e5fdaa18 100644 --- a/smt/design_space/__init__.py +++ b/smt/design_space/__init__.py @@ -34,10 +34,10 @@ ) if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ArchDesignSpaceGraph + from SMTDesignSpace.design_space import DesignSpaceGraph else: - class ArchDesignSpaceGraph: + class DesignSpaceGraph: pass From 70ed02ff1dcfd52169e1d9c53f6cc42c547163f9 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Mon, 30 Sep 2024 16:55:12 +0200 Subject: [PATCH 66/77] improve the code --- .coveragerc | 3 --- .github/workflows/tests_minimal.yml | 3 +-- smt/design_space/__init__.py | 6 +++--- smt/design_space/tests/test_design_space.py | 2 +- smt/design_space/tests/test_design_space_local.py | 6 +++--- 5 files changed, 8 insertions(+), 12 deletions(-) diff --git a/.coveragerc b/.coveragerc index b53ea88bf..e33a113f6 100644 --- a/.coveragerc +++ b/.coveragerc @@ -12,6 +12,3 @@ omit = */examples/* */__init__.py */setup.py - -[report] -show_missing = True \ No newline at end of file diff --git a/.github/workflows/tests_minimal.yml b/.github/workflows/tests_minimal.yml index 80d36c6aa..98b1f30eb 100644 --- a/.github/workflows/tests_minimal.yml +++ b/.github/workflows/tests_minimal.yml @@ -21,8 +21,7 @@ jobs: pip install --upgrade pip pip install numpy cython pip install -e . - pip install -r requirements.txt - + - name: Test with pytest run: | pip install pytest diff --git a/smt/design_space/__init__.py b/smt/design_space/__init__.py index 2e5fdaa18..184ab2b2b 100644 --- a/smt/design_space/__init__.py +++ b/smt/design_space/__init__.py @@ -1,6 +1,6 @@ import importlib -spec = importlib.util.find_spec("SMTDesignSpace") +spec = importlib.util.find_spec("smt_design_space") if spec: HAS_SMTDesignSpace = True HAS_CONFIG_SPACE = True @@ -12,7 +12,7 @@ if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import ( + from smt_design_space.design_space import ( CategoricalVariable, DesignSpace, BaseDesignSpace, @@ -34,7 +34,7 @@ ) if HAS_SMTDesignSpace: - from SMTDesignSpace.design_space import DesignSpaceGraph + from smt_design_space.design_space import DesignSpaceGraph else: class DesignSpaceGraph: diff --git a/smt/design_space/tests/test_design_space.py b/smt/design_space/tests/test_design_space.py index f458ff9c7..914da17f4 100644 --- a/smt/design_space/tests/test_design_space.py +++ b/smt/design_space/tests/test_design_space.py @@ -11,7 +11,7 @@ from smt.sampling_methods import LHS import os -if os.getenv("FORCE_RUN_LOCAL"): +if os.getenv("FORCE_RUN_PLAIN_BASICS"): import smt.design_space as ds from smt.design_space import ( HAS_CONFIG_SPACE, diff --git a/smt/design_space/tests/test_design_space_local.py b/smt/design_space/tests/test_design_space_local.py index 0a8173cac..c70901748 100644 --- a/smt/design_space/tests/test_design_space_local.py +++ b/smt/design_space/tests/test_design_space_local.py @@ -1,20 +1,20 @@ import unittest import os -os.environ["FORCE_RUN_LOCAL"] = "1" +os.environ["FORCE_RUN_PLAIN_BASICS"] = "1" from test_design_space import Test # Import the existing test class class TestDSLocal(Test): def test_design_variables(self): - os.environ["FORCE_RUN_LOCAL"] = "1" + os.environ["FORCE_RUN_PLAIN_BASICS"] = "1" # Load all tests from test_design_space.py loader = unittest.TestLoader() suite = loader.discover(start_dir=".", pattern="test_design_space.py") # Run the tests runner = unittest.TextTestRunner() runner.run(suite) - del os.environ["FORCE_RUN_LOCAL"] + del os.environ["FORCE_RUN_PLAIN_BASICS"] if __name__ == "__main__": From 96c15b5bacb7bddf73af85091465c703ac316c63 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Mon, 30 Sep 2024 17:20:50 +0200 Subject: [PATCH 67/77] remove old smtdesignspace --- smt/design_space/design_space.py | 6 ++++-- smt/design_space/tests/test_design_space.py | 2 +- smt/surrogate_models/krg.py | 1 - 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/smt/design_space/design_space.py b/smt/design_space/design_space.py index d7ea25ced..caf25dd71 100644 --- a/smt/design_space/design_space.py +++ b/smt/design_space/design_space.py @@ -9,7 +9,7 @@ from smt.sampling_methods.lhs import LHS from typing import List, Optional, Sequence, Tuple, Union -spec = importlib.util.find_spec("SMTDesignSpace") +spec = importlib.util.find_spec("smt_design_space") if spec: HAS_SMTDesignSpace = True HAS_CONFIG_SPACE = True @@ -639,7 +639,9 @@ def __repr__(self): def raise_config_space(): - raise RuntimeError("Dependencies are not installed, please install SMTDesignSpace.") + raise RuntimeError( + "Dependencies are not installed, please install smt_design_space." + ) class DesignSpace(BaseDesignSpace): diff --git a/smt/design_space/tests/test_design_space.py b/smt/design_space/tests/test_design_space.py index 914da17f4..75ad30988 100644 --- a/smt/design_space/tests/test_design_space.py +++ b/smt/design_space/tests/test_design_space.py @@ -707,7 +707,7 @@ def test_restrictive_value_constraint_categorical(self): ) def test_adsg_to_legacy(self): from adsg_core import BasicADSG, NamedNode, DesignVariableNode - from SMTDesignSpace.design_space import ensure_design_space + from smt_design_space.design_space import ensure_design_space from adsg_core import GraphProcessor # Create the ADSG diff --git a/smt/surrogate_models/krg.py b/smt/surrogate_models/krg.py index 69ec35dab..cddd921ae 100644 --- a/smt/surrogate_models/krg.py +++ b/smt/surrogate_models/krg.py @@ -9,7 +9,6 @@ from smt.kernels import Kernel - class KRG(KrgBased): name = "Kriging" From 5c02088e00d6e3ff266bbe47de80eb0ca6129e1a Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 1 Oct 2024 09:40:20 +0200 Subject: [PATCH 68/77] fix srtup --- setup.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/setup.py b/setup.py index 75cafb3fa..ae64ef838 100644 --- a/setup.py +++ b/setup.py @@ -107,6 +107,8 @@ "smt.sampling_methods", "smt.utils", "smt.applications", + "smt.design_space", + "smt.kernels", ], install_requires=[ "scikit-learn", From aff6f196f5f75d5c2bfef063af35aea553bd730d Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 1 Oct 2024 09:53:44 +0200 Subject: [PATCH 69/77] try for better init --- smt/__init__.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/smt/__init__.py b/smt/__init__.py index 2614ce9d9..1cce59f99 100644 --- a/smt/__init__.py +++ b/smt/__init__.py @@ -1 +1,9 @@ +import glob + __version__ = "2.7.0" + +modules = glob.glob(join(dirname(__file__), "*.py")) +__all__ = [ + basename(f)[:-3] for f in modules if isfile(f) and not f.endswith("__init__.py") +] +repo_root = os.path.abspath(os.path.dirname(__file__)) From 206f8fe5e76f3df93d458f5a7d1530aea78c668a Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 1 Oct 2024 09:57:49 +0200 Subject: [PATCH 70/77] try for better init --- smt/__init__.py | 1 + 1 file changed, 1 insertion(+) diff --git a/smt/__init__.py b/smt/__init__.py index 1cce59f99..ab8202bf3 100644 --- a/smt/__init__.py +++ b/smt/__init__.py @@ -1,4 +1,5 @@ import glob +from os.path import join __version__ = "2.7.0" From 86ed356de39ed2795f87390690d4066903fa0d21 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 1 Oct 2024 09:59:44 +0200 Subject: [PATCH 71/77] try for better init --- smt/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/smt/__init__.py b/smt/__init__.py index ab8202bf3..dde1a8880 100644 --- a/smt/__init__.py +++ b/smt/__init__.py @@ -1,5 +1,5 @@ import glob -from os.path import join +from os.path import join, dirname __version__ = "2.7.0" From 44ae42fe22dfb269f020618df794aecde61e723a Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 1 Oct 2024 10:10:49 +0200 Subject: [PATCH 72/77] try for better init --- smt/__init__.py | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/smt/__init__.py b/smt/__init__.py index dde1a8880..52c7a8c77 100644 --- a/smt/__init__.py +++ b/smt/__init__.py @@ -1,10 +1,12 @@ -import glob -from os.path import join, dirname - __version__ = "2.7.0" -modules = glob.glob(join(dirname(__file__), "*.py")) +import .surrogate_models +import .kernels +import .design_space +import .applications __all__ = [ - basename(f)[:-3] for f in modules if isfile(f) and not f.endswith("__init__.py") + "surrogate_models", + "kernels", + "design_space", + "applications", ] -repo_root = os.path.abspath(os.path.dirname(__file__)) From fd2483d5c2920380100246421d1442ce14288fc5 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 1 Oct 2024 10:16:12 +0200 Subject: [PATCH 73/77] try for better init --- smt/__init__.py | 23 ++++++++++++++++++----- 1 file changed, 18 insertions(+), 5 deletions(-) diff --git a/smt/__init__.py b/smt/__init__.py index 52c7a8c77..03b5527d8 100644 --- a/smt/__init__.py +++ b/smt/__init__.py @@ -1,12 +1,25 @@ __version__ = "2.7.0" -import .surrogate_models -import .kernels -import .design_space -import .applications +import smt.surrogate_models +import smt.kernels +import smt.design_space +import smt.examples +import smt.sampling_methods +import smt.applications +import smt.utils +import smt.tests +import smt.src +import smt.problems + __all__ = [ - "surrogate_models", + "surrogate_models", "kernels", "design_space", "applications", + "examples", + "sampling_methods", + "utils", + "tests", + "src", + "problems", ] From 0b93b8343fdf9afc1955656a654eaff470f582a8 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 1 Oct 2024 10:20:31 +0200 Subject: [PATCH 74/77] try for better init --- smt/__init__.py | 11 ----------- 1 file changed, 11 deletions(-) diff --git a/smt/__init__.py b/smt/__init__.py index 03b5527d8..ad074fa58 100644 --- a/smt/__init__.py +++ b/smt/__init__.py @@ -1,16 +1,5 @@ __version__ = "2.7.0" -import smt.surrogate_models -import smt.kernels -import smt.design_space -import smt.examples -import smt.sampling_methods -import smt.applications -import smt.utils -import smt.tests -import smt.src -import smt.problems - __all__ = [ "surrogate_models", "kernels", From 6eb4b0f9eaa6edadf991097151e8a28d9c2a74c6 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 1 Oct 2024 17:03:28 +0200 Subject: [PATCH 75/77] rename repo --- .github/workflows/tests_coverage.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tests_coverage.yml b/.github/workflows/tests_coverage.yml index 559d13413..4407ddc93 100644 --- a/.github/workflows/tests_coverage.yml +++ b/.github/workflows/tests_coverage.yml @@ -27,7 +27,7 @@ jobs: - name: Install dependencies run: | pip install --upgrade pip - pip install -r requirements.txt numpy==1.26.4 ConfigSpace==0.6.1 adsg-core==1.1.1 git+https://github.com/SMTorg/smt-design-space + pip install -r requirements.txt numpy==1.26.4 ConfigSpace==0.6.1 adsg-core==1.1.1 git+https://github.com/SMTorg/smt-design-space-ext pip list pip install -e . From ae1d794804b6514db351b7fc905e7a219cfd973a Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Tue, 1 Oct 2024 17:13:00 +0200 Subject: [PATCH 76/77] change boolean name --- smt/design_space/__init__.py | 10 +++++----- smt/design_space/design_space.py | 4 ++-- smt/design_space/tests/test_design_space.py | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/smt/design_space/__init__.py b/smt/design_space/__init__.py index 184ab2b2b..fa0ef40c8 100644 --- a/smt/design_space/__init__.py +++ b/smt/design_space/__init__.py @@ -2,16 +2,16 @@ spec = importlib.util.find_spec("smt_design_space") if spec: - HAS_SMTDesignSpace = True + HAS_DESIGN_SPACE_EXT = True HAS_CONFIG_SPACE = True HAS_ADSG = True else: - HAS_SMTDesignSpace = False + HAS_DESIGN_SPACE_EXT = False HAS_CONFIG_SPACE = False HAS_ADSG = False -if HAS_SMTDesignSpace: +if HAS_DESIGN_SPACE_EXT: from smt_design_space.design_space import ( CategoricalVariable, DesignSpace, @@ -33,7 +33,7 @@ BaseDesignSpace, ) -if HAS_SMTDesignSpace: +if HAS_DESIGN_SPACE_EXT: from smt_design_space.design_space import DesignSpaceGraph else: @@ -42,7 +42,7 @@ class DesignSpaceGraph: __all__ = [ - "HAS_SMTDesignSpace", + "HAS_DESIGN_SPACE_EXT", "HAS_CONFIG_SPACE", "HAS_ADSG", "BaseDesignSpace", diff --git a/smt/design_space/design_space.py b/smt/design_space/design_space.py index caf25dd71..fee836194 100644 --- a/smt/design_space/design_space.py +++ b/smt/design_space/design_space.py @@ -11,11 +11,11 @@ spec = importlib.util.find_spec("smt_design_space") if spec: - HAS_SMTDesignSpace = True + HAS_DESIGN_SPACE_EXT = True HAS_CONFIG_SPACE = True HAS_ADSG = True else: - HAS_SMTDesignSpace = False + HAS_DESIGN_SPACE_EXT = False HAS_CONFIG_SPACE = False HAS_ADSG = False spec = importlib.util.find_spec("adsg-core") diff --git a/smt/design_space/tests/test_design_space.py b/smt/design_space/tests/test_design_space.py index 75ad30988..7348427bd 100644 --- a/smt/design_space/tests/test_design_space.py +++ b/smt/design_space/tests/test_design_space.py @@ -16,7 +16,7 @@ from smt.design_space import ( HAS_CONFIG_SPACE, HAS_ADSG, - HAS_SMTDesignSpace, + HAS_DESIGN_SPACE_EXT, BaseDesignSpace, CategoricalVariable, FloatVariable, @@ -27,7 +27,7 @@ ) else: HAS_ADSG = False - HAS_SMTDesignSpace = False + HAS_DESIGN_SPACE_EXT = False HAS_CONFIG_SPACE = False import smt.design_space.design_space as ds from smt.design_space.design_space import ( @@ -702,7 +702,7 @@ def test_restrictive_value_constraint_categorical(self): ) @unittest.skipIf( - not (HAS_SMTDesignSpace), + not (HAS_DESIGN_SPACE_EXT), "Architecture Design Space Graph or ConfigSpace not installed.", ) def test_adsg_to_legacy(self): From 69037ae0210e7bd872712c3a8fcec1475dc7a262 Mon Sep 17 00:00:00 2001 From: Paul-Saves Date: Wed, 2 Oct 2024 11:02:06 +0200 Subject: [PATCH 77/77] update name of bool --- smt/design_space/tests/test_design_space.py | 24 +++++++++---------- .../tests/test_design_space_local.py | 6 ++--- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/smt/design_space/tests/test_design_space.py b/smt/design_space/tests/test_design_space.py index 7348427bd..5dc18314e 100644 --- a/smt/design_space/tests/test_design_space.py +++ b/smt/design_space/tests/test_design_space.py @@ -11,32 +11,32 @@ from smt.sampling_methods import LHS import os -if os.getenv("FORCE_RUN_PLAIN_BASICS"): - import smt.design_space as ds - from smt.design_space import ( - HAS_CONFIG_SPACE, - HAS_ADSG, - HAS_DESIGN_SPACE_EXT, +if not (os.getenv("RUN_PLAIN_DESIGN_SPACE_TEST")): + HAS_ADSG = False + HAS_DESIGN_SPACE_EXT = False + HAS_CONFIG_SPACE = False + import smt.design_space.design_space as ds + from smt.design_space.design_space import ( BaseDesignSpace, CategoricalVariable, FloatVariable, IntegerVariable, OrdinalVariable, DesignSpace, - DesignSpaceGraph, ) else: - HAS_ADSG = False - HAS_DESIGN_SPACE_EXT = False - HAS_CONFIG_SPACE = False - import smt.design_space.design_space as ds - from smt.design_space.design_space import ( + import smt.design_space as ds + from smt.design_space import ( + HAS_CONFIG_SPACE, + HAS_ADSG, + HAS_DESIGN_SPACE_EXT, BaseDesignSpace, CategoricalVariable, FloatVariable, IntegerVariable, OrdinalVariable, DesignSpace, + DesignSpaceGraph, ) diff --git a/smt/design_space/tests/test_design_space_local.py b/smt/design_space/tests/test_design_space_local.py index c70901748..61a775e9d 100644 --- a/smt/design_space/tests/test_design_space_local.py +++ b/smt/design_space/tests/test_design_space_local.py @@ -1,20 +1,20 @@ import unittest import os -os.environ["FORCE_RUN_PLAIN_BASICS"] = "1" +os.environ["RUN_PLAIN_DESIGN_SPACE_TEST"] = "1" from test_design_space import Test # Import the existing test class class TestDSLocal(Test): def test_design_variables(self): - os.environ["FORCE_RUN_PLAIN_BASICS"] = "1" + os.environ["RUN_PLAIN_DESIGN_SPACE_TEST"] = "1" # Load all tests from test_design_space.py loader = unittest.TestLoader() suite = loader.discover(start_dir=".", pattern="test_design_space.py") # Run the tests runner = unittest.TextTestRunner() runner.run(suite) - del os.environ["FORCE_RUN_PLAIN_BASICS"] + del os.environ["RUN_PLAIN_DESIGN_SPACE_TEST"] if __name__ == "__main__":