Skip to content

Commit

Permalink
tyler comments
Browse files Browse the repository at this point in the history
  • Loading branch information
yaugenst-flex committed Sep 17, 2024
1 parent b476704 commit 3fb6c51
Show file tree
Hide file tree
Showing 13 changed files with 81 additions and 44 deletions.
2 changes: 1 addition & 1 deletion CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]

### Added
- Added `tidy3d.plugins.metrics` module for constructing and serializing simulation metrics like `ModeCoefficient` and `ModePower`.
- Added `tidy3d.plugins.expressions` module for constructing and serializing mathematical expressions and simulation metrics like `ModeAmps` and `ModePower`.

## [2.7.3] - 2024-09-12

Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import numpy as np
import pytest
from tidy3d.plugins.metrics.functions import Cos, Exp, Log, Log10, Sin, Tan
from tidy3d.plugins.metrics.variables import Constant
from tidy3d.plugins.expressions.functions import Cos, Exp, Log, Log10, Sin, Tan
from tidy3d.plugins.expressions.variables import Constant

FUNCTIONS = [
(Sin, np.sin),
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@

import numpy as np
import pytest
from tidy3d.plugins.metrics.operators import (
from tidy3d.plugins.expressions.operators import (
Abs,
Add,
Divide,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import numpy as np
import pytest
from tidy3d.plugins.metrics.variables import Constant, Variable
from tidy3d.plugins.expressions.variables import Constant, Variable


@pytest.fixture(params=[1, 2.5, 1 + 2j, np.array([1, 2, 3])])
Expand Down
Original file line number Diff line number Diff line change
@@ -1,26 +1,26 @@
# Metrics module
# Expressions module

The `metrics` module provides a way to construct and serialize complex mathematical expressions involving simulation metrics in Tidy3D.
The `expressions` module provides a way to construct and serialize complex mathematical expressions involving simulation metrics in Tidy3D.
It allows users to define objective functions for optimization tasks, for example in conjunction with the `invdes` plugin.
This module is essential for creating expressions that can be easily saved, loaded, and passed between different components of a simulation workflow.

## Introduction

The `metrics` module is designed to facilitate the construction of serializable mathematical expressions involving simulation metrics like mode power, mode coefficients, field intensity, and more.
The `expressions` module is designed to facilitate the construction of serializable mathematical expressions involving simulation metrics like mode power, mode coefficients, field intensity, and more.
These expressions can be combined using standard arithmetic operators.
This functionality is important when defining objective functions for optimization routines, especially in inverse design tasks where the objective functions may need to be transmitted or stored.

## Usage

### Creating metrics

To start using the `metrics` module, you can create expressions using predefined metric classes such as `ModeCoefficient` and `ModePower`.
To start using the `expressions` module, you can create metrics using predefined metric classes such as `ModeAmp` and `ModePower`.

Metrics are a special instance of a `Variable`, which itself is a subclass of `Expression`, that take a `SimulationData` as input and are intended to return a single scalar.

```python
from tidy3d.plugins.metrics import ModeCoefficient, ModePower
from tidy3d.plugins.expressions import ModeAmp, ModePower

# Create a ModeCoefficient metric
mode_coeff = ModeCoefficient(monitor_name="monitor1", freqs=[1.0])
# Create a ModeAmp metric
mode_coeff = ModeAmp(monitor_name="monitor1", freqs=[1.0])

# Create a ModePower metric
mode_power = ModePower(monitor_name="monitor2", freqs=[1.0])
Expand All @@ -29,6 +29,7 @@ mode_power = ModePower(monitor_name="monitor2", freqs=[1.0])
### Combining metrics with operators

Metrics can be combined using standard arithmetic operators like `+`, `-`, `*`, `/`, `**`, and functions like `abs()`.
Together, they will form an `Expression`.

```python
# Define an objective function using metrics
Expand All @@ -37,15 +38,15 @@ f = abs(mode_coeff) - mode_power / 2

### Functions

The `metrics` module also provides a set of mathematical functions that can be used to create more complex expressions.
The `expressions` module also provides a set of mathematical functions that can be used to create more complex expressions.

```python
from tidy3d.plugins.metrics import Sin, Cos
from tidy3d.plugins.expressions import Sin, Cos

f = Sin(mode_coeff) + Cos(mode_power)
```

### Evaluating metrics
### Evaluating expressions

Once you have a metric, you can evaluate it using simulation data.

Expand All @@ -57,30 +58,66 @@ result = f.evaluate(data)
result = f(data)
```

### Serializing and deserializing metrics
### Serializing and deserializing expressions

Metrics can be serialized to a file using the `to_file` method and deserialized using the `from_file` class method.
Expressions can be serialized to a file using the `to_file` method and deserialized using the `from_file` class method.

```python
# Serialize the metric to a file
f.to_file("metric_expression.hdf5")

# Deserialize the metric from a file
from tidy3d.plugins.metrics import Expression
from tidy3d.plugins.expressions import Expression
loaded_expr = Expression.from_file("metric_expression.hdf5")
```

## Supported features

### Operators and functions

The `expressions` module supports various operators and functions to build complex expressions:

| Type | Name | Description | Class Name |
|------------|------------|--------------------------------------------------|------------------|
| Operator | `+` | Addition | `Add` |
| Operator | `-` | Subtraction | `Subtract` |
| Operator | `*` | Multiplication | `Multiply` |
| Operator | `/` | Division | `Divide` |
| Operator | `**` | Power | `Power` |
| Operator | `//` | Floor Division | `FloorDivide` |
| Operator | `%` | Modulus | `Modulus` |
| Operator | `@` | Matrix Multiplication | `MatMul` |
| Operator | `abs` | Absolute Value | `Abs` |
| Function | `Sin` | Sine function | `Sin` |
| Function | `Cos` | Cosine function | `Cos` |
| Function | `Tan` | Tangent function | `Tan` |
| Function | `Exp` | Exponential function | `Exp` |
| Function | `Log` | Natural logarithm function | `Log` |
| Function | `Log10` | Base-10 logarithm function | `Log10` |

### Variables and metrics

The module provides predefined metrics and variables for constructing expressions.
Metrics represent specific simulation data, while variables act as placeholders.

| Type | Name | Description |
|------------|------------|--------------------------------------------------|
| Metric | `ModeAmp` | Metric for calculating the mode coefficient |
| Metric | `ModePower`| Metric for calculating the mode power |
| Variable | `Constant` | Fixed value in expressions |
| Variable | `Variable` | Placeholder for values in expressions |

## Examples

### `ModeCoefficient` and `ModePower`
### `ModeAmp` and `ModePower`

In this example, we create metrics using only `ModeCoefficient` and `ModePower` and combine them to define an objective function.
In this example, we create metrics using only `ModeAmp` and `ModePower` and combine them to define an objective function.

```python
from tidy3d.plugins.metrics import ModeCoefficient, ModePower
from tidy3d.plugins.expressions import ModeAmp, ModePower

# Create metrics
mode_coeff = ModeCoefficient(monitor_name="monitor1", freqs=[1.0])
mode_coeff = ModeAmp(monitor_name="monitor1", freqs=[1.0])
mode_power = ModePower(monitor_name="monitor2", freqs=[1.0])

# Define an objective function using metrics
Expand All @@ -93,7 +130,7 @@ print(f)
**Expected output:**

```text
(abs(ModeCoefficient("monitor1")) - (ModePower("monitor2") / 2))
(abs(ModeAmp("monitor1")) - (ModePower("monitor2") / 2))
```

**Evaluating the expression:**
Expand All @@ -108,16 +145,16 @@ print(result)

### Using variables

The `metrics` module provides `Variable` and `Constant` classes to represent placeholders and fixed values in your expressions.
The `expressions` module provides `Variable` and `Constant` classes to represent placeholders and fixed values in your expressions.
Variables can be used to parameterize expressions, allowing you to supply values at evaluation time.
Note that a `Metric` such as `ModeCoefficient` is a subclass of `Variable`, so it can be used in the same way.
Note that a `Metric` such as `ModeAmp` is a subclass of `Variable`, so it can be used in the same way.

#### Unnamed variables (positional arguments)

If you create a `Variable` without a name, it expects its value to be provided as a single positional argument during evaluation.

```python
from tidy3d.plugins.metrics import Variable
from tidy3d.plugins.expressions import Variable

# Create an unnamed variable
x = Variable()
Expand All @@ -136,7 +173,7 @@ print(result) # Outputs: 126
If you create a `Variable` with a name, it expects its value to be provided as a keyword argument during evaluation.

```python
from tidy3d.plugins.metrics import Variable
from tidy3d.plugins.expressions import Variable

# Create named variables
x = Variable(name="x")
Expand Down Expand Up @@ -166,13 +203,13 @@ print(result) # Outputs: 25

#### A `Metric` is a `Variable`

A `Metric` such as `ModeCoefficient` is a subclass of `Variable`, so all the rules for `Variable` apply to `Metric` as well.
A `Metric` such as `ModeAmp` is a subclass of `Variable`, so all the rules for `Variable` apply to `Metric` as well.

from tidy3d.plugins.metrics import ModeCoefficient, ModePower
from tidy3d.plugins.expressions import ModeAmp, ModePower

```python
# Define two named metrics
mode_coeff1 = ModeCoefficient(name="mode_coeff1", monitor_name="monitor1", freqs=[1.0])
mode_coeff1 = ModeAmp(name="mode_coeff1", monitor_name="monitor1", freqs=[1.0])
mode_power1 = ModePower(name="mode_power1", monitor_name="monitor2", freqs=[1.0])

# Create an expression using the metrics
Expand All @@ -195,7 +232,7 @@ You should assign names to the variables and provide their values as keyword arg

## Developer notes

### Extending metrics
### Extending expressions

To implement new metrics, follow these steps:

Expand All @@ -204,7 +241,7 @@ To implement new metrics, follow these steps:
Create a new class that inherits from `Metric` and implement the required methods.

```python
from tidy3d.plugins.metrics import Metric
from tidy3d.plugins.expressions.metrics import Metric

class CustomMetric(Metric):
monitor_name: str
Expand All @@ -225,14 +262,14 @@ To implement new metrics, follow these steps:

### Extending operators

To extend the `metrics` module with additional operators:
To extend the `expressions` module with additional operators:

1. **Create a new operator class:**

Subclass `UnaryOperator` or `BinaryOperator` depending on the operator's arity.

```python
from tidy3d.plugins.metrics import BinaryOperator
from tidy3d.plugins.expressions.operators import BinaryOperator

class CustomOperator(BinaryOperator):
_symbol = "??" # Replace with the operator symbol
Expand Down Expand Up @@ -262,4 +299,4 @@ To extend the `metrics` module with additional operators:

4. **Register the operator (if necessary):**

Ensure the new operator is recognized by the serialization mechanism. If your operator introduces a new type, update any type maps or registries used in the `metrics` module.
Ensure the new operator is recognized by the serialization mechanism. If your operator introduces a new type, update any type maps or registries used in the `expressions` module.
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
from .base import Expression
from .functions import Cos, Exp, Log, Log10, Sin, Tan
from .metrics import ModeCoefficient, ModePower
from .metrics import ModeAmp, ModePower
from .variables import Constant, Variable

__all__ = [
"Expression",
"Constant",
"Variable",
"ModeCoefficient",
"ModeAmp",
"ModePower",
"Sin",
"Cos",
Expand Down
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ def __repr__(self) -> str:
return f'{self.type}("{self.monitor_name}")'


class ModeCoefficient(Metric):
class ModeAmp(Metric):
"""
Metric for calculating the mode coefficient from a ModeMonitor.
Expand All @@ -41,7 +41,7 @@ class ModeCoefficient(Metric):
Examples
--------
>>> monitor = ModeMonitor(name="monitor1", freqs=[1.0])
>>> mode_coeff = ModeCoefficient.from_mode_monitor(monitor)
>>> mode_coeff = ModeAmp.from_mode_monitor(monitor)
>>> data = SimulationData() # Assume this is a valid SimulationData object
>>> result = mode_coeff.evaluate(data)
"""
Expand Down Expand Up @@ -69,7 +69,7 @@ def evaluate(self, *args: Any, **kwargs: Any) -> NumberType:
return anp.squeeze(amps.values.tolist())


class ModePower(ModeCoefficient):
class ModePower(ModeAmp):
"""
Metric for calculating the mode power from a ModeMonitor.
Expand Down
File renamed without changes.
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

if TYPE_CHECKING:
from .functions import Cos, Exp, Log, Log10, Sin, Tan
from .metrics import ModeCoefficient, ModePower
from .metrics import ModeAmp, ModePower
from .operators import (
Abs,
Add,
Expand Down Expand Up @@ -55,7 +55,7 @@
Union[
"Constant",
"Variable",
"ModeCoefficient",
"ModeAmp",
"ModePower",
],
Field(discriminator=TYPE_TAG_STR),
Expand Down
File renamed without changes.

0 comments on commit 3fb6c51

Please sign in to comment.