VOCS data structure¶
Variables, Objectives, Constraints, and other Settings (VOCS) helps define our optimization problems.
In [1]:
Copied!
from xopt.vocs import VOCS
from xopt.vocs import form_objective_data
import pandas as pd
import numpy as np
from xopt.vocs import VOCS
from xopt.vocs import form_objective_data
import pandas as pd
import numpy as np
In [2]:
Copied!
Y = """
variables:
a: [0, 1e3] # Note that 1e3 usually parses as a str with YAML.
b: [-1, 1]
objectives:
c: maximize
d: minimize
constraints:
e: ['Less_than', 2]
f: ['greater_than', 0]
constants:
g: 1234
"""
vocs = VOCS.from_yaml(Y)
vocs
Y = """
variables:
a: [0, 1e3] # Note that 1e3 usually parses as a str with YAML.
b: [-1, 1]
objectives:
c: maximize
d: minimize
constraints:
e: ['Less_than', 2]
f: ['greater_than', 0]
constants:
g: 1234
"""
vocs = VOCS.from_yaml(Y)
vocs
Out[2]:
VOCS(variables={'a': [0.0, 1000.0], 'b': [-1.0, 1.0]}, constraints={'e': ['LESS_THAN', 2.0], 'f': ['GREATER_THAN', 0.0]}, objectives={'c': 'MAXIMIZE', 'd': 'MINIMIZE'}, constants={'g': 1234}, observables=[])
In [3]:
Copied!
# as dict
dict(vocs)
# as dict
dict(vocs)
Out[3]:
{'variables': {'a': [0.0, 1000.0], 'b': [-1.0, 1.0]}, 'constraints': {'e': ['LESS_THAN', 2.0], 'f': ['GREATER_THAN', 0.0]}, 'objectives': {'c': 'MAXIMIZE', 'd': 'MINIMIZE'}, 'constants': {'g': 1234}, 'observables': []}
In [4]:
Copied!
# re-parse dict
vocs2 = VOCS.from_dict(dict(vocs))
# re-parse dict
vocs2 = VOCS.from_dict(dict(vocs))
In [5]:
Copied!
# Check that these are the same
vocs2 == vocs
# Check that these are the same
vocs2 == vocs
Out[5]:
True
In [6]:
Copied!
# This replaces the old vocs["variables"]
getattr(vocs, "variables")
# This replaces the old vocs["variables"]
getattr(vocs, "variables")
Out[6]:
{'a': [0.0, 1000.0], 'b': [-1.0, 1.0]}
In [7]:
Copied!
vocs.objectives["c"] == "MAXIMIZE"
vocs.objectives["c"] == "MAXIMIZE"
Out[7]:
True
In [8]:
Copied!
# json
vocs.to_json()
# json
vocs.to_json()
Out[8]:
'{"variables":{"a":[0.0,1000.0],"b":[-1.0,1.0]},"constraints":{"e":["LESS_THAN",2.0],"f":["GREATER_THAN",0.0]},"objectives":{"c":"MAXIMIZE","d":"MINIMIZE"},"constants":{"g":1234},"observables":[]}'
Objective Evaluation¶
In [9]:
Copied!
data = pd.DataFrame(vocs.random_inputs(10))
# Add some outputs
data["c"] = data["a"] + data["b"]
data["d"] = data["a"] - data["b"]
data["e"] = data["a"] * 2 + data["b"] * 2
data["f"] = data["a"] * 2 - data["b"] * 2
data.index = np.arange(len(data)) + 5 # custom index
data
data = pd.DataFrame(vocs.random_inputs(10))
# Add some outputs
data["c"] = data["a"] + data["b"]
data["d"] = data["a"] - data["b"]
data["e"] = data["a"] * 2 + data["b"] * 2
data["f"] = data["a"] * 2 - data["b"] * 2
data.index = np.arange(len(data)) + 5 # custom index
data
Out[9]:
a | b | g | c | d | e | f | |
---|---|---|---|---|---|---|---|
5 | 88.265550 | 0.130760 | 1234 | 88.396311 | 88.134790 | 176.792621 | 176.269580 |
6 | 514.128139 | -0.649280 | 1234 | 513.478860 | 514.777419 | 1026.957719 | 1029.554838 |
7 | 388.300575 | -0.951967 | 1234 | 387.348608 | 389.252541 | 774.697215 | 778.505083 |
8 | 808.994432 | -0.958273 | 1234 | 808.036160 | 809.952705 | 1616.072319 | 1619.905410 |
9 | 715.343610 | -0.156711 | 1234 | 715.186899 | 715.500321 | 1430.373799 | 1431.000642 |
10 | 521.458748 | 0.106343 | 1234 | 521.565091 | 521.352405 | 1043.130181 | 1042.704811 |
11 | 15.915948 | -0.431274 | 1234 | 15.484674 | 16.347222 | 30.969348 | 32.694443 |
12 | 684.997792 | 0.790394 | 1234 | 685.788186 | 684.207397 | 1371.576372 | 1368.414795 |
13 | 924.539210 | 0.918710 | 1234 | 925.457919 | 923.620500 | 1850.915839 | 1847.241000 |
14 | 692.592235 | -0.469057 | 1234 | 692.123179 | 693.061292 | 1384.246357 | 1386.122585 |
In [10]:
Copied!
vocs.objectives
vocs.objectives
Out[10]:
{'c': 'MAXIMIZE', 'd': 'MINIMIZE'}
In [11]:
Copied!
# These are in standard form for minimization
form_objective_data(vocs.objectives, data)
# These are in standard form for minimization
form_objective_data(vocs.objectives, data)
Out[11]:
objective_c | objective_d | |
---|---|---|
5 | -88.396311 | 88.134790 |
6 | -513.478860 | 514.777419 |
7 | -387.348608 | 389.252541 |
8 | -808.036160 | 809.952705 |
9 | -715.186899 | 715.500321 |
10 | -521.565091 | 521.352405 |
11 | -15.484674 | 16.347222 |
12 | -685.788186 | 684.207397 |
13 | -925.457919 | 923.620500 |
14 | -692.123179 | 693.061292 |
In [12]:
Copied!
# This is also available as a method
vocs.objective_data(data)
# This is also available as a method
vocs.objective_data(data)
Out[12]:
objective_c | objective_d | |
---|---|---|
5 | -88.396311 | 88.134790 |
6 | -513.478860 | 514.777419 |
7 | -387.348608 | 389.252541 |
8 | -808.036160 | 809.952705 |
9 | -715.186899 | 715.500321 |
10 | -521.565091 | 521.352405 |
11 | -15.484674 | 16.347222 |
12 | -685.788186 | 684.207397 |
13 | -925.457919 | 923.620500 |
14 | -692.123179 | 693.061292 |
In [13]:
Copied!
# use the to_numpy() method to convert for low level use.
vocs.objective_data(data).to_numpy()
# use the to_numpy() method to convert for low level use.
vocs.objective_data(data).to_numpy()
Out[13]:
array([[ -88.39631051, 88.13478981], [-513.47885972, 514.77741905], [-387.34860763, 389.25254146], [-808.0361596 , 809.95270489], [-715.18689947, 715.500321 ], [-521.56509071, 521.35240537], [ -15.48467381, 16.34722152], [-685.78818594, 684.20739743], [-925.45791949, 923.62049982], [-692.12317852, 693.06129245]])
In [14]:
Copied!
vocs.constraint_data(data)
vocs.constraint_data(data)
Out[14]:
constraint_e | constraint_f | |
---|---|---|
5 | 174.792621 | -176.269580 |
6 | 1024.957719 | -1029.554838 |
7 | 772.697215 | -778.505083 |
8 | 1614.072319 | -1619.905410 |
9 | 1428.373799 | -1431.000642 |
10 | 1041.130181 | -1042.704811 |
11 | 28.969348 | -32.694443 |
12 | 1369.576372 | -1368.414795 |
13 | 1848.915839 | -1847.241000 |
14 | 1382.246357 | -1386.122585 |
In [15]:
Copied!
vocs.feasibility_data(data)
vocs.feasibility_data(data)
Out[15]:
feasible_e | feasible_f | feasible | |
---|---|---|---|
5 | False | True | False |
6 | False | True | False |
7 | False | True | False |
8 | False | True | False |
9 | False | True | False |
10 | False | True | False |
11 | False | True | False |
12 | False | True | False |
13 | False | True | False |
14 | False | True | False |
In [16]:
Copied!
# normalize inputs to unit domain [0,1]
normed_data = vocs.normalize_inputs(data)
normed_data
# normalize inputs to unit domain [0,1]
normed_data = vocs.normalize_inputs(data)
normed_data
Out[16]:
a | b | |
---|---|---|
5 | 0.088266 | 0.565380 |
6 | 0.514128 | 0.175360 |
7 | 0.388301 | 0.024017 |
8 | 0.808994 | 0.020864 |
9 | 0.715344 | 0.421645 |
10 | 0.521459 | 0.553171 |
11 | 0.015916 | 0.284363 |
12 | 0.684998 | 0.895197 |
13 | 0.924539 | 0.959355 |
14 | 0.692592 | 0.265472 |
In [17]:
Copied!
# and denormalize
vocs.denormalize_inputs(normed_data)
# and denormalize
vocs.denormalize_inputs(normed_data)
Out[17]:
a | b | |
---|---|---|
5 | 88.265550 | 0.130760 |
6 | 514.128139 | -0.649280 |
7 | 388.300575 | -0.951967 |
8 | 808.994432 | -0.958273 |
9 | 715.343610 | -0.156711 |
10 | 521.458748 | 0.106343 |
11 | 15.915948 | -0.431274 |
12 | 684.997792 | 0.790394 |
13 | 924.539210 | 0.918710 |
14 | 692.592235 | -0.469057 |
Error handling¶
In [18]:
Copied!
Y = """
variables:
a: [0, 1e3] # Note that 1e3 usually parses as a str with YAML.
b: [-1, 1]
objectives:
c: maximize
d: minimize
constraints:
e: ['Less_than', 2]
f: ['greater_than', 0]
constants:
g: 1234
"""
vocs = VOCS.from_yaml(Y)
Y = """
variables:
a: [0, 1e3] # Note that 1e3 usually parses as a str with YAML.
b: [-1, 1]
objectives:
c: maximize
d: minimize
constraints:
e: ['Less_than', 2]
f: ['greater_than', 0]
constants:
g: 1234
"""
vocs = VOCS.from_yaml(Y)
In [19]:
Copied!
d = {"a": [1, 2, 3]}
df = pd.DataFrame(d)
df2 = pd.DataFrame(df).copy()
df2["b"] = np.nan
df2["b"] - 1
d = {"a": [1, 2, 3]}
df = pd.DataFrame(d)
df2 = pd.DataFrame(df).copy()
df2["b"] = np.nan
df2["b"] - 1
Out[19]:
0 NaN 1 NaN 2 NaN Name: b, dtype: float64
In [20]:
Copied!
data["a"] = np.nan
data["a"] = np.nan
In [21]:
Copied!
a = 2
def f(x=a):
return x
a = 99
f()
a = 2
def f(x=a):
return x
a = 99
f()
Out[21]:
2
In [22]:
Copied!
pd.DataFrame(6e66, index=[1, 2, 3], columns=["A"])
pd.DataFrame(6e66, index=[1, 2, 3], columns=["A"])
Out[22]:
A | |
---|---|
1 | 6.000000e+66 |
2 | 6.000000e+66 |
3 | 6.000000e+66 |
In [23]:
Copied!
# These are in standard form for minimization
data = pd.DataFrame({"c": [1, 2, 3, 4]}, index=[9, 3, 4, 5])
form_objective_data(vocs.objectives, data)
# These are in standard form for minimization
data = pd.DataFrame({"c": [1, 2, 3, 4]}, index=[9, 3, 4, 5])
form_objective_data(vocs.objectives, data)
Out[23]:
objective_c | objective_d | |
---|---|---|
9 | -1.0 | inf |
3 | -2.0 | inf |
4 | -3.0 | inf |
5 | -4.0 | inf |