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 VOCS
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!
from xopt.vocs import form_objective_data, form_constraint_data, form_feasibility_data
import pandas as pd
import numpy as np
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
from xopt.vocs import form_objective_data, form_constraint_data, form_feasibility_data
import pandas as pd
import numpy as np
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 | 389.034192 | -0.934125 | 1234 | 388.100067 | 389.968318 | 776.200134 | 779.936636 |
6 | 936.811016 | -0.916698 | 1234 | 935.894318 | 937.727714 | 1871.788636 | 1875.455428 |
7 | 177.681378 | -0.324009 | 1234 | 177.357368 | 178.005387 | 354.714737 | 356.010774 |
8 | 859.688021 | -0.703519 | 1234 | 858.984502 | 860.391540 | 1717.969004 | 1720.783080 |
9 | 398.767047 | 0.010787 | 1234 | 398.777835 | 398.756260 | 797.555670 | 797.512520 |
10 | 136.568258 | -0.690382 | 1234 | 135.877876 | 137.258640 | 271.755753 | 274.517281 |
11 | 261.359759 | 0.864270 | 1234 | 262.224030 | 260.495489 | 524.448060 | 520.990978 |
12 | 148.238487 | -0.967087 | 1234 | 147.271399 | 149.205574 | 294.542798 | 298.411148 |
13 | 262.084438 | 0.946883 | 1234 | 263.031321 | 261.137554 | 526.062642 | 522.275109 |
14 | 463.003605 | -0.432295 | 1234 | 462.571310 | 463.435899 | 925.142621 | 926.871799 |
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 | -388.100067 | 389.968318 |
6 | -935.894318 | 937.727714 |
7 | -177.357368 | 178.005387 |
8 | -858.984502 | 860.391540 |
9 | -398.777835 | 398.756260 |
10 | -135.877876 | 137.258640 |
11 | -262.224030 | 260.495489 |
12 | -147.271399 | 149.205574 |
13 | -263.031321 | 261.137554 |
14 | -462.571310 | 463.435899 |
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 | -388.100067 | 389.968318 |
6 | -935.894318 | 937.727714 |
7 | -177.357368 | 178.005387 |
8 | -858.984502 | 860.391540 |
9 | -398.777835 | 398.756260 |
10 | -135.877876 | 137.258640 |
11 | -262.224030 | 260.495489 |
12 | -147.271399 | 149.205574 |
13 | -263.031321 | 261.137554 |
14 | -462.571310 | 463.435899 |
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([[-388.10006705, 389.96831786], [-935.89431802, 937.72771396], [-177.35736831, 178.00538678], [-858.98450209, 860.39154003], [-398.77783491, 398.75625993], [-135.87787638, 137.25864029], [-262.22402976, 260.49548922], [-147.27139924, 149.20557378], [-263.03132082, 261.13755442], [-462.57131026, 463.43589936]])
In [14]:
Copied!
vocs.constraint_data(data)
vocs.constraint_data(data)
Out[14]:
constraint_e | constraint_f | |
---|---|---|
5 | 774.200134 | -779.936636 |
6 | 1869.788636 | -1875.455428 |
7 | 352.714737 | -356.010774 |
8 | 1715.969004 | -1720.783080 |
9 | 795.555670 | -797.512520 |
10 | 269.755753 | -274.517281 |
11 | 522.448060 | -520.990978 |
12 | 292.542798 | -298.411148 |
13 | 524.062642 | -522.275109 |
14 | 923.142621 | -926.871799 |
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.389034 | 0.032937 |
6 | 0.936811 | 0.041651 |
7 | 0.177681 | 0.337995 |
8 | 0.859688 | 0.148241 |
9 | 0.398767 | 0.505394 |
10 | 0.136568 | 0.154809 |
11 | 0.261360 | 0.932135 |
12 | 0.148238 | 0.016456 |
13 | 0.262084 | 0.973442 |
14 | 0.463004 | 0.283853 |
In [17]:
Copied!
# and denormalize
vocs.denormalize_inputs(normed_data)
# and denormalize
vocs.denormalize_inputs(normed_data)
Out[17]:
a | b | |
---|---|---|
5 | 389.034192 | -0.934125 |
6 | 936.811016 | -0.916698 |
7 | 177.681378 | -0.324009 |
8 | 859.688021 | -0.703519 |
9 | 398.767047 | 0.010787 |
10 | 136.568258 | -0.690382 |
11 | 261.359759 | 0.864270 |
12 | 148.238487 | -0.967087 |
13 | 262.084438 | 0.946883 |
14 | 463.003605 | -0.432295 |
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 |