Utils
get_constraint_satisfaction_mask(evaluations, constraint_bounds=None)
Return boolean mask indicating which evaluations satisfy the constraints.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
evaluations |
List[blackboxopt.evaluation.Evaluation] |
List of evaluations to check. |
required |
constraint_bounds |
Optional[Dict[str, Tuple[Optional[float], Optional[float]]]] |
For each constraint name a tuple of (lower, upper) bounds. A constraint is satisfied when lower <= value <= upper, where None means no bound on that side. If None, all evaluations are considered feasible. |
None |
Returns:
| Type | Description |
|---|---|
ndarray |
Boolean numpy array with True for feasible evaluations. |
Source code in blackboxopt/visualizations/utils.py
def get_constraint_satisfaction_mask(
evaluations: List[Evaluation],
constraint_bounds: Optional[
Dict[str, Tuple[Optional[float], Optional[float]]]
] = None,
) -> np.ndarray:
"""Return boolean mask indicating which evaluations satisfy the constraints.
Args:
evaluations: List of evaluations to check.
constraint_bounds: For each constraint name a tuple of (lower, upper) bounds.
A constraint is satisfied when lower <= value <= upper, where None means
no bound on that side. If None, all evaluations are considered feasible.
Returns:
Boolean numpy array with True for feasible evaluations.
"""
if constraint_bounds is None:
return np.ones(len(evaluations), dtype=bool)
mask = np.ones(len(evaluations), dtype=bool)
for i, e in enumerate(evaluations):
if e.constraints is None:
mask[i] = False
continue
for name, (lower, upper) in constraint_bounds.items():
value = e.constraints.get(name)
if value is None:
mask[i] = False
break
if lower is not None and value < lower:
mask[i] = False
break
if upper is not None and value > upper:
mask[i] = False
break
return mask
get_incumbent_objective_over_iterations(objective, objective_values, feasible_mask)
Compute incumbent trace over iterations considering only feasible evaluations.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
objective |
Objective |
The objective specification. |
required |
objective_values |
ndarray |
Array of objective values for all evaluations. |
required |
feasible_mask |
ndarray |
Boolean mask indicating feasible evaluations. |
required |
Returns:
| Type | Description |
|---|---|
Tuple of (iterations, incumbent_values) arrays for step-line plotting. |
Source code in blackboxopt/visualizations/utils.py
def get_incumbent_objective_over_iterations(
objective: Objective,
objective_values: np.ndarray,
feasible_mask: np.ndarray,
):
"""Compute incumbent trace over iterations considering only feasible evaluations.
Args:
objective: The objective specification.
objective_values: Array of objective values for all evaluations.
feasible_mask: Boolean mask indicating feasible evaluations.
Returns:
Tuple of (iterations, incumbent_values) arrays for step-line plotting.
"""
iterations = np.arange(1, len(objective_values) + 1)
feasible_iterations = iterations[feasible_mask]
feasible_values = objective_values[feasible_mask]
if len(feasible_values) == 0:
return np.array([]), np.array([])
return _get_incumbent_trace(
objective, feasible_iterations, feasible_values, float(iterations[-1])
)
get_incumbent_objective_over_time_single_fidelity(objective, objective_values, times, fidelities, target_fidelity)
Filter for results with given target fidelity and generate incumbent trace.
Source code in blackboxopt/visualizations/utils.py
def get_incumbent_objective_over_time_single_fidelity(
objective: Objective,
objective_values: np.ndarray,
times: np.ndarray,
fidelities: np.ndarray,
target_fidelity: float,
):
"""Filter for results with given target fidelity and generate incumbent trace."""
# filter out fidelity and take min/max of objective_values
idx = np.logical_and(fidelities == target_fidelity, np.isfinite(objective_values))
return _get_incumbent_trace(
objective, times[idx], objective_values[idx], np.nanmax(times)
)
patch_plotly_io_to_html(method)
Patch plotly.io.to_html with additional javascript to improve usability.
Might become obsolete, when https://github.com/plotly/plotly.js/issues/998 gets fixed.
Injects <script>-tag with content from to_html_patch.js at the end of the HTML
output. But only, if the chart title starts with "[BBO]" (to minimize side
effects, if the user uses plotly.io for something else).
plotly.io.to_html is also internally used for figure.show() and
figure.to_html(), so this is covered, too.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method |
Callable |
Original |
required |
Returns:
| Type | Description |
|---|---|
Callable |
Patched method. |
Source code in blackboxopt/visualizations/utils.py
def patch_plotly_io_to_html(method: Callable) -> Callable:
"""Patch `plotly.io.to_html` with additional javascript to improve usability.
Might become obsolete, when https://github.com/plotly/plotly.js/issues/998 gets
fixed.
Injects `<script>`-tag with content from `to_html_patch.js` at the end of the HTML
output. But only, if the chart title starts with "[BBO]" (to minimize side
effects, if the user uses `plotly.io` for something else).
`plotly.io.to_html` is also internally used for `figure.show()` and
`figure.to_html()`, so this is covered, too.
Args:
method: Original `plotly.io.to_html` method.
Returns:
Patched method.
"""
@wraps(method)
def wrapped(*args, **kwargs):
html = method(*args, **kwargs)
# Test if title text contains "[BBO]"
if html.find('"title":{"text":"[BBO]') < 0:
return html
js = importlib.resources.read_text(
blackboxopt.visualizations, "to_html_patch.js"
)
html_to_inject = f"<script>{js}</script>"
insert_idx = html.rfind("</body>")
if insert_idx >= 0:
# Full html page got rendered, inject <script> before <\body>
html = html[:insert_idx] + html_to_inject + html[insert_idx:]
else:
# Only chart part got rendered: append <script> at the end
html = html + html_to_inject
return html
return wrapped