Shortcuts

Source code for torchdyn.numerics.systems

# 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 torch
import torch.nn as nn
import torch.distributions
from torch.distributions import Uniform


[docs]class Lorenz(nn.Module): def __init__(self): super().__init__() self.p = nn.Linear(1, 1)
[docs] def forward(self, t, x, **kwargs): x1, x2, x3 = x[..., :1], x[..., 1:2], x[..., 2:] dx1 = 10 * (x2 - x1) dx2 = x1 * (28 - x3) - x2 dx3 = x1 * x2 - 8 / 3 * x3 return torch.cat([dx1, dx2, dx3], -1)
[docs]class VanDerPol(nn.Module): def __init__(self, alpha=10): super().__init__() self.alpha = alpha self.nfe = 0
[docs] def forward(self, t, x, **kwargs): self.nfe += 1 x1, x2 = x[..., :1], x[..., 1:2] return torch.cat([x2, self.alpha * (1 - x1 ** 2) * x2 - x1], -1)
[docs]class ODEProblem2(nn.Module): def __init__(self): super().__init__()
[docs] def forward(self, s, z): return 0.5 * z
[docs]class ODEProblem3(nn.Module): def __init__(self): super().__init__()
[docs] def forward(self, s, z): return -0.1 * z
[docs]class ODEProblem4(nn.Module): "Rabinovich-Fabrikant" def __init__(self): super().__init__()
[docs] def forward(self, s, z): x1, x2, x3 = z[..., :1], z[..., 1:2], z[..., -1:] dx1 = x2 * (x3 - 1 + x1 ** 2) + 0.87 * x1 dx2 = x1 * (3 * x3 + 1 - x1 ** 2) + 0.87 * x2 dx3 = -2 * x3 * (1.1 + x1 * x2) return torch.cat([dx1, dx2, dx3], -1)
[docs]class SineSystem(nn.Module): def __init__(self): super().__init__()
[docs] def forward(self, s, z): s = s * torch.ones_like(z) return torch.sin(s)
[docs]class LTISystem(nn.Module): def __init__(self, dim=2, randomizable=True): super().__init__() self.dim = dim self.randomizable = randomizable self.l = nn.Linear(dim, dim)
[docs] def forward(self, s, x): return self.l(x)
[docs] def randomize_parameters(self): self.l = nn.Linear(self.dim, self.dim)
[docs]class FourierSystem(nn.Module): def __init__(self, dim=2, A_dist=Uniform(-10, 10), phi_dist=Uniform(-1, 1), w_dist=Uniform(-20, 20), randomizable=True ): super().__init__() self.n_harmonics = n_harmonics = torch.randint(2, 20, size=(1,)) self.A_dist = A_dist; self.A = A_dist.sample(torch.Size([dim, n_harmonics, 2])) self.phi_dist = phi_dist; self.phi = phi_dist.sample(torch.Size([dim, n_harmonics, 2])) self.w_dist = w_dist; self.w = w_dist.sample(torch.Size([dim, n_harmonics, 2])) self.dim = dim self.randomizable = randomizable
[docs] def forward(self, s, x): if len(s.shape) == 0: return (self.A[:, :, 0] * torch.cos(self.w[:, :, 0] * s + self.phi[:, :, 0]) + self.A[:, :, 1] * torch.cos(self.w[:, :, 1] * s + self.phi[:, :, 1])).sum(1)[None, :] else: sol = [] for s_ in s: sol += [(self.A[:, :, 0] * torch.cos(self.w[:, :, 0] * s_ + self.phi[:, :, 0]) + self.A[:, :, 1] * torch.cos(self.w[:, :, 1] * s_ + self.phi[:, :, 1])).sum(1)[None, :]] return torch.cat(sol)
[docs] def randomize_parameters(self): self.A = self.A_dist.sample(torch.Size([self.dim, self.n_harmonics, 2])) self.phi = self.phi_dist.sample(torch.Size([self.dim, self.n_harmonics, 2])) self.w = self.w_dist.sample(torch.Size([self.dim, self.n_harmonics, 2]))
[docs]class StiffFourierSystem(nn.Module): def __init__(self, dim=2, A_dist=Uniform(-10, 10), phi_dist=Uniform(-1, 1), w_dist=Uniform(-20, 20), randomizable=True ): super().__init__() self.n_harmonics = n_harmonics = torch.randint(20, 100, size=(1,)) self.A_dist = A_dist; self.A = A_dist.sample(torch.Size([dim, n_harmonics, 2])) self.phi_dist = phi_dist; self.phi = phi_dist.sample(torch.Size([dim, n_harmonics, 2])) self.w_dist = w_dist; self.w = w_dist.sample(torch.Size([dim, n_harmonics, 2])) self.dim = dim self.randomizable = randomizable
[docs] def forward(self, s, x): if len(s.shape) == 0: return (self.A[:, :, 0] * torch.cos(self.w[:, :, 0] * s + self.phi[:, :, 0]) + self.A[:, :, 1] * torch.cos(self.w[:, :, 1] * s + self.phi[:, :, 1])).sum(1)[None, :] else: sol = [] for s_ in s: sol += [(self.A[:, :, 0] * torch.cos(self.w[:, :, 0] * s_ + self.phi[:, :, 0]) + self.A[:, :, 1] * torch.cos(self.w[:, :, 1] * s_ + self.phi[:, :, 1])).sum(1)[None, :]] return torch.cat(sol)
[docs] def randomize_parameters(self): self.A = self.A_dist.sample(torch.Size([self.dim, self.n_harmonics, 2])) self.phi = self.phi_dist.sample(torch.Size([self.dim, self.n_harmonics, 2])) self.w = self.w_dist.sample(torch.Size([self.dim, self.n_harmonics, 2]))
[docs]class CoupledFourierSystem(nn.Module): def __init__(self, dim=2, A_dist=Uniform(-10, 10), phi_dist=Uniform(-1, 1), w_dist=Uniform(-20, 20), randomizable=True ): super().__init__() self.n_harmonics = n_harmonics = torch.randint(2, 20, size=(1,)) self.A_dist = A_dist; self.A = A_dist.sample(torch.Size([dim, n_harmonics, 2])) self.phi_dist = phi_dist; self.phi = phi_dist.sample(torch.Size([dim, n_harmonics, 2])) self.w_dist = w_dist; self.w = w_dist.sample(torch.Size([dim, n_harmonics, 2])) self.dim = dim self.randomizable = randomizable self.mixing_l = nn.Linear(dim, dim)
[docs] def forward(self, s, x): if len(s.shape) == 0: pre_sol = (self.A[:, :, 0] * torch.cos(self.w[:, :, 0] * s + self.phi[:, :, 0]) + self.A[:, :, 1] * torch.cos(self.w[:, :, 1] * s + self.phi[:, :, 1])).sum(1)[None, :] return self.mixing_l(pre_sol) else: sol = [] for s_ in s: sol += [(self.A[:, :, 0] * torch.cos(self.w[:, :, 0] * s_ + self.phi[:, :, 0]) + self.A[:, :, 1] * torch.cos(self.w[:, :, 1] * s_ + self.phi[:, :, 1])).sum(1)[None, None, :]] return self.mixing_l(torch.cat(sol, 0))[:, 0, :]
[docs] def randomize_parameters(self): self.A = self.A_dist.sample(torch.Size([self.dim, self.n_harmonics, 2])) self.phi = self.phi_dist.sample(torch.Size([self.dim, self.n_harmonics, 2])) self.w = self.w_dist.sample(torch.Size([self.dim, self.n_harmonics, 2])) self.mixing_l = nn.Linear(self.dim, self.dim)
[docs]class MatMulSystem(nn.Module): def __init__(self, dim=2, activation=nn.Tanh(), layers=5, hdim=32, randomizable=True): super().__init__() self.dim = dim self.net = nn.Sequential(nn.Sequential(nn.Linear(dim, hdim), nn.Tanh(), *[nn.Sequential(nn.Linear(hdim, hdim), nn.Tanh()) for i in range(4)], nn.Linear(hdim, dim))) self.randomizable = randomizable
[docs] def forward(self, s, x): return self.net(x)
[docs] def randomize_parameters(self): for p in self.net.parameters(): torch.nn.init.normal_(p, 0, 1)
[docs]class MatMulBoundedSystem(nn.Module): def __init__(self, dim=2, activation=nn.Tanh(), layers=5, hdim=32, randomizable=True): super().__init__() self.dim = dim self.net = nn.Sequential(nn.Sequential(nn.Linear(dim, hdim), nn.Tanh(), *[nn.Sequential(nn.Linear(hdim, hdim), nn.Tanh()) for i in range(4)], nn.Linear(hdim, dim), nn.Tanh())) self.randomizable = randomizable
[docs] def forward(self, s, x): return self.net(x)
[docs] def randomize_parameters(self): for p in self.net.parameters(): torch.nn.init.normal_(p, 0, 1)

© Copyright 2020, Stefano Massaroli & Michael Poli. Revision 7b05e463.

Built with Sphinx using a theme provided by Read the Docs.
Read the Docs v: latest
Versions
latest
stable
Downloads
On Read the Docs
Project Home
Builds

Free document hosting provided by Read the Docs.