Ceviche challenges

Ceviche challenges#

Visit the invrs-gym docs for the ceviche challenges.

The ceviche challenges are based on “Inverse design of photonic devices with strict foundry fabrication constraints” by M. F. Schubert et al., and the associated github repo. They entail the design of integrated photonic components such as a beam splitter, mode converter, waveguide bend, and wavelength demultiplexer (wdm).

The eval metric for ceviche challenges is defined in terms of transmission upper and lower bounds that are specified for each challenge, as follows:

Hide code cell source
from invrs_gym import challenges

challenge = challenges.ceviche_beam_splitter()
docstring = challenge.eval_metric.__doc__
print("\n".join([s[8:] for s in docstring.split("Args")[0].split("\n")[2:-2]]))
The evaluation metric is computed from a psuedodistance to the target volume
of the response space defined by the tranmission upper and lower bounds. A
psuedodistance is defined for each element in the transmission array, and is
a signed quantity with magnitude equal to the distance between a transmission
value and its target, with sign being positive when the transmission is outside
the target window, and negative inside.

The distance is scaled by the size of the target window, and the negative
maximum distance is taken as the eval metric.

Positive values indicate that the target specification has been achieved.
Hide code cell content
import os
import plotly.express as px
from IPython import display
from invrs_leaderboard import data

df = data.leaderboard_dataframe(base_path="../../../")
grid_spacing_nm = float(challenge.component.ceviche_model.params.resolution)
df["minimum_width_nm"] = df["minimum_width"] * grid_spacing_nm
df["minimum_spacing_nm"] = df["minimum_spacing"] * grid_spacing_nm
df["minimum_length_scale_nm"] = df["minimum_length_scale"] * grid_spacing_nm

def _trim_filename(name):
    return name if len(name) < 40 else name[:25] + "..." + name[-12:]

df["file"] = [_trim_filename(f) for f in df["file"]]

def plot_challenge_metrics(challenge_name: str) -> display.DisplayHandle:
    challenge_df = df[df["challenge"] == challenge_name]
    fig = px.scatter(
        challenge_df,
        x="minimum_length_scale_nm",
        y="eval_metric",
        color="file_prefix",
        hover_data=["file", "minimum_width_nm", "minimum_spacing_nm", "binarization_degree"],
    )
    if not os.path.exists("_plots/"):
        os.mkdir("_plots/")
    filename = f"_plots/eval_metric_{challenge_name}.html"
    fig.write_html(filename)
    return display.display(display.HTML(filename))
plot_challenge_metrics("ceviche_beam_splitter")
plot_challenge_metrics("ceviche_mode_converter")
plot_challenge_metrics("ceviche_power_splitter")
plot_challenge_metrics("ceviche_waveguide_bend")
plot_challenge_metrics("ceviche_wdm")