bayes opt water acc
This commit is contained in:
1 parent
1690651127
commit
3d35371a22
2 files changed
+1162
-794
No files matched your search
+325
-794
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,837 @@
|
|||||||
|
{
|
||||||
|
"cells": [
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 67,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"import pandas as pd\n",
|
||||||
|
"from sklearn import preprocessing\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"import GPy\n",
|
||||||
|
"from scipy import stats\n",
|
||||||
|
"from scipy import optimize\n",
|
||||||
|
"import matplotlib.pyplot as plt\n",
|
||||||
|
"from tqdm import tqdm\n",
|
||||||
|
"from functools import partial\n",
|
||||||
|
"import matplotlib.pyplot as plt\n",
|
||||||
|
"import numpy as np\n",
|
||||||
|
"from anastruct.basic import converge\n",
|
||||||
|
"from anastruct.material.profile import HEA, IPE\n",
|
||||||
|
"from anastruct.fem.system import SystemElements, Vertex\n",
|
||||||
|
"from anastruct.material.units import to_kNm2, to_kN\n",
|
||||||
|
"import anastruct"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 70,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"# anastruct version == anastruct==1.1.0a1"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Bayesian Optimization for water accumulation analysis\n",
|
||||||
|
"\n",
|
||||||
|
"See these posts:\n",
|
||||||
|
"\n",
|
||||||
|
"* [water accumulation](https://www.ritchievink.com/blog/2017/08/23/a-nonlinear-water-accumulation-analysis-in-python/)\n",
|
||||||
|
"* [bayesian optimization](https://www.ritchievink.com/blog/2019/08/25/algorithm-breakdown-bayesian-optimization/)\n",
|
||||||
|
"\n",
|
||||||
|
"For optimization purposes we make the `structure` function take the following inputs:\n",
|
||||||
|
"\n",
|
||||||
|
"* mp_span_1\n",
|
||||||
|
"* mp_span_2\n",
|
||||||
|
"* mp_span_3\n",
|
||||||
|
"* k1\n",
|
||||||
|
"* k2\n",
|
||||||
|
"\n",
|
||||||
|
"These parameters will be optimized within the following boundaries:\n",
|
||||||
|
"\n",
|
||||||
|
"```python\n",
|
||||||
|
"{'mp_span_1': {'range': [70, 91], 'type': 'float'},\n",
|
||||||
|
" 'mp_span_2': {'range': [240, 312], 'type': 'float'},\n",
|
||||||
|
" 'mp_span_3': {'range': [25, 32], 'type': 'float'},\n",
|
||||||
|
" 'k1': {'range': [2000, 2600], 'type': 'float'},\n",
|
||||||
|
" 'k2': {'range': [3000, 3900], 'type': 'float'}}\n",
|
||||||
|
"```\n",
|
||||||
|
"\n",
|
||||||
|
"The stiffness of the rotation is assumed to be linearly increasing with `mp`. See the `structure` function;\n",
|
||||||
|
"\n",
|
||||||
|
"```python\n",
|
||||||
|
" first = dict(spring={1: 9e3 / 70 * mp_span_1}, mp={1: mp_span_1})\n",
|
||||||
|
"```\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 56,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"\n",
|
||||||
|
"# constants\n",
|
||||||
|
"E = 2.1e5 / 1.3\n",
|
||||||
|
"b = 5 * 1.09\n",
|
||||||
|
"q_water = 10\n",
|
||||||
|
"\n",
|
||||||
|
"# axes height levels\n",
|
||||||
|
"h_1 = 0\n",
|
||||||
|
"h_2 = 0.258\n",
|
||||||
|
"h_3 = 0.046\n",
|
||||||
|
"h_4 = 0.274\n",
|
||||||
|
"h_5 = 0.032\n",
|
||||||
|
"h_6 = 0.15\n",
|
||||||
|
"\n",
|
||||||
|
"# beam spans\n",
|
||||||
|
"span_1 = span_2 = 21.9\n",
|
||||||
|
"span_3 = 8.9\n",
|
||||||
|
"\n",
|
||||||
|
"# Vertices at the axes\n",
|
||||||
|
"p1 = Vertex(0, h_1)\n",
|
||||||
|
"p2 = Vertex(span_1 * 0.5, h_2)\n",
|
||||||
|
"p3 = Vertex(span_1, h_3)\n",
|
||||||
|
"p4 = Vertex(span_1 + span_2 * 0.5, h_4)\n",
|
||||||
|
"p5 = Vertex(span_1 + span_2, h_5)\n",
|
||||||
|
"p6 = Vertex(span_1 + span_2 + span_3, h_6)\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"def structure(\n",
|
||||||
|
" mp_span_1=70,\n",
|
||||||
|
" mp_span_2=240,\n",
|
||||||
|
" mp_span_3=25,\n",
|
||||||
|
" k1=2e3,\n",
|
||||||
|
" k2=3e3,\n",
|
||||||
|
"):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Build the structure from left to right, starting at axis 1.\n",
|
||||||
|
"\n",
|
||||||
|
" variables:\n",
|
||||||
|
" EA = Young's modulus * Area\n",
|
||||||
|
" EI = Young's modulus * moment of Inertia\n",
|
||||||
|
" g = Weight [kN/ m]\n",
|
||||||
|
" elements = reference of the element id's that were created\n",
|
||||||
|
" dl = c.t.c distance different nodes.\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
" dl = 0.2\n",
|
||||||
|
"\n",
|
||||||
|
" ## SPAN 1 AND 2\n",
|
||||||
|
"\n",
|
||||||
|
" # The elements between axis 1 and 3 are an IPE 450 member.\n",
|
||||||
|
" EA = to_kN(E * IPE[450][\"A\"]) # Y\n",
|
||||||
|
" EI = to_kNm2(E * IPE[450][\"Iy\"])\n",
|
||||||
|
" g = IPE[450][\"G\"] / 100\n",
|
||||||
|
"\n",
|
||||||
|
" # New system.\n",
|
||||||
|
" ss = SystemElements(mesh=3)\n",
|
||||||
|
"\n",
|
||||||
|
" # span 1\n",
|
||||||
|
" first = dict(spring={1: 9e3 / 70 * mp_span_1}, mp={1: mp_span_1})\n",
|
||||||
|
"\n",
|
||||||
|
" elements = ss.add_multiple_elements(\n",
|
||||||
|
" location=[p1, p2], dl=dl, first=first, EA=EA, EI=EI, g=g\n",
|
||||||
|
" )\n",
|
||||||
|
" elements += ss.add_multiple_elements(location=p3, dl=dl, EA=EA, EI=EI, g=g)\n",
|
||||||
|
"\n",
|
||||||
|
" # span 2\n",
|
||||||
|
" first = dict(spring={1: 40e3 / 240 * mp_span_2}, mp={1: mp_span_2})\n",
|
||||||
|
" elements += ss.add_multiple_elements(\n",
|
||||||
|
" location=p4, dl=dl, first=first, EA=EA, EI=EI, g=g\n",
|
||||||
|
" )\n",
|
||||||
|
" elements += ss.add_multiple_elements(location=p5, dl=dl, EA=EA, EI=EI, g=g)\n",
|
||||||
|
"\n",
|
||||||
|
" ## SPAN 3\n",
|
||||||
|
"\n",
|
||||||
|
" # span 3\n",
|
||||||
|
" # different IPE\n",
|
||||||
|
" g = IPE[240][\"G\"] / 100\n",
|
||||||
|
" EA = to_kN(E * IPE[240][\"A\"])\n",
|
||||||
|
" EI = to_kNm2(E * IPE[240][\"Iy\"])\n",
|
||||||
|
" first = dict(spring={1: 15e3 / 25 * mp_span_3}, mp={1: mp_span_3})\n",
|
||||||
|
"\n",
|
||||||
|
" elements += ss.add_multiple_elements(\n",
|
||||||
|
" location=p6, first=first, dl=dl, EA=EA, EI=EI, g=g\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" # Add a dead load of -2 kN/m to all elements.\n",
|
||||||
|
" ss.q_load(-2, elements, direction=\"y\")\n",
|
||||||
|
"\n",
|
||||||
|
" ## COLUMNS\n",
|
||||||
|
"\n",
|
||||||
|
" # column height\n",
|
||||||
|
" h = 7.2\n",
|
||||||
|
"\n",
|
||||||
|
" # left column\n",
|
||||||
|
" EA = to_kN(E * IPE[220][\"A\"])\n",
|
||||||
|
" EI = to_kNm2(E * HEA[220][\"Iy\"])\n",
|
||||||
|
" left = ss.add_element([[0, 0], [0, -h]], EA=EA, EI=EI)\n",
|
||||||
|
"\n",
|
||||||
|
" # right column\n",
|
||||||
|
" EA = to_kN(E * IPE[180][\"A\"])\n",
|
||||||
|
" EI = to_kNm2(E * HEA[180][\"Iy\"])\n",
|
||||||
|
" right = ss.add_element([p6, Vertex(p6.x, -h)], EA=EA, EI=EI)\n",
|
||||||
|
"\n",
|
||||||
|
" ## SUPPORTS\n",
|
||||||
|
"\n",
|
||||||
|
" # node ids for the support\n",
|
||||||
|
" id_left = max(ss.element_map[left].node_map.keys())\n",
|
||||||
|
" id_top_right = min(ss.element_map[right].node_map.keys())\n",
|
||||||
|
" id_btm_right = max(ss.element_map[right].node_map.keys())\n",
|
||||||
|
"\n",
|
||||||
|
" # Add supports. The location of the supports is defined with the nodes id.\n",
|
||||||
|
" ss.add_support_hinged((id_left, id_btm_right))\n",
|
||||||
|
"\n",
|
||||||
|
" # Retrieve the node ids at axis 2 and 3\n",
|
||||||
|
" id_p3 = ss.find_node_id(p3)\n",
|
||||||
|
" id_p5 = ss.find_node_id(p5)\n",
|
||||||
|
"\n",
|
||||||
|
" ss.add_support_roll(id_top_right, direction=1)\n",
|
||||||
|
"\n",
|
||||||
|
" # Add translational spring supports at axes 2 and 3\n",
|
||||||
|
" ss.add_support_spring(id_p3, translation=2, k=k1, roll=True)\n",
|
||||||
|
" ss.add_support_spring(id_p5, translation=2, k=k2, roll=True)\n",
|
||||||
|
" return ss\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"def water_load(ss, water_height, deflection=None):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" :param ss: (SystemElements) object.\n",
|
||||||
|
" :param water_height: (flt) Water level.\n",
|
||||||
|
" :param deflection: (array) Computed deflection.\n",
|
||||||
|
" :return (flt) The cubic meters of water on the structure\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
" # The horizontal distance between the nodes.\n",
|
||||||
|
" dl = np.diff(ss.nodes_range(\"x\"))\n",
|
||||||
|
"\n",
|
||||||
|
" if deflection is None:\n",
|
||||||
|
" deflection = np.zeros(len(ss.node_map))\n",
|
||||||
|
"\n",
|
||||||
|
" # Height of the nodes\n",
|
||||||
|
" y = np.array(ss.nodes_range(\"y\"))\n",
|
||||||
|
"\n",
|
||||||
|
" # An array with point loads.\n",
|
||||||
|
" # cubic meters * weight water\n",
|
||||||
|
" force_water = (water_height - y[:-3] - deflection[:-3]) * q_water * b * dl[:-2]\n",
|
||||||
|
"\n",
|
||||||
|
" cubics = 0\n",
|
||||||
|
" n = force_water.shape[0]\n",
|
||||||
|
" for k in ss.node_map:\n",
|
||||||
|
" if k > n:\n",
|
||||||
|
" break\n",
|
||||||
|
" point_load = force_water[k - 1]\n",
|
||||||
|
"\n",
|
||||||
|
" if point_load > 0:\n",
|
||||||
|
" ss.point_load(k, Fx=0, Fy=-point_load)\n",
|
||||||
|
" cubics += point_load / q_water\n",
|
||||||
|
"\n",
|
||||||
|
" return cubics\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"def det_water_height(c, deflection=None, hyperparams={}):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" :param c: (flt) Cubic meters.\n",
|
||||||
|
" :param deflection: (array) Node deflection values.\n",
|
||||||
|
" :return (SystemElement, flt) The structure and the redistributed water level is returned.\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" wh = 0.1\n",
|
||||||
|
"\n",
|
||||||
|
" while True:\n",
|
||||||
|
" ss = structure(**hyperparams)\n",
|
||||||
|
" cubics = water_load(ss, wh, deflection)\n",
|
||||||
|
"\n",
|
||||||
|
" factor = converge(cubics, c)\n",
|
||||||
|
" if 0.9999 <= factor <= 1.0001:\n",
|
||||||
|
" return ss, wh\n",
|
||||||
|
"\n",
|
||||||
|
" wh *= factor\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"def determine_max_water_cubic(hyper_params, return_ss=False):\n",
|
||||||
|
" cubics = [0]\n",
|
||||||
|
" water_heights = [0]\n",
|
||||||
|
"\n",
|
||||||
|
" deflection = None\n",
|
||||||
|
" max_water_level = 0\n",
|
||||||
|
"\n",
|
||||||
|
" # Iterate from 8 m3 to 15 m3 of water.\n",
|
||||||
|
" for cubic in reversed(\n",
|
||||||
|
" (14 - np.logspace(0, 1, 35)[:-10])\n",
|
||||||
|
" ): # This loop computes the results per m3 of storaged water.\n",
|
||||||
|
" wh = 0.05\n",
|
||||||
|
" lastwh = 0.2\n",
|
||||||
|
"\n",
|
||||||
|
" print(f\"Starting analysis of {cubic} m3\")\n",
|
||||||
|
"\n",
|
||||||
|
" c = 1\n",
|
||||||
|
" for _ in range(100): # This loop redistributes the water until the water level converges.\n",
|
||||||
|
"\n",
|
||||||
|
" # redistribute the water\n",
|
||||||
|
" ss, wh = det_water_height(cubic, deflection, hyper_params)\n",
|
||||||
|
"\n",
|
||||||
|
" # Do a non linear calculation!!\n",
|
||||||
|
" ss.solve(max_iter=100, verbosity=1)\n",
|
||||||
|
" deflection = ss.get_node_result_range(\"uy\")\n",
|
||||||
|
"\n",
|
||||||
|
" # Some breaking conditions\n",
|
||||||
|
" if min(deflection) < -1:\n",
|
||||||
|
" print(min(deflection), \"Breaking due to exceeding max deflection\")\n",
|
||||||
|
" break\n",
|
||||||
|
" if 0.9999 < lastwh / wh < 1.001:\n",
|
||||||
|
" print(f\"Convergence in {c} iterations.\")\n",
|
||||||
|
" cubics.append(cubic)\n",
|
||||||
|
" water_heights.append(wh)\n",
|
||||||
|
" break\n",
|
||||||
|
"\n",
|
||||||
|
" lastwh = wh\n",
|
||||||
|
" c += 1\n",
|
||||||
|
"\n",
|
||||||
|
" if wh > max_water_level:\n",
|
||||||
|
" max_water_level = wh\n",
|
||||||
|
" else:\n",
|
||||||
|
" print(\"Breaking. Water level isn't rising.\")\n",
|
||||||
|
" break\n",
|
||||||
|
" \n",
|
||||||
|
" if return_ss:\n",
|
||||||
|
" return ss, cubics, water_heights\n",
|
||||||
|
" \n",
|
||||||
|
" return max_water_level\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 14,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"\n",
|
||||||
|
"def select_hyperparams_random(param_ranges):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Select hyperparameters at random.\n",
|
||||||
|
" \n",
|
||||||
|
" Parameters\n",
|
||||||
|
" ----------\n",
|
||||||
|
" param_ranges : dict\n",
|
||||||
|
" Named parameter ranges.\n",
|
||||||
|
"\n",
|
||||||
|
" Example:\n",
|
||||||
|
" \n",
|
||||||
|
" {\n",
|
||||||
|
" 'foo': {\n",
|
||||||
|
" 'range': [1, 10],\n",
|
||||||
|
" 'type': 'float'\n",
|
||||||
|
" }\n",
|
||||||
|
" 'bar': {\n",
|
||||||
|
" 'range': [10, 1000],\n",
|
||||||
|
" 'type': 'int'\n",
|
||||||
|
" }\n",
|
||||||
|
" }\n",
|
||||||
|
"\n",
|
||||||
|
" Returns\n",
|
||||||
|
" -------\n",
|
||||||
|
" selection : dict\n",
|
||||||
|
" Randomly selected hyperparameters within given boundaries.\n",
|
||||||
|
" \n",
|
||||||
|
" Example:\n",
|
||||||
|
" {'foo': 4.213, 'bar': 935}\n",
|
||||||
|
"\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" selection = {}\n",
|
||||||
|
" for k in param_ranges:\n",
|
||||||
|
" val = np.random.choice(\n",
|
||||||
|
" np.linspace(*param_ranges[k]['range'], num=100)\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" dtype = param_ranges[k]['type']\n",
|
||||||
|
" if dtype is 'int':\n",
|
||||||
|
" val = int(val)\n",
|
||||||
|
" selection[k] = val\n",
|
||||||
|
" return selection\n",
|
||||||
|
"\n",
|
||||||
|
"\n",
|
||||||
|
"def expected_improvement(f, y_current, x_proposed):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Return E(max(f_proposed - f_current), 0)\n",
|
||||||
|
"\n",
|
||||||
|
" Parameters\n",
|
||||||
|
" ----------\n",
|
||||||
|
"\n",
|
||||||
|
" f : GP predict function\n",
|
||||||
|
" y_current : float\n",
|
||||||
|
" Current best evaluation f(x+)\n",
|
||||||
|
" x_proposed : np.array\n",
|
||||||
|
" Proposal parameters. Shape: (1, 1)\n",
|
||||||
|
"\n",
|
||||||
|
" Returns\n",
|
||||||
|
" -------\n",
|
||||||
|
" expected_improvement : float\n",
|
||||||
|
" E(max(f_proposed - f_current), 0)\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" mu, var = f(x_proposed)\n",
|
||||||
|
" std = var ** 0.5\n",
|
||||||
|
" delta = mu - y_current\n",
|
||||||
|
"\n",
|
||||||
|
" # x / inf = 0\n",
|
||||||
|
" std[std == 0] = np.inf\n",
|
||||||
|
" z = delta / std\n",
|
||||||
|
" unit_norm = stats.norm()\n",
|
||||||
|
" return delta * unit_norm.cdf(z) + std * unit_norm.pdf(z)\n"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 15,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"class BayesOpt:\n",
|
||||||
|
" def __init__(\n",
|
||||||
|
" self, param_ranges, f, random_trials=5, optimization_trials=20, kernel=None\n",
|
||||||
|
" ):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Parameters\n",
|
||||||
|
" ----------\n",
|
||||||
|
"\n",
|
||||||
|
" param_ranges : dict\n",
|
||||||
|
" f : function\n",
|
||||||
|
" black box function to evaluate\n",
|
||||||
|
" random_trials : int\n",
|
||||||
|
" Number of random trials to run before optimization starts\n",
|
||||||
|
" optimization_trials : int\n",
|
||||||
|
" Number of optimization trials to run.\n",
|
||||||
|
" Together with the random_trials this is the total budget\n",
|
||||||
|
" kernel: GPy.kern.src.kern.Kern\n",
|
||||||
|
" GPy kernel for the Gaussian Process.\n",
|
||||||
|
" If None given, RBF kernel is used\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" self.param_ranges = param_ranges\n",
|
||||||
|
" self.f = f\n",
|
||||||
|
" self.random_trials = random_trials\n",
|
||||||
|
" self.optimization_trials = optimization_trials\n",
|
||||||
|
" self.n_trials = random_trials + optimization_trials\n",
|
||||||
|
" self.x = np.zeros((self.n_trials, len(param_ranges)))\n",
|
||||||
|
" self.y = np.zeros((self.n_trials, 1))\n",
|
||||||
|
"\n",
|
||||||
|
" if kernel is None:\n",
|
||||||
|
" self.kernel = GPy.kern.RBF(\n",
|
||||||
|
" input_dim=self.x.shape[1], variance=1, lengthscale=1\n",
|
||||||
|
" )\n",
|
||||||
|
" else:\n",
|
||||||
|
" self.kernel = kernel\n",
|
||||||
|
" self.gp = None\n",
|
||||||
|
" self.bounds = np.array([pr[\"range\"] for pr in param_ranges.values()])\n",
|
||||||
|
"\n",
|
||||||
|
" @property\n",
|
||||||
|
" def best_params(self):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Select best parameters.\n",
|
||||||
|
"\n",
|
||||||
|
" Returns\n",
|
||||||
|
" -------\n",
|
||||||
|
" best_parameters : dict\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" return self._prepare_kwargs(self.x[self.y.argmax()])\n",
|
||||||
|
"\n",
|
||||||
|
" def fit(self):\n",
|
||||||
|
" self._random_search()\n",
|
||||||
|
" self._bayesian_search()\n",
|
||||||
|
"\n",
|
||||||
|
" def _random_search(self):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Run the random trials budget\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" print(f\"Starting {self.random_trials} random trials...\")\n",
|
||||||
|
" for i in tqdm(range(self.random_trials)):\n",
|
||||||
|
" hp = select_hyperparams_random(self.param_ranges)\n",
|
||||||
|
" self.x[i] = np.array(list(hp.values()))\n",
|
||||||
|
" self.y[i] = self.f(hp)\n",
|
||||||
|
" print(f'HP: {hp}\\t y:{self.y[i]}')\n",
|
||||||
|
"\n",
|
||||||
|
" def _bayesian_search(self):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Run the Bayesian Optimization budget\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" print(f\"Starting {self.optimization_trials} optimization trials...\")\n",
|
||||||
|
" for i in tqdm(\n",
|
||||||
|
" range(self.random_trials, self.random_trials + self.optimization_trials)\n",
|
||||||
|
" ):\n",
|
||||||
|
" self.x[i], self.y[i] = self._single_iter()\n",
|
||||||
|
"\n",
|
||||||
|
" def _single_iter(self, x=None):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Fit a GP and retrieve and evaluate a new\n",
|
||||||
|
" parameter proposal.\n",
|
||||||
|
"\n",
|
||||||
|
" Returns\n",
|
||||||
|
" -------\n",
|
||||||
|
" out : tuple[np.array[flt], np.array[flt]]\n",
|
||||||
|
" (x, f(x))\n",
|
||||||
|
"\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" self._fit_gp()\n",
|
||||||
|
" if x is None:\n",
|
||||||
|
" x = self._new_proposal()\n",
|
||||||
|
" y = self.f(self._prepare_kwargs(x))\n",
|
||||||
|
" print(f'HP: {self._prepare_kwargs(x)}\\t y:{y}')\n",
|
||||||
|
" return x, y\n",
|
||||||
|
"\n",
|
||||||
|
" def _fit_gp(self, noise_var=0):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Fit a GP on the currently observed data points.\n",
|
||||||
|
"\n",
|
||||||
|
" Parameters\n",
|
||||||
|
" ----------\n",
|
||||||
|
" noise_var : flt\n",
|
||||||
|
" GPY argmument noise_var\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" mask = self.x.sum(axis=1) != 0\n",
|
||||||
|
" self.gp = GPy.models.GPRegression(\n",
|
||||||
|
" self.x[mask],\n",
|
||||||
|
" self.y[mask],\n",
|
||||||
|
" normalizer=True,\n",
|
||||||
|
" kernel=self.kernel,\n",
|
||||||
|
" noise_var=noise_var,\n",
|
||||||
|
" )\n",
|
||||||
|
" self.gp.optimize()\n",
|
||||||
|
"\n",
|
||||||
|
" def _new_proposal(self, n=25):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Get a new parameter proposal by maximizing\n",
|
||||||
|
" the acquisition function.\n",
|
||||||
|
"\n",
|
||||||
|
" Parameters\n",
|
||||||
|
" ----------\n",
|
||||||
|
" n : int\n",
|
||||||
|
" Number of retries.\n",
|
||||||
|
" Each new retry the optimization is\n",
|
||||||
|
" started in another parameter location.\n",
|
||||||
|
" This improves the chance of finding a global optimum.\n",
|
||||||
|
"\n",
|
||||||
|
" Returns\n",
|
||||||
|
" -------\n",
|
||||||
|
" proposal : dict\n",
|
||||||
|
" Example:\n",
|
||||||
|
" {'foo': 4.213, 'bar': 935}\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
"\n",
|
||||||
|
" def f(x):\n",
|
||||||
|
" return -expected_improvement(\n",
|
||||||
|
" f=self.gp.predict, y_current=self.y.max(), x_proposed=x[None, :]\n",
|
||||||
|
" )\n",
|
||||||
|
"\n",
|
||||||
|
" x0 = np.random.uniform(\n",
|
||||||
|
" low=self.bounds[:, 0], high=self.bounds[:, 1], size=(n, self.x.shape[1])\n",
|
||||||
|
" )\n",
|
||||||
|
" proposal = None\n",
|
||||||
|
" best_ei = np.inf\n",
|
||||||
|
" for x0_ in x0:\n",
|
||||||
|
" res = optimize.minimize(f, x0_, bounds=self.bounds)\n",
|
||||||
|
" if res.success and res.fun < best_ei:\n",
|
||||||
|
" best_ei = res.fun\n",
|
||||||
|
" proposal = res.x\n",
|
||||||
|
" if np.isnan(res.fun):\n",
|
||||||
|
" raise ValueError(\"NaN within bounds\")\n",
|
||||||
|
" return proposal\n",
|
||||||
|
"\n",
|
||||||
|
" def _prepare_kwargs(self, x):\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" Create a dictionary with named parameters\n",
|
||||||
|
" and the proper python types.\n",
|
||||||
|
"\n",
|
||||||
|
" Parameters\n",
|
||||||
|
" ----------\n",
|
||||||
|
" x : np.array\n",
|
||||||
|
" Example:\n",
|
||||||
|
" [4.213, 935.03]\n",
|
||||||
|
"\n",
|
||||||
|
" Returns\n",
|
||||||
|
" -------\n",
|
||||||
|
" hyperparameters : dict\n",
|
||||||
|
"\n",
|
||||||
|
" Example:\n",
|
||||||
|
" {'foo': 4.213, 'bar': 935}\n",
|
||||||
|
" \"\"\"\n",
|
||||||
|
" # create hyper parameter dict\n",
|
||||||
|
" hp = dict(zip(self.param_ranges.keys(), x))\n",
|
||||||
|
" # cast values\n",
|
||||||
|
" for k in self.param_ranges:\n",
|
||||||
|
" if self.param_ranges[k][\"type\"] == \"int\":\n",
|
||||||
|
" hp[k] = int(hp[k])\n",
|
||||||
|
" elif self.param_ranges[k][\"type\"] == \"float\":\n",
|
||||||
|
" hp[k] = float(hp[k])\n",
|
||||||
|
" else:\n",
|
||||||
|
" raise ValueError(\"Parameter type not known\")\n",
|
||||||
|
" return hp"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 16,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"maximum_factor = 1.3\n",
|
||||||
|
"\n",
|
||||||
|
"param_ranges = {\n",
|
||||||
|
" 'mp_span_1': {\n",
|
||||||
|
" 'range': [70, int(70 * maximum_factor)],\n",
|
||||||
|
" 'type': 'float'\n",
|
||||||
|
" },\n",
|
||||||
|
" 'mp_span_2': {\n",
|
||||||
|
" 'range': [240, int(240 * maximum_factor)],\n",
|
||||||
|
" 'type': 'float'\n",
|
||||||
|
" },\n",
|
||||||
|
" 'mp_span_3': {\n",
|
||||||
|
" 'range': [25, int(25 * maximum_factor)],\n",
|
||||||
|
" 'type': 'float'\n",
|
||||||
|
" },\n",
|
||||||
|
" 'k1': {\n",
|
||||||
|
" 'range': [2000, int(2000 * maximum_factor)],\n",
|
||||||
|
" 'type': 'float'\n",
|
||||||
|
" },\n",
|
||||||
|
" 'k2': {\n",
|
||||||
|
" 'range': [3000, int(3000 * maximum_factor)],\n",
|
||||||
|
" 'type': 'float'\n",
|
||||||
|
" }\n",
|
||||||
|
"}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": [
|
||||||
|
"bo = BayesOpt(param_ranges, \n",
|
||||||
|
" determine_max_water_cubic, \n",
|
||||||
|
" random_trials=5, \n",
|
||||||
|
" optimization_trials=15, \n",
|
||||||
|
" kernel=GPy.kern.Matern52(input_dim=3) + GPy.kern.Matern32(input_dim=3))\n",
|
||||||
|
"bo.fit()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "markdown",
|
||||||
|
"metadata": {},
|
||||||
|
"source": [
|
||||||
|
"# Results"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 50,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"{'mp_span_1': 79.73448251348799,\n",
|
||||||
|
" 'mp_span_2': 265.11052593961267,\n",
|
||||||
|
" 'mp_span_3': 29.237956757987163,\n",
|
||||||
|
" 'k1': 2570.259044964325,\n",
|
||||||
|
" 'k2': 3443.585144096509}"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 50,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"bo.best_params"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 51,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"Text(0.5, 0, 'iterations')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 51,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 432x288 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"plt.title('Maximum value after n iterations')\n",
|
||||||
|
"plt.plot(np.maximum.accumulate(bo.y))\n",
|
||||||
|
"plt.ylabel('Reached water level')\n",
|
||||||
|
"plt.xlabel('iterations')"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 53,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"<matplotlib.collections.PathCollection at 0x7ff625609358>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 53,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 432x288 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"plt.scatter(np.arange(bo.y.shape[0]), bo.y)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 59,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"name": "stdout",
|
||||||
|
"output_type": "stream",
|
||||||
|
"text": [
|
||||||
|
"Starting analysis of 8.919781953086979 m3\n",
|
||||||
|
"Convergence in 5 iterations.\n",
|
||||||
|
"Starting analysis of 9.252438621002577 m3\n",
|
||||||
|
"Convergence in 3 iterations.\n",
|
||||||
|
"Starting analysis of 9.563312669021387 m3\n",
|
||||||
|
"Convergence in 3 iterations.\n",
|
||||||
|
"Starting analysis of 9.85383044020318 m3\n",
|
||||||
|
"Convergence in 3 iterations.\n",
|
||||||
|
"Starting analysis of 10.125324879543868 m3\n",
|
||||||
|
"Convergence in 3 iterations.\n",
|
||||||
|
"Starting analysis of 10.379041649754082 m3\n",
|
||||||
|
"Convergence in 4 iterations.\n",
|
||||||
|
"Starting analysis of 10.616144846571766 m3\n",
|
||||||
|
"Convergence in 39 iterations.\n",
|
||||||
|
"Breaking. Water level isn't rising.\n"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"ss, cubics, water_heights = determine_max_water_cubic(bo.best_params, return_ss=True)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 62,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"text/plain": [
|
||||||
|
"[<matplotlib.lines.Line2D at 0x7ff62427fc18>]"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"execution_count": 62,
|
||||||
|
"metadata": {},
|
||||||
|
"output_type": "execute_result"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "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 truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 432x288 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"plt.plot(cubics, water_heights)"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": 63,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [
|
||||||
|
{
|
||||||
|
"data": {
|
||||||
|
"image/png": "iVBORw0KGgoAAAANSUhEUgAAAZAAAAEGCAYAAABLgMOSAAAABHNCSVQICAgIfAhkiAAAAAlwSFlzAAALEgAACxIB0t1+/AAAADh0RVh0U29mdHdhcmUAbWF0cGxvdGxpYiB2ZXJzaW9uMy4xLjEsIGh0dHA6Ly9tYXRwbG90bGliLm9yZy8QZhcZAAAgAElEQVR4nOydd3yV1f3H3yd7hySEBLIDAdkrBELYULe4QBkq4ACtq+vX2vHTqvXXVltbtbZCVURlioqiqFUQwgwr7BmyQwjZe9/z++O5sSG5N1ySO5Pzfr3Oi+R5zpPzaRPveb7nu4SUEoVCoVAorhUnWwtQKBQKhWOiNhCFQqFQdAq1gSgUCoWiU6gNRKFQKBSdQm0gCoVCoegULrYWYE169+4to6OjbS1DoVAoHIpDhw4VSSmD217vURtIdHQ0Bw8etLUMhUKhcCiEEFmGrqsjLIVCoVB0CrWBKBQKhaJTqA1EoVAoFJ1CbSAKhUKh6BRqA1EoFApFp1AbiEKhUCg6hdEwXiFEoAnP66SUZWbUo1AoFAoHoaM8kIv6ITqY4wxEmlWRQqGwOTqdZMPBHG4YGkqAt5ut5SjslI42kNNSytEdPSyESDWzHoVCYQd8d7qAZz45zplLlfx+9lBby1HYKR35QBJNeN6UOQqFwsFYkZwOwMZDuVTWNdpYjcJeMbqBSCnrWr4WQgQIIUYIIca0jLZzFApF9+BQVgkHs0q5a0wYVfVNbDyUa2tJCjvlqrWwhBAvAouBC0BL/1sJzLCcLIVCYSuW70jH39OVF28fRlZxDav2ZLIoMRonp47coYqeiClhvPcA/aWU06SU0/VDbR4KRTfkQmEV354u4IHEKLzdXVg8MZrM4hq+P3vZ1tIUdogpG8gJoJelhSgUCtvz9s50XJ2deCAxGoAbh4US6ufBe3sybapLYZ+YsoH8EUgVQnwjhPi8ZVhamEKhsC6FlfV8fDiPu8eEE+zrDoCrsxP3J0ax83wR5wsqbaxQYW+YsoGsAv4M/An4a6uhUCi6Eav2ZNLYrOORyTFXXJ+fEIm7i5OyQhTtMKWhVI2U8nWLK1EoFDajur6JD/Zlcf2QEGKDfa64F+jtxh2jwvjkcB6/vOE6/L1cbaRSYW+YYoHsFEL8UQiR2DaMV9H9+TQ1l19uPIqU8uqTFQ7L+gM5lNc2smxqf4P3FydFU9vYzLoD2VZWprBnTLFAWrLRJ7S6psJ4ewDNOslfvjlHXlktNw/vy7RBfWwtSWEBGpt1vLMrg3HRAYyJDDA4Z3BfPybEBvL+3iwemhSDi7Oqw6owwQJpFbo7XYXx9ix2nLtMXlktbs5OvLb1vLJCuilbjueTV1bL0imGrY8WFk+MIa+slu9OF1hJmcLeMbqBCCFuvdrDpsy5yvM3CiHOCiHShBDPGLj/MyHEKSHEMSHEViFEVKt7zUKII/qhosIswJqUbIJ93fnNzdeRml3G7rRiW0tSmBkpJct3pNM/2JuZ13VsYf5oSAjhAZ6s3J1pHXEKu6cjC+QVIcTo1n6PtgP4v84uLIRwBt4EbgKGAPOFEEPaTEsF4qWUI4CNwMut7tVKKUfpx+zO6lAYJq+slm1nLnNvfATzx0cS6ufBa1vPKSukm7ErrYhT+RUsnRJ71UxzZyfBosRoUjJKOHmx3EoKFfZMRz6QAuDVqzx/vgtrJwBpUsp0ACHEOuB24FTLBCnl963m7wPu68J6imtg/f5sJDAvIQJ3F2cem9af5z4/yd70Yib2721reQozsSI5nWBfd+4YHWbS/HviI3j123Os2pPJy3NGWlidwt7pqJjiNCP+j9bj7i6sHQbktPo+V3/NGA8BX7X63kMIcVAIsU8IcYexh4QQS/XzDhYWFnZBbs+hsVnHugM5TBsYTHiAFwD3jougj687r2/tyjuDwp44kVfOzvNFLEmKxt3F2aRn/L1cuXtsGJuOXKS4qt7CChX2jkOEUggh7gPigVdaXY6SUsYDC4C/CyEMegCllCuklPFSyvjg4GArqHV8tp6+zOXKehaO/8HlhIerM49O7c++9BJS0pUvpDvw753peLs5X/F7NoXFE6NpaNKxdr8K6e3p2HIDyQMiWn0frr92BUKIWcBvgdlSyh9eeaSUefp/04Ht/DfcWNFFVqdk0dffg2mDrtxw5ydE0tvHnTe2pdlImcJc5JbW8MWxfOYnROLveW2JgQP6+DI5rjcf7MuisVlnIYUKR8CWG8gBIE4IESOEcAPmAVdEUwkhRgPL0TaPy62uBwgh3PVf9waSaOU7UXSerOJqdp4vYt64yHax/p5uziybEsuutCIOZZXYSKHCHLyzKwMBPDgp5qpzDfFgUgwFFfV8deKSeYUpHIqrbiBCiLsMjJlCiC5llUkpm4AngG+A08AGKeVJIcQLQoiWqKpXAB/gozbhuoOBg0KIo8D3wJ+klGoDMQNr9+fg7CS4d1yEwfsLJ0QS5O3Ga1uVFeKolNc0sv5ADreN7Ee/Xp6d+hlTBwYT09ub93ZnmFmdwpEwJRP9IbTWtS0RUdOAQ0CMEOIFKeUHnV1cSrkF2NLm2rOtvp5l5Lk9wPDOrqswTH1TMx8dzGHW4D6E+nsYnOPl5sIjU2L501dnSM0uZbSRzGWF/fJhShY1Dc0snRJrfJJOB4dWwpA7wDuo3W0nJ8GixCh+v/kUR3PKGBmhOj70REw5wnIBBksp79ZHXQ1BK2UyHviVJcUprMs3Jwsorm5gwVWcqvdPiCLAy1X5QhyQusZmVu7OZMrAYAb39TM+8dSn8OXPYOdfjE65e2w4Pu4urFRWSI/FlA0kQkrZunbBZf21EqDRMrIUtmD1viwiAj2ZPKDjPA9vdxcenhzLtjOXOZZbZiV1CnPwaWoeRVX1PNqh9dEM2/+sfX1kNTTWGpzm6+HK3Phwvjyez+WKOguoVdg7pmwg24UQXwghFgkhFgGf6a95A+rTo5uQdrmKlIwSFiREmdT7+oHEKPw9XXld+UIcBp1O8u/kdIaF+ZHYv/2x1A+c+ASKzsK4h6GuHE5+anTqosRomnSSD1NUSG9PxJQN5HHgPWCUfrwPPC6lrJZSTregNoUVWZOSjauzYG58uEnzfT1ceWhSDN+dLuBEnipr4Qh8e7qA9KJqlk7pjxBGXhJ0zbDjT9BnKNz0MgTFwcGVRn9mdG9vZgzqw5qULOqbmi2kXGGvmFKNV0opN0opf6ofG6UqiNStqGtsZuOhHG4YGkpvH3eTn1s0MRpfDxf+oXwhDsGK5HTCAzy5eVio8UnH1kNxGkx7BpycIf5ByN0Pl44bfWRJUgxFVQ18cTTfAqoV9oypYbznhRDlQogKIUSlEKLCGuIU1uGLY/lU1DVdc0ayv6crS5Ji+PrkJU7nqz8Je+ZgZgmHskp5uKNeHk0NsP2P0HckDL5NuzZyHji7d2iFJA0IIq6PDyv3ZKhimz0MU46wXkZL5POXUvpJKX2llB2EbygcjTUpWcQGezMhNvCan30wKRofd2WF2DvLk9Pp5eXKPUbyewBI/QDKsmHG/0LLEZdXIAy7C45tgPoqg48JIVicFM2JvAoOZZVaQL3CXjFlAymQUp62uBKFTTh1sYLD2WUsHB9l/Fy8A3p5ubF4YjRbTuRzrqDSAgoVXSXtchXfnirggQlReLkZSf1qrIXkVyBiAgxok34V/yA0VMKJjUbXuHN0GH4eLqpXSA/DlA3koBBivRBifutsdIsrU1iFNfuzcHNx4u4xppXzNsRDk2LwdHVWVoid8vbOdNxdnHhgYrTxSQffhcp8mPG7/1ofLYSPg5BhcOAdMHJE5eXmwvyESL4+eYmLZYbDfhXdD1M2ED+gBrgeuE0/utSJUGEfVNc3sSn1IreO6EsvL7dO/5wAbzceSIxm87GLpF02fMyhsA2XK+v45HAec8aGGw+QqK+Cna9C7DSImdz+vhAwdjFcOgYXDxtd6/7EKKSUfLAvyxzSFQ6AKVFYSwyMB60hTmFZPj96kar6a3eeG+KRyTF4uDjz5vfKCrEn3tudSaNOx8OTO0gcTHkLaoo034cxRtwLrt4dOtPDA7y4fkgoa/dnU9ugQnp7Ah31RP+l/t83hBCvtx3Wk6iwBFJKPtyXxXWhvoyJ7HodoyAfd+5PjOKzI3lkFFWbQaGiq1TVN/HhvixuHBpKTG9vw5Nqy2DP6zDwJgiPN/7DPPxg+Bw48bH2jBGWJEVTVtPIZ0fadWZQdEM6skBaHOcH0Yonth0KB+ZYbjknL1awcHxkp5znhnhkciyuzk7KCrET1u3PpqKuqeOiiXv/oWWbT//N1X9g/BJorNEisoyQEBPI4L5+rNydqUJ6ewAdtbTdrP+yRkq5qvVA84koHJjVKVl4uTmb3AvbFIJ93Vk4PopPU/PIKlZWiC1pbNbx7q4MEqIDjVdMri6Cff+CoXdC3xFX/6H9Rmvj4LtGnelCCJYkRXO2oJK9qnNlt8cUJ/qvTbymcBDKaxvZfDSf20f1w9fj2rrRXY1lU2NxdhL88/sLZv25imvjy2P5XCyvY9nUDqyPXX/TLIppJlgfLcQ/CIWnISfF6JTZI/sR6O2mQnp7AB35QG4SQrwBhLXxf7wHNFlNocLsbErNo7axmQUJXXeetyXEz4MFCZF8fDiXnBJlqNoCKSVv7bjAgD4+TB9kpO9bRT4ceBtGzIPggab/8GF3g7ufZoUYwcPVmQUJkXx3uoDsYvU30J3pyAK5iOb/qONK38fnwA2Wl6awBFJKVqdkMSLcn+Hh/hZZY9nUWJyE4F87lBViC3aeL+LMpUqWTo41Xlk5+RXQNcG0a2zp4+atRWSd3AQ1xtsa3zchCmcheH9v5rX9fIVD0ZEP5Kje3zGgjQ/kEymlqlfgoBzMKuVcQRULx0dabI2+/p7cMy6cjw7mkKeSyqzOiuR0+vi6c/vofoYnlGbC4fdhzAMQEH3tC8Q/CM31WukTI4T6e3DT8L6sP5hLine truncated
|
||||||
|
"text/plain": [
|
||||||
|
"<Figure size 432x288 with 1 Axes>"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
"metadata": {
|
||||||
|
"needs_background": "light"
|
||||||
|
},
|
||||||
|
"output_type": "display_data"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"source": [
|
||||||
|
"plt.plot(ss.nodes_range('x')[:-2], ss.nodes_range('y')[:-2])\n",
|
||||||
|
"plt.plot(ss.nodes_range('x')[:-2], [a + b for a, b in zip(ss.nodes_range('y')[:-2], ss.get_node_result_range(\"uy\")[:-2])])\n",
|
||||||
|
"\n",
|
||||||
|
"plt.ylabel(\"Height level roof when accumulating [m]\")\n",
|
||||||
|
"plt.xlabel(\"Span [m]\")\n",
|
||||||
|
"plt.show()"
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"cell_type": "code",
|
||||||
|
"execution_count": null,
|
||||||
|
"metadata": {},
|
||||||
|
"outputs": [],
|
||||||
|
"source": []
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"metadata": {
|
||||||
|
"kernelspec": {
|
||||||
|
"display_name": "Python 3",
|
||||||
|
"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.7.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"nbformat": 4,
|
||||||
|
"nbformat_minor": 2
|
||||||
|
}
|
||||||
Reference in new issue
Block a user