From 4b43a9dc57d548510f4ca0eb646dc00aab8edaf2 Mon Sep 17 00:00:00 2001 From: Deluca Team Date: Tue, 14 Nov 2023 06:58:35 -0800 Subject: [PATCH] Update basic agents and planar quadrotor environment. PiperOrigin-RevId: 582307788 --- deluca/_src/agents/bang_bang.py | 53 +++++ deluca/_src/agents/constant.py | 45 ++++ deluca/_src/agents/pid.py | 65 ++++++ deluca/_src/agents/random.py | 59 +++++ deluca/_src/base.py | 211 ++++++++++++++++++ deluca/_src/envs/classic/planar_quadrotor.py | 151 +++++++++++++ deluca/agents/__init__.py | 2 +- deluca/agents/_adaptive.py | 2 +- deluca/agents/_bang_bang.py | 29 --- deluca/agents/_bpc.py | 2 +- deluca/agents/_deep.py | 2 +- deluca/agents/_drc.py | 2 +- deluca/agents/_gpc.py | 2 +- deluca/agents/_hinf.py | 2 +- deluca/agents/_igpc.py | 2 +- deluca/agents/_ilc.py | 2 +- deluca/agents/_ilqr.py | 2 +- deluca/agents/_lqr.py | 2 +- deluca/agents/_pid.py | 48 ---- deluca/agents/_predestined.py | 4 +- deluca/agents/_random.py | 33 --- deluca/agents/_zero.py | 28 --- deluca/core.py | 2 +- deluca/envs/__init__.py | 2 +- deluca/envs/_brax.py | 2 +- deluca/envs/_lds.py | 8 +- deluca/envs/brax/_pendulum2d.py | 2 +- deluca/envs/brax/_pendulum3d.py | 2 +- deluca/envs/classic/_acrobot.py | 2 +- deluca/envs/classic/_cartpole.py | 2 +- deluca/envs/classic/_mountain_car.py | 2 +- deluca/envs/classic/_pendulum.py | 2 +- deluca/envs/classic/_planar_quadrotor.py | 2 +- deluca/envs/classic/_reacher.py | 2 +- deluca/igpc/igpc.py | 2 +- deluca/igpc/ilc.py | 2 +- deluca/igpc/ilqr.py | 2 +- deluca/igpc/lqr_solver.py | 2 +- deluca/igpc/rollout.py | 2 +- deluca/lung/__init__.py | 2 +- deluca/lung/controllers/__init__.py | 2 +- deluca/lung/controllers/_bang_bang.py | 2 +- deluca/lung/controllers/_deep_actor_critic.py | 11 +- deluca/lung/controllers/_deep_apg.py | 9 +- deluca/lung/controllers/_deep_cnn.py | 6 +- deluca/lung/controllers/_deep_mlp.py | 6 +- deluca/lung/controllers/_expiratory.py | 2 +- deluca/lung/controllers/_pid.py | 4 +- deluca/lung/controllers/_predestined.py | 4 +- deluca/lung/controllers/_residual.py | 2 +- deluca/lung/core.py | 11 +- deluca/lung/envs/__init__.py | 2 +- deluca/lung/envs/_balloon_lung.py | 2 +- deluca/lung/envs/_delay_lung.py | 6 +- deluca/lung/envs/_learned_lung.py | 5 +- deluca/lung/envs/_single_comp_lung.py | 2 +- deluca/lung/utils/data/analyzer.py | 2 +- deluca/lung/utils/data/breath_dataset.py | 2 +- deluca/lung/utils/data/transform.py | 2 +- deluca/lung/utils/nn/__init__.py | 2 +- deluca/lung/utils/nn/cnn.py | 4 +- deluca/lung/utils/nn/lstm.py | 16 +- deluca/lung/utils/nn/mlp.py | 2 +- .../lung/utils/nn/shallow_boundary_model.py | 2 +- deluca/lung/utils/scripts/run_controller.py | 2 +- deluca/lung/utils/scripts/test_controller.py | 2 +- deluca/lung/utils/scripts/test_simulator.py | 2 +- deluca/lung/utils/scripts/train_controller.py | 2 +- deluca/lung/utils/scripts/train_simulator.py | 2 +- deluca/tests/lung/core_test.py | 2 +- deluca/tests/lung/utils/data/analyzer_test.py | 2 +- .../lung/utils/data/breath_dataset_test.py | 2 +- .../tests/lung/utils/data/transform_test.py | 2 +- .../lung/utils/scripts/run_controller_test.py | 2 +- .../utils/scripts/test_controller_test.py | 2 +- .../lung/utils/scripts/test_simulator_test.py | 2 +- .../utils/scripts/train_controller_test.py | 2 +- .../utils/scripts/train_simulator_test.py | 2 +- deluca/tests/training/ppo_run.py | 2 +- deluca/tests/training/ppo_test.py | 2 +- deluca/training/__init__.py | 2 +- deluca/training/apg.py | 2 +- deluca/training/ppo.py | 2 +- deluca/utils/__init__.py | 2 +- deluca/utils/experiment.py | 4 +- deluca/utils/planning.py | 2 +- deluca/utils/tree.py | 2 +- deluca/version.py | 2 +- plugin/setup.py | 2 +- scripts/make_plugin.py | 2 +- setup.py | 2 +- 91 files changed, 700 insertions(+), 254 deletions(-) create mode 100644 deluca/_src/agents/bang_bang.py create mode 100644 deluca/_src/agents/constant.py create mode 100644 deluca/_src/agents/pid.py create mode 100644 deluca/_src/agents/random.py create mode 100644 deluca/_src/base.py create mode 100644 deluca/_src/envs/classic/planar_quadrotor.py delete mode 100644 deluca/agents/_bang_bang.py delete mode 100644 deluca/agents/_pid.py delete mode 100644 deluca/agents/_random.py delete mode 100644 deluca/agents/_zero.py diff --git a/deluca/_src/agents/bang_bang.py b/deluca/_src/agents/bang_bang.py new file mode 100644 index 0000000..b6cecf5 --- /dev/null +++ b/deluca/_src/agents/bang_bang.py @@ -0,0 +1,53 @@ +# Copyright 2023 The Deluca Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""A bang-bang or on-off agent.""" + +import jax.numpy as jnp +from optax._src import base + + +BangBangState = base.EmptyAgentState + + +def bang_bang( + target: float | jnp.array, + min_action: float | jnp.array, + max_action: float | jnp.array, +) -> base.Agent: + """An on-off agent. + + NOTE: `target`, `min_action`, `max_action`, and `obs` must be the same shape. + + Args: + target: The target value of the agent. + min_action: The minimum or "off" action. + max_action: The maximum or "on" action. + + Returns: + A Bang Bang agent. + """ + + def init_fn(): + return BangBangState() + + def action_fn( + state: BangBangState, obs: base.EnvironmentState + ) -> tuple[BangBangState, float | jnp.array]: + return state, jnp.where(obs > target, min_action, max_action) + + def update_fn(state: BangBangState) -> BangBangState: + return state + + return base.Agent(init_fn, action_fn, update_fn) diff --git a/deluca/_src/agents/constant.py b/deluca/_src/agents/constant.py new file mode 100644 index 0000000..8cd503b --- /dev/null +++ b/deluca/_src/agents/constant.py @@ -0,0 +1,45 @@ +# Copyright 2023 The Deluca Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""A constant controller.""" + +import jax.numpy as jnp +from optax._src import base + + +def constant( + control: float | jnp.array, +) -> base.Agent: + """A controller that gives a constant response. + + Args: + control: The control to give. + + Returns: + A constant agent. + """ + + def init_fn(): + return None + + def control_fn( + state: base.AgentState, obs: base.EnvironmentState + ) -> tuple[base.AgentState, float | jnp.array]: + del obs + return state, control + + def update_fn(state: base.AgentState) -> base.AgentState: + return state + + return base.Agent(init_fn, control_fn, update_fn) diff --git a/deluca/_src/agents/pid.py b/deluca/_src/agents/pid.py new file mode 100644 index 0000000..e8fce27 --- /dev/null +++ b/deluca/_src/agents/pid.py @@ -0,0 +1,65 @@ +# Copyright 2023 The Deluca Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Vanilla PID agent.""" + +import jax.numpy as jnp +from optax._src import base + + +class PIDState(base.AgentState): + P: float + I: float + D: float + + +def pid( + kp: float, + ki: float, + kd: float, + dt: float, + rc: float = 0.0, +) -> base.Agent: + """A PID agent. + + Args: + kp: P constant. + ki: I constant. + kd: D constant. + dt: Time increment. + rc: Delay constant. + + Returns: + A constant agent. + """ + + decay = dt / (dt + rc) + + def init_fn(): + return PIDState() + + def action_fn( + state: PIDState, obs: base.EnvironmentState + ) -> tuple[PIDState, float | jnp.array]: + p = obs + i = state.I + decay * (obs - state.I) + d = state.D + decay * (obs - state.P - state.D) + + action = kp * p + ki * i + kd * d + return state.replace(P=p, I=i, D=d), action + + def update_fn(state: PIDState) -> PIDState: + return state + + return base.Agent(init_fn, action_fn, update_fn) diff --git a/deluca/_src/agents/random.py b/deluca/_src/agents/random.py new file mode 100644 index 0000000..900da52 --- /dev/null +++ b/deluca/_src/agents/random.py @@ -0,0 +1,59 @@ +# Copyright 2023 The Deluca Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""A random agent.""" + +from typing import Callable + +import jax +import jax.numpy as jnp +from optax._src import base + + +class RandomState(base.AgentState): + key: jnp.ndarray + + +def random( + key: jnp.ndarray, + shape: tuple[int, ...], + func: Callable[[jnp.ndarray, jnp.ndarray], jnp.ndarray] | None = None, +) -> base.Agent: + """An agent that outputs random actions. + + Args: + key: A `jax` key. + shape: The shape of the output actions. + func: A function that takes a key and a shape and outputs random actions. + + Returns: + A Bang Bang agent. + """ + + if func is None: + func = jax.random.uniform + + def init_fn(): + return RandomState(key=key) + + def action_fn( + state: RandomState, obs: base.EnvironmentState + ) -> tuple[RandomState, float | jnp.array]: + del obs + return state, func(state.key, shape) + + def update_fn(state: RandomState) -> RandomState: + return state.replace(key=jax.random.fold_in(key, shape)) + + return base.Agent(init_fn, action_fn, update_fn) diff --git a/deluca/_src/base.py b/deluca/_src/base.py new file mode 100644 index 0000000..bee7591 --- /dev/null +++ b/deluca/_src/base.py @@ -0,0 +1,211 @@ +# Copyright 2023 The Deluca Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Base interfaces and datatypes. + +NOTES +- Agents are not, generally speaking, interchangeable and neither are + environments. +- Agents and environments likely need to know how to interpret each others' + inputs and outputs. +- Any notion of an API is a loose one (as evidenced by the number of `*args` and + `**kwargs` in `Protocol` signatures); this API serves a more minor ergonomic + role and provides some consistency. +- There may be subsets of environments (e.g., lungs) or agents that can have a + more specific API. This should probably be encouraged. + +Questions +- Should we be able to further update agent/actionler state when getting the + action of the agent based on its state? +- Should `Environment`s action what is observable or leave that to `Agent`s to + responsibly access only what they should be allowed to? +- Should `AgentActionFn`s take `AgentState` and `EnvironmentState` or be more + permissive? +- Should we have a `state_dim` and `action_dim` property for `EnvironmentState`? +""" + +from typing import Any, NamedTuple, Protocol + + +AgentState = Any +AgentRegistry = {} +Action = Any +EnvironmentState = Any +EnvironmentRegistry = {} + + +class CostFn(Protocol): + """A callable type for the `cost` function of a task.""" + + def __call__( + self, state: EnvironmentState, action: Action, *args, **kwargs + ) -> float: + """The `cost` function. + + Args: + state: An `EnvironmentState` object. + action: An `Action` object. + *args: Arbitrary positional arguments. + **kwargs: Arbitrary keyword arguments. + + Returns: + The cost of a task. + """ + + +class AgentInitFn(Protocol): + """A callable type for the `init` step of an `Agent`. + + The `init` step takes `*args` and `**kwargs` to construct an arbitrary initial + `state` for the Agent. This may hold statistics of the past updates or any + other non-static information. + """ + + def __call__(self, *args, **kwargs) -> AgentState: + """The `init` function. + + Args: + *args: Arbitrary positional arguments. + **kwargs: Arbitrary keyword arguments. + + Returns: + The initial state of an Agent. + """ + + +class AgentActionFn(Protocol): + """A callable type for the `action` step of an `Agent`. + + The `action` step takes an `AgentState`, an `EnvironmentState`, and `*args` / + `**kwargs` and produces a possibly updated `AgentState` and a `Action`. + """ + + def __call__( + self, state: AgentState, obs: EnvironmentState, *args, **kwargs + ) -> tuple[AgentState, Action]: + """The `action` function. + + Args: + state: An `AgentState` object to update. + obs: An `EnvironmentState` object. + *args: Arbitrary positional arguments. + **kwargs: Arbitrary keyword arguments. + + Returns: + An updated `AgentState` for an `Agent` and a `Action`. + """ + + +class AgentUpdateFn(Protocol): + """A callable type for the `update` step of an `Agent`. + + The `update` step takes an `AgentState` and `*args` / `**kwargs`, typically + from the `Environment` and produces a new `AgentState`. + """ + + def __call__(self, state: AgentState, *args, **kwargs) -> AgentState: + """The `update` function. + + Args: + state: An `AgentState` object to update. + *args: Arbitrary positional arguments. + **kwargs: Arbitrary keyword arguments. + + Returns: + An updated `AgentState` for an `Agent`. + """ + + +class Agent(NamedTuple): + """A set of pure functions implementing an agent's behavior.""" + + init: AgentInitFn + action: AgentActionFn + update: AgentUpdateFn + + def __init_subclass__(cls, *args, **kwargs) -> None: + """Adds a new `Agent` subclass to the registry. + + Args: + *args: Arbitrary positional arguments. + **kwargs: Arbitrary keyword arguments. + """ + name = cls.__name__ + if name in AgentRegistry: + raise ValueError(f'Agent {name} already exists.') + AgentRegistry[name] = cls + + +class EnvironmentInitFn(Protocol): + """A callable type for the `init` step of an `Environment`. + + The `init` step takes `*args` and `**kwargs` to construct an arbitrary initial + `state` for the Environment. This may hold statistics of the past updates or + any + other non-static information. + """ + + def __call__(self, *args, **kwargs) -> EnvironmentState: + """The `init` function. + + Args: + *args: Arbitrary positional arguments. + **kwargs: Arbitrary keyword arguments. + + Returns: + The initial state of an Environment. + """ + + +class EnvironmentUpdateFn(Protocol): + """A callable type for the `update` step of an `Environment`. + + The `update` step takes an `EnvironmentState` and `*args` / `**kwargs`, + typically + from the `Environment` and produces a new `EnvironmentState`. + """ + + def __call__( + self, state: EnvironmentState, action: Any, *args, **kwargs + ) -> EnvironmentState: + """The `update` function. + + Args: + state: An `EnvironmentState` object to update. + action: An `Action` object. + *args: Arbitrary positional arguments. + **kwargs: Arbitrary keyword arguments. + + Returns: + An updated `EnvironmentState` for an `Environment`. + """ + + +class Environment(NamedTuple): + """A set of pure functions implementing an agent's behavior.""" + + init: EnvironmentInitFn + update: EnvironmentUpdateFn + + def __init_subclass__(cls, *args, **kwargs) -> None: + """Adds a new `Environment` subclass to the registry. + + Args: + *args: Arbitrary positional arguments. + **kwargs: Arbitrary keyword arguments. + """ + name = cls.__name__ + if name in EnvironmentRegistry: + raise ValueError(f'Environment {name} already exists.') + EnvironmentRegistry[name] = cls \ No newline at end of file diff --git a/deluca/_src/envs/classic/planar_quadrotor.py b/deluca/_src/envs/classic/planar_quadrotor.py new file mode 100644 index 0000000..88cb821 --- /dev/null +++ b/deluca/_src/envs/classic/planar_quadrotor.py @@ -0,0 +1,151 @@ +# Copyright 2023 The Deluca Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +# Copyright 2022 The Deluca Authors. +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +"""Planar quadrotor.""" +from typing import Protocol + +from deluca._src import base +import jax.numpy as jnp + +STATE_DIM = 6 +ACTION_DIM = 2 + + +class WindFunction(Protocol): + """A callable type for describing wind.""" + + def __call__(self, x: float, y: float): + """Wind function. + + Args: + x: Position of planar quadrotor in the x axis. + y: Position of planar quadrotor in the y axis. + + Returns: + tuple[float, float]: Wind force in the x axis and y axis, respectively. + """ + + +def make_dissipative(wind_x: float, wind_y: float): + """Make dissipative wind function. + + Args: + wind_x: Wind force in the x axis. + wind_y: Wind force in the y axis. + + Returns: + Dissipative wind function. + """ + + def dissipative(x: float, y: float): + """Dissipative wind function.""" + return wind_x * x, wind_y * y + + return dissipative + + +def make_constant( + wind_x: float = jnp.cos(jnp.pi / 4.0), wind_y: float = jnp.sin(jnp.pi / 4.0) +): + """Make constant wind function. + + Args: + wind_x: Wind force in the x axis. + wind_y: Wind force in the y axis. + + Returns: + Constant wind function. + """ + + def constant( + x: float, + y: float, + ): + """Constant wind function.""" + del x, y + return wind_x, wind_y + + return constant + + +def planar_quadrotor( + mass: float = 0.1, + length: float = 0.2, + gravity: float = 9.81, + dt: float = 0.05, + wind_fn: WindFunction = make_dissipative(wind_x=0.0, wind_y=0.0), +) -> base.Environment: + """Planar quadrotor. + + Args: + mass: Mass of planar quadrotor. + length: Overall length of planar quadrotor. + gravity: Gravity applied to quadrotor in the y axis. + dt: Time delta. + wind_fn: Function describing wind force at location (x, y). + + Returns: + A planar quadrotor environment. + """ + def init_fn( + x: float = 0.0, + y: float = 0.0, + theta: float = 0.0, + x_dot: float = 0.0, + y_dot: float = 0.0, + theta_dot: float = 0.0, + ): + """Create initial state for planar quadrotor. + + Args: + x: Position of planar quadrotor in the x axis. + y: Position of planar quadrotor in the y axis. + theta: Angle of rotation of planar quadrotor. + x_dot: Velocity of planar quadrotor in the x axis. + y_dot: Velocrity of planar quadrotor in the y axis. + theta_dot: Angular velocity of planar quadrotor + + Returns: + Initial state for planar quadrotor as a 6-dimensional array. + """ + return jnp.array([x, y, theta, x_dot, y_dot, theta_dot]) + + def update_fn(state: jnp.ndarray, action: jnp.ndarray): + x, y, theta, x_dot, y_dot, theta_dot = state + u1, u2 = action + wind_x, wind_y = wind_fn(x, y) + + x_ddot = -(u1 + u2) * jnp.sin(theta) / mass + wind_x / mass + y_ddot = (u1 + u2) * jnp.cos(theta) / mass - gravity + wind_y / mass + theta_ddot = length * (u2 - u1) / (mass * length**2) + + state_dot = jnp.array([x_dot, y_dot, theta_dot, x_ddot, y_ddot, theta_ddot]) + + return state + state_dot * dt + + return base.Environment(init_fn, update_fn) diff --git a/deluca/agents/__init__.py b/deluca/agents/__init__.py index 227b5b7..4583298 100644 --- a/deluca/agents/__init__.py +++ b/deluca/agents/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/agents/_adaptive.py b/deluca/agents/_adaptive.py index f09951f..b0333d1 100644 --- a/deluca/agents/_adaptive.py +++ b/deluca/agents/_adaptive.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/agents/_bang_bang.py b/deluca/agents/_bang_bang.py deleted file mode 100644 index 2c3eeac..0000000 --- a/deluca/agents/_bang_bang.py +++ /dev/null @@ -1,29 +0,0 @@ -# Copyright 2022 The Deluca Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from deluca.core import Agent -from deluca.core import field - - -class BangBang(Agent): - target: float = field(0.0, jaxed=False) - min_action: float = field(0.0, jaxed=False) - max_action: float = field(100.0, jaxed=False) - - def init(self): - return None - - def __call__(self, state, obs): - """Assume observation is env state""" - return state, self.min_action if obs > self.target else self.max_action diff --git a/deluca/agents/_bpc.py b/deluca/agents/_bpc.py index 3109a2e..d6a1a43 100644 --- a/deluca/agents/_bpc.py +++ b/deluca/agents/_bpc.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/agents/_deep.py b/deluca/agents/_deep.py index 1527677..ba16121 100644 --- a/deluca/agents/_deep.py +++ b/deluca/agents/_deep.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/agents/_drc.py b/deluca/agents/_drc.py index 0d0b5a7..05aa1ad 100644 --- a/deluca/agents/_drc.py +++ b/deluca/agents/_drc.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/agents/_gpc.py b/deluca/agents/_gpc.py index fc28139..565c765 100644 --- a/deluca/agents/_gpc.py +++ b/deluca/agents/_gpc.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/agents/_hinf.py b/deluca/agents/_hinf.py index 1456145..4fa028b 100644 --- a/deluca/agents/_hinf.py +++ b/deluca/agents/_hinf.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/agents/_igpc.py b/deluca/agents/_igpc.py index 2541f0e..9e17782 100644 --- a/deluca/agents/_igpc.py +++ b/deluca/agents/_igpc.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/agents/_ilc.py b/deluca/agents/_ilc.py index 870e4e9..3bccc74 100644 --- a/deluca/agents/_ilc.py +++ b/deluca/agents/_ilc.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/agents/_ilqr.py b/deluca/agents/_ilqr.py index f970577..9e3b712 100644 --- a/deluca/agents/_ilqr.py +++ b/deluca/agents/_ilqr.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/agents/_lqr.py b/deluca/agents/_lqr.py index 29eb516..5b7b8ba 100644 --- a/deluca/agents/_lqr.py +++ b/deluca/agents/_lqr.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/agents/_pid.py b/deluca/agents/_pid.py deleted file mode 100644 index 175285a..0000000 --- a/deluca/agents/_pid.py +++ /dev/null @@ -1,48 +0,0 @@ -# Copyright 2022 The Deluca Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from deluca.core import Agent -from deluca.core import field -from deluca.core import Obj - - -class PIDState(Obj): - P: float = field(0.0, jaxed=True) - I: float = field(0.0, jaxed=True) - D: float = field(0.0, jaxed=True) - - -class PID(Agent): - K_P: float = field(0.0, jaxed=True) - K_I: float = field(0.0, jaxed=True) - K_D: float = field(0.0, jaxed=True) - RC: float = field(0.5, jaxed=False) - dt: float = field(0.03, jaxed=False) - decay: float = field(jaxed=False) - - def init(self): - return PIDState() - - def setup(self): - self.decay = self.dt / (self.dt + self.RC) - - def __call__(self, state, obs): - """Assume observation is err""" - P = obs - I = state.I + self.decay * (obs - state.I) - D = state.D + self.decay * (obs - state.P - state.D) - - action = self.K_P * P + self.K_I * I + self.K_D * D - - return state.replace(P=P, I=I, D=D), action diff --git a/deluca/agents/_predestined.py b/deluca/agents/_predestined.py index b39c21a..29df830 100644 --- a/deluca/agents/_predestined.py +++ b/deluca/agents/_predestined.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -23,7 +23,7 @@ class Predestined(Agent): time: float = deluca.field(jaxed=False) steps: int = deluca.field(jaxed=False) - u: jnp.array = deluca.field(jaxed=False) + u: jnp.ndarray = deluca.field(jaxed=False) def __call__(self, state, obs, *args, **kwargs): action = jax.lax.dynamic_slice(self.u, (state.steps.astype(int),), (1,)) diff --git a/deluca/agents/_random.py b/deluca/agents/_random.py deleted file mode 100644 index 6d9caca..0000000 --- a/deluca/agents/_random.py +++ /dev/null @@ -1,33 +0,0 @@ -# Copyright 2022 The Deluca Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -from typing import Callable - -import jax - -from deluca.core import Agent -from deluca.core import field - - -class Random(Agent): - seed: int = field(0, jaxed=False) - func: Callable = field(lambda key: 0.0, jaxed=False) - - def init(self): - return jax.random.PRNGKey(self.seed) - - def __call__(self, state, obs): - key, subkey = jax.random.split(state) - - return subkey, self.func(key) diff --git a/deluca/agents/_zero.py b/deluca/agents/_zero.py deleted file mode 100644 index b599d5c..0000000 --- a/deluca/agents/_zero.py +++ /dev/null @@ -1,28 +0,0 @@ -# Copyright 2022 The Deluca Authors. -# -# Licensed under the Apache License, Version 2.0 (the "License"); -# you may not use this file except in compliance with the License. -# You may obtain a copy of the License at -# -# http://www.apache.org/licenses/LICENSE-2.0 -# -# Unless required by applicable law or agreed to in writing, software -# distributed under the License is distributed on an "AS IS" BASIS, -# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. -# See the License for the specific language governing permissions and -# limitations under the License. - -import jax.numpy as jnp - -from deluca.core import Agent -from deluca.core import field - - -class Zero(Agent): - action_dim: int = field(1, jaxed=False) - - def init(self): - return None - - def __call__(self, state, obs): - return state, jnp.zeros(self.action_dim) diff --git a/deluca/core.py b/deluca/core.py index a93467b..aa79ccf 100644 --- a/deluca/core.py +++ b/deluca/core.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/envs/__init__.py b/deluca/envs/__init__.py index 543777d..817bfac 100644 --- a/deluca/envs/__init__.py +++ b/deluca/envs/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/envs/_brax.py b/deluca/envs/_brax.py index 181f956..0936c16 100644 --- a/deluca/envs/_brax.py +++ b/deluca/envs/_brax.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/envs/_lds.py b/deluca/envs/_lds.py index 1b6e3ac..0dd97de 100644 --- a/deluca/envs/_lds.py +++ b/deluca/envs/_lds.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -21,9 +21,9 @@ class LDS(Env): """LDS.""" - A: jnp.array = field(jaxed=False) - B: jnp.array = field(jaxed=False) - C: jnp.array = field(jaxed=False) + A: jnp.ndarray = field(jaxed=False) + B: jnp.ndarray = field(jaxed=False) + C: jnp.ndarray = field(jaxed=False) key: int = field(jax.random.PRNGKey(0), jaxed=False) state_size: int = field(1, jaxed=False) action_size: int = field(1, jaxed=False) diff --git a/deluca/envs/brax/_pendulum2d.py b/deluca/envs/brax/_pendulum2d.py index a30b8d9..140beaf 100644 --- a/deluca/envs/brax/_pendulum2d.py +++ b/deluca/envs/brax/_pendulum2d.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/envs/brax/_pendulum3d.py b/deluca/envs/brax/_pendulum3d.py index f5be0a0..cfeac2b 100644 --- a/deluca/envs/brax/_pendulum3d.py +++ b/deluca/envs/brax/_pendulum3d.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/envs/classic/_acrobot.py b/deluca/envs/classic/_acrobot.py index 91bc76d..427a44a 100644 --- a/deluca/envs/classic/_acrobot.py +++ b/deluca/envs/classic/_acrobot.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/envs/classic/_cartpole.py b/deluca/envs/classic/_cartpole.py index d58131d..116a521 100644 --- a/deluca/envs/classic/_cartpole.py +++ b/deluca/envs/classic/_cartpole.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/envs/classic/_mountain_car.py b/deluca/envs/classic/_mountain_car.py index 406404d..ff2d864 100644 --- a/deluca/envs/classic/_mountain_car.py +++ b/deluca/envs/classic/_mountain_car.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/envs/classic/_pendulum.py b/deluca/envs/classic/_pendulum.py index 2dbc956..681e38e 100644 --- a/deluca/envs/classic/_pendulum.py +++ b/deluca/envs/classic/_pendulum.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/envs/classic/_planar_quadrotor.py b/deluca/envs/classic/_planar_quadrotor.py index 294c5d0..26a79f4 100644 --- a/deluca/envs/classic/_planar_quadrotor.py +++ b/deluca/envs/classic/_planar_quadrotor.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/envs/classic/_reacher.py b/deluca/envs/classic/_reacher.py index 94fccf5..16ade15 100644 --- a/deluca/envs/classic/_reacher.py +++ b/deluca/envs/classic/_reacher.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/igpc/igpc.py b/deluca/igpc/igpc.py index 591a950..98cee42 100644 --- a/deluca/igpc/igpc.py +++ b/deluca/igpc/igpc.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/igpc/ilc.py b/deluca/igpc/ilc.py index cc482c9..c7df89a 100644 --- a/deluca/igpc/ilc.py +++ b/deluca/igpc/ilc.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/igpc/ilqr.py b/deluca/igpc/ilqr.py index 49423e5..ba0ddb2 100644 --- a/deluca/igpc/ilqr.py +++ b/deluca/igpc/ilqr.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/igpc/lqr_solver.py b/deluca/igpc/lqr_solver.py index 6ea9e0a..03bca16 100644 --- a/deluca/igpc/lqr_solver.py +++ b/deluca/igpc/lqr_solver.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/igpc/rollout.py b/deluca/igpc/rollout.py index 5540b55..4c4d5f7 100644 --- a/deluca/igpc/rollout.py +++ b/deluca/igpc/rollout.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/__init__.py b/deluca/lung/__init__.py index 6d18a35..c4d21a5 100644 --- a/deluca/lung/__init__.py +++ b/deluca/lung/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/controllers/__init__.py b/deluca/lung/controllers/__init__.py index 8f7a579..b8dd09c 100644 --- a/deluca/lung/controllers/__init__.py +++ b/deluca/lung/controllers/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/controllers/_bang_bang.py b/deluca/lung/controllers/_bang_bang.py index d98cd47..323eafa 100644 --- a/deluca/lung/controllers/_bang_bang.py +++ b/deluca/lung/controllers/_bang_bang.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/controllers/_deep_actor_critic.py b/deluca/lung/controllers/_deep_actor_critic.py index 2c3fad5..f94d9bb 100644 --- a/deluca/lung/controllers/_deep_actor_critic.py +++ b/deluca/lung/controllers/_deep_actor_critic.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -79,7 +79,7 @@ def __call__(self, x): class DeepACControllerState(deluca.Obj): - errs: jnp.array + errs: jnp.ndarray key: int time: float = float('inf') steps: int = 0 @@ -89,10 +89,9 @@ class DeepACControllerState(deluca.Obj): class DeepAC(Controller): """ Class defining the conroller based on the actor critic model """ - params: list = deluca.field(jaxed=True) model: nn.module = deluca.field(ActorCritic, jaxed=False) - featurizer: jnp.array = deluca.field(jaxed=False) + featurizer: jnp.ndarray = deluca.field(jaxed=False) H: int = deluca.field(100, jaxed=False) input_dim: int = deluca.field(1, jaxed=False) history_len: int = deluca.field(10, jaxed=False) @@ -167,7 +166,7 @@ def __call__(self, controller_state, obs): errs=next_errs_expanded, key=current_key) decay = self.decay(waveform, t) log_prob, value = self.derive_prob_and_value(controller_state_big) - #value = value[0] + # value = value[0] prob = jnp.exp(log_prob) # environment step u_in = jax.random.choice(current_key, prob.shape[0], p=prob) @@ -178,7 +177,7 @@ def __call__(self, controller_state, obs): # jnp.isinf(decay), true_func, lambda x: (jnp.array(decay), None, None), None) # TODO (@namanagarwal) : Figure out what to do with clamping - #u_in = jax.lax.clamp(0.0, u_in.astype(jnp.float64), self.clip).squeeze() + # u_in = jax.lax.clamp(0.0, u_in.astype(jnp.float64), self.clip).squeeze() # update controller_state diff --git a/deluca/lung/controllers/_deep_apg.py b/deluca/lung/controllers/_deep_apg.py index 4ef0926..b6f1b82 100644 --- a/deluca/lung/controllers/_deep_apg.py +++ b/deluca/lung/controllers/_deep_apg.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -75,7 +75,7 @@ def __call__(self, x): return outputs class DeepControllerState(deluca.Obj): - errs: jnp.array + errs: jnp.ndarray key: int time: float = float('inf') steps: int = 0 @@ -85,10 +85,9 @@ class DeepControllerState(deluca.Obj): class Deep(Controller): """ Class defining the conroller based on the actor critic model """ - params: list = deluca.field(jaxed=True) model: nn.module = deluca.field(CNN, jaxed=False) - featurizer: jnp.array = deluca.field(jaxed=False) + featurizer: jnp.ndarray = deluca.field(jaxed=False) H: int = deluca.field(100, jaxed=False) input_dim: int = deluca.field(1, jaxed=False) history_len: int = deluca.field(10, jaxed=False) @@ -128,7 +127,7 @@ def setup(self, waveform=None): # TODO(dsuo): Handle dataclass initialization of jax objects def init(self, key): errs = jnp.array([0.0] * self.history_len) - #key = jax.random.PRNGKey(seed) + # key = jax.random.PRNGKey(seed) state = DeepControllerState(errs=errs, key=key) return state diff --git a/deluca/lung/controllers/_deep_cnn.py b/deluca/lung/controllers/_deep_cnn.py index b81d875..42083a1 100644 --- a/deluca/lung/controllers/_deep_cnn.py +++ b/deluca/lung/controllers/_deep_cnn.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -55,7 +55,7 @@ def __call__(self, x): class DeepControllerState(deluca.Obj): waveform: deluca.Obj # waveform can change during training - errs: jnp.array + errs: jnp.ndarray time: float = float("inf") steps: int = 0 dt: float = DEFAULT_DT @@ -65,7 +65,7 @@ class DeepCnn(Controller): """deep cnn controller.""" params: list = deluca.field(jaxed=True) model: nn.module = deluca.field(DeepNetwork, jaxed=False) - featurizer: jnp.array = deluca.field(jaxed=False) + featurizer: jnp.ndarray = deluca.field(jaxed=False) H: int = deluca.field(100, jaxed=False) input_dim: int = deluca.field(1, jaxed=False) history_len: int = deluca.field(10, jaxed=False) diff --git a/deluca/lung/controllers/_deep_mlp.py b/deluca/lung/controllers/_deep_mlp.py index 25685e8..3007e18 100644 --- a/deluca/lung/controllers/_deep_mlp.py +++ b/deluca/lung/controllers/_deep_mlp.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -36,8 +36,8 @@ class DeepControllerState(deluca.Obj): waveform: deluca.Obj # waveform can change during training - errs: jnp.array - fwd_targets: jnp.array + errs: jnp.ndarray + fwd_targets: jnp.ndarray time: float = float("inf") steps: int = 0 dt: float = DEFAULT_DT diff --git a/deluca/lung/controllers/_expiratory.py b/deluca/lung/controllers/_expiratory.py index 4fb9eaf..1db4569 100644 --- a/deluca/lung/controllers/_expiratory.py +++ b/deluca/lung/controllers/_expiratory.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/controllers/_pid.py b/deluca/lung/controllers/_pid.py index af9583e..d0b5d29 100644 --- a/deluca/lung/controllers/_pid.py +++ b/deluca/lung/controllers/_pid.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -48,7 +48,7 @@ def __call__(self, x): class PID(Controller): """PID controller.""" model: nn.module = deluca.field(PIDNetwork, jaxed=False) - params: jnp.array = deluca.field(jaxed=True) # jnp.array([3.0, 4.0, 0.0] + params: jnp.ndarray = deluca.field(jaxed=True) # jnp.array([3.0, 4.0, 0.0] RC: float = deluca.field(0.5, jaxed=False) dt: float = deluca.field(0.03, jaxed=False) model_apply: collections.abc.Callable = deluca.field(jaxed=False) diff --git a/deluca/lung/controllers/_predestined.py b/deluca/lung/controllers/_predestined.py index 4beb400..58e9a9d 100644 --- a/deluca/lung/controllers/_predestined.py +++ b/deluca/lung/controllers/_predestined.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -27,7 +27,7 @@ class Predestined(Controller): time: float = deluca.field(jaxed=False) steps: int = deluca.field(jaxed=False) dt: float = deluca.field(jaxed=False) - u_ins: jnp.array = deluca.field(jaxed=False) + u_ins: jnp.ndarray = deluca.field(jaxed=False) def __call__(self, state, obs, *args, **kwargs): action = jax.lax.dynamic_slice(self.u_ins, (state.steps.astype(int),), (1,)) diff --git a/deluca/lung/controllers/_residual.py b/deluca/lung/controllers/_residual.py index 59f4dd5..3814bc8 100644 --- a/deluca/lung/controllers/_residual.py +++ b/deluca/lung/controllers/_residual.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/core.py b/deluca/lung/core.py index 1de2d9a..e690b88 100644 --- a/deluca/lung/core.py +++ b/deluca/lung/core.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -15,7 +15,7 @@ """Core.""" import functools import os -from typing import Tuple +from typing import Any, Tuple import deluca.core import jax @@ -35,14 +35,13 @@ class BreathWaveform(deluca.Obj): peep: float = deluca.field(5., jaxed=False) pip: float = deluca.field(35., jaxed=False) bpm: int = deluca.field(20, jaxed=False) - fp: jnp.array = deluca.field(jaxed=False) - xp: jnp.array = deluca.field(jaxed=False) + fp: jnp.ndarray = deluca.field(jaxed=False) + xp: jnp.ndarray = deluca.field(jaxed=False) in_bounds: Tuple[int, int] = deluca.field((0, 1), jaxed=False) ex_bounds: Tuple[int, int] = deluca.field((2, 4), jaxed=False) period: float = deluca.field(jaxed=False) dt: float = deluca.field(DEFAULT_DT, jaxed=False) - dtype: jax._src.numpy.lax_numpy._ScalarMeta = deluca.field( - jnp.float32, jaxed=False) + dtype: type[Any] = deluca.field(jnp.float32, jaxed=False) def setup(self): if self.fp is None: diff --git a/deluca/lung/envs/__init__.py b/deluca/lung/envs/__init__.py index f12d3ea..34a987d 100644 --- a/deluca/lung/envs/__init__.py +++ b/deluca/lung/envs/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/envs/_balloon_lung.py b/deluca/lung/envs/_balloon_lung.py index 73b6bbe..ca07512 100644 --- a/deluca/lung/envs/_balloon_lung.py +++ b/deluca/lung/envs/_balloon_lung.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/envs/_delay_lung.py b/deluca/lung/envs/_delay_lung.py index e991411..6970097 100644 --- a/deluca/lung/envs/_delay_lung.py +++ b/deluca/lung/envs/_delay_lung.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -26,8 +26,8 @@ class Observation(deluca.Obj): class SimulatorState(deluca.Obj): - in_history: jnp.array - out_history: jnp.array + in_history: jnp.ndarray + out_history: jnp.ndarray steps: int = 0 time: float = 0.0 volume: float = 0.0 diff --git a/deluca/lung/envs/_learned_lung.py b/deluca/lung/envs/_learned_lung.py index 1d7612a..59f9083 100644 --- a/deluca/lung/envs/_learned_lung.py +++ b/deluca/lung/envs/_learned_lung.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -92,7 +92,7 @@ def false_func(state, u_in, model_idx, u_normalizer, update_history, class LearnedLung(LungEnv): """Learned lung.""" params: list = deluca.field(jaxed=True) - init_rng: jnp.array = deluca.field(jaxed=False) + init_rng: jnp.ndarray = deluca.field(jaxed=False) u_window: int = deluca.field(5, jaxed=False) p_window: int = deluca.field(3, jaxed=False) u_history_len: int = deluca.field(5, jaxed=False) @@ -148,7 +148,6 @@ def setup(self): def init(self, key): return self.reset() - def reset(self): normalized_peep = self.reset_normalized_peep state = SimulatorState( diff --git a/deluca/lung/envs/_single_comp_lung.py b/deluca/lung/envs/_single_comp_lung.py index d1a8ea2..e72b612 100644 --- a/deluca/lung/envs/_single_comp_lung.py +++ b/deluca/lung/envs/_single_comp_lung.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/utils/data/analyzer.py b/deluca/lung/utils/data/analyzer.py index 599b978..cbcd791 100644 --- a/deluca/lung/utils/data/analyzer.py +++ b/deluca/lung/utils/data/analyzer.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/utils/data/breath_dataset.py b/deluca/lung/utils/data/breath_dataset.py index 9436a75..6e2edfd 100644 --- a/deluca/lung/utils/data/breath_dataset.py +++ b/deluca/lung/utils/data/breath_dataset.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/utils/data/transform.py b/deluca/lung/utils/data/transform.py index ca74e34..1bfa718 100644 --- a/deluca/lung/utils/data/transform.py +++ b/deluca/lung/utils/data/transform.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/utils/nn/__init__.py b/deluca/lung/utils/nn/__init__.py index d0a377a..d28caca 100644 --- a/deluca/lung/utils/nn/__init__.py +++ b/deluca/lung/utils/nn/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/utils/nn/cnn.py b/deluca/lung/utils/nn/cnn.py index a4c5456..532bd34 100644 --- a/deluca/lung/utils/nn/cnn.py +++ b/deluca/lung/utils/nn/cnn.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -26,7 +26,7 @@ class CNN(nn.Module): # strides: Tuple[int, int] = (1, 1) strides: int = 1 out_dim: int = 1 - activation_fn: Callable[[jnp.array], jnp.array] = nn.relu + activation_fn: Callable[[jnp.ndarray], jnp.ndarray] = nn.relu @nn.compact def __call__(self, x): diff --git a/deluca/lung/utils/nn/lstm.py b/deluca/lung/utils/nn/lstm.py index 3bd03f9..a9f7966 100644 --- a/deluca/lung/utils/nn/lstm.py +++ b/deluca/lung/utils/nn/lstm.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -55,17 +55,21 @@ class LSTMNetwork(nn.Module): variable_broadcast='params', in_axes=1, out_axes=1, - split_rngs={'params': False}) + split_rngs={'params': False}, + ) @nn.compact def __call__(self, carry, x): + features = carry[0].shape[-1] for _ in range(self.n_layers): - carry, x = nn.OptimizedLSTMCell(activation_fn=self.activation_fn)(carry, - x) + carry, x = nn.OptimizedLSTMCell( + features, activation_fn=self.activation_fn + )(carry, x) return carry, x @staticmethod def initialize_carry(batch_dims, hidden_dim): # (N, C, H, W) = (N, 1, 1, W) where W = feature_dim and N is batch_size # Use fixed random key since default state init fn is just zeros. - return nn.OptimizedLSTMCell.initialize_carry( - jax.random.PRNGKey(0), batch_dims, hidden_dim) + return nn.OptimizedLSTMCell(hidden_dim, parent=None).initialize_carry( + jax.random.PRNGKey(0), (batch_dims, 1) + ) diff --git a/deluca/lung/utils/nn/mlp.py b/deluca/lung/utils/nn/mlp.py index 3934ccb..c6ab650 100644 --- a/deluca/lung/utils/nn/mlp.py +++ b/deluca/lung/utils/nn/mlp.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/utils/nn/shallow_boundary_model.py b/deluca/lung/utils/nn/shallow_boundary_model.py index 2c49eb2..5c623cd 100644 --- a/deluca/lung/utils/nn/shallow_boundary_model.py +++ b/deluca/lung/utils/nn/shallow_boundary_model.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/utils/scripts/run_controller.py b/deluca/lung/utils/scripts/run_controller.py index 896dab4..545145d 100644 --- a/deluca/lung/utils/scripts/run_controller.py +++ b/deluca/lung/utils/scripts/run_controller.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/utils/scripts/test_controller.py b/deluca/lung/utils/scripts/test_controller.py index 972fcd9..8f06dfb 100644 --- a/deluca/lung/utils/scripts/test_controller.py +++ b/deluca/lung/utils/scripts/test_controller.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/utils/scripts/test_simulator.py b/deluca/lung/utils/scripts/test_simulator.py index dbf03ba..50a7d00 100644 --- a/deluca/lung/utils/scripts/test_simulator.py +++ b/deluca/lung/utils/scripts/test_simulator.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/utils/scripts/train_controller.py b/deluca/lung/utils/scripts/train_controller.py index cf0bb5b..5f70af9 100644 --- a/deluca/lung/utils/scripts/train_controller.py +++ b/deluca/lung/utils/scripts/train_controller.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/lung/utils/scripts/train_simulator.py b/deluca/lung/utils/scripts/train_simulator.py index 88b67a1..db8fa95 100644 --- a/deluca/lung/utils/scripts/train_simulator.py +++ b/deluca/lung/utils/scripts/train_simulator.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/tests/lung/core_test.py b/deluca/tests/lung/core_test.py index 6280cc3..f09bf5a 100644 --- a/deluca/tests/lung/core_test.py +++ b/deluca/tests/lung/core_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/tests/lung/utils/data/analyzer_test.py b/deluca/tests/lung/utils/data/analyzer_test.py index 5ffef33..f6992f6 100644 --- a/deluca/tests/lung/utils/data/analyzer_test.py +++ b/deluca/tests/lung/utils/data/analyzer_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/tests/lung/utils/data/breath_dataset_test.py b/deluca/tests/lung/utils/data/breath_dataset_test.py index 0d3221f..be3910b 100644 --- a/deluca/tests/lung/utils/data/breath_dataset_test.py +++ b/deluca/tests/lung/utils/data/breath_dataset_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/tests/lung/utils/data/transform_test.py b/deluca/tests/lung/utils/data/transform_test.py index c52a74f..3aa492d 100644 --- a/deluca/tests/lung/utils/data/transform_test.py +++ b/deluca/tests/lung/utils/data/transform_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/tests/lung/utils/scripts/run_controller_test.py b/deluca/tests/lung/utils/scripts/run_controller_test.py index c9d9ba0..51d49f3 100644 --- a/deluca/tests/lung/utils/scripts/run_controller_test.py +++ b/deluca/tests/lung/utils/scripts/run_controller_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/tests/lung/utils/scripts/test_controller_test.py b/deluca/tests/lung/utils/scripts/test_controller_test.py index ae64803..1d67e61 100644 --- a/deluca/tests/lung/utils/scripts/test_controller_test.py +++ b/deluca/tests/lung/utils/scripts/test_controller_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/tests/lung/utils/scripts/test_simulator_test.py b/deluca/tests/lung/utils/scripts/test_simulator_test.py index 0acfec2..88342a6 100644 --- a/deluca/tests/lung/utils/scripts/test_simulator_test.py +++ b/deluca/tests/lung/utils/scripts/test_simulator_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/tests/lung/utils/scripts/train_controller_test.py b/deluca/tests/lung/utils/scripts/train_controller_test.py index 94231c6..27247b1 100644 --- a/deluca/tests/lung/utils/scripts/train_controller_test.py +++ b/deluca/tests/lung/utils/scripts/train_controller_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/tests/lung/utils/scripts/train_simulator_test.py b/deluca/tests/lung/utils/scripts/train_simulator_test.py index ebebd64..61eaf65 100644 --- a/deluca/tests/lung/utils/scripts/train_simulator_test.py +++ b/deluca/tests/lung/utils/scripts/train_simulator_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/tests/training/ppo_run.py b/deluca/tests/training/ppo_run.py index 0f896e2..50d2326 100644 --- a/deluca/tests/training/ppo_run.py +++ b/deluca/tests/training/ppo_run.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/tests/training/ppo_test.py b/deluca/tests/training/ppo_test.py index f97e0ea..5426940 100644 --- a/deluca/tests/training/ppo_test.py +++ b/deluca/tests/training/ppo_test.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/training/__init__.py b/deluca/training/__init__.py index 17c34b3..a1d872f 100644 --- a/deluca/training/__init__.py +++ b/deluca/training/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/training/apg.py b/deluca/training/apg.py index d725c92..717f0b9 100644 --- a/deluca/training/apg.py +++ b/deluca/training/apg.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/training/ppo.py b/deluca/training/ppo.py index 16515a4..00cb915 100644 --- a/deluca/training/ppo.py +++ b/deluca/training/ppo.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/utils/__init__.py b/deluca/utils/__init__.py index 17c34b3..a1d872f 100644 --- a/deluca/utils/__init__.py +++ b/deluca/utils/__init__.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/utils/experiment.py b/deluca/utils/experiment.py index 4679e2e..7d92d98 100644 --- a/deluca/utils/experiment.py +++ b/deluca/utils/experiment.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -185,7 +185,7 @@ def run(self, processes=1, chunksize=1, tqdm=None): self._validate() single = lambda: map(runner, self._generate_arglists()) # noqa: E731 - num_tasks = np.product([len(spec[1]) for spec in self._spec]) + num_tasks = np.prod([len(spec[1]) for spec in self._spec]) # TODO: Figure out why parallel hangs in pytest parallel = lambda: pathos.pools.ProcessPool(nodes=processes).imap( # noqa: E731 diff --git a/deluca/utils/planning.py b/deluca/utils/planning.py index 302c985..60a6a4a 100644 --- a/deluca/utils/planning.py +++ b/deluca/utils/planning.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/utils/tree.py b/deluca/utils/tree.py index 1ace9e6..1931fc1 100644 --- a/deluca/utils/tree.py +++ b/deluca/utils/tree.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/deluca/version.py b/deluca/version.py index dfd82a6..54130d0 100644 --- a/deluca/version.py +++ b/deluca/version.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/plugin/setup.py b/plugin/setup.py index da45894..7b1081e 100644 --- a/plugin/setup.py +++ b/plugin/setup.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/scripts/make_plugin.py b/scripts/make_plugin.py index 8b0f5c1..964a924 100755 --- a/scripts/make_plugin.py +++ b/scripts/make_plugin.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/setup.py b/setup.py index 8649064..51a94e4 100644 --- a/setup.py +++ b/setup.py @@ -1,4 +1,4 @@ -# Copyright 2022 The Deluca Authors. +# Copyright 2023 The Deluca Authors. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License.