From 4ed7f50a982ebbec9a3d0fa12d1c70e4e11f8138 Mon Sep 17 00:00:00 2001 From: Prakhar Sharma <1915438@swansea.ac.uk> Date: Thu, 9 Nov 2023 16:52:20 +0000 Subject: [PATCH] geometry refactor in future --- DeepINN/geometry/__init__.py | 6 +- .../conditions/__init__.py | 0 .../conditions/condition.py | 0 .../conditions/deeponet_condition.py | 0 .../domains/__init__.py | 0 .../domains/domain.py | 0 .../domains/domain0D/__init__.py | 0 .../domains/domain0D/point.py | 0 .../domains/domain1D/__init__.py | 0 .../domains/domain1D/interval.py | 0 .../domains/domain2D/__init__.py | 0 .../domains/domain2D/circle.py | 0 .../domains/domain2D/parallelogram.py | 0 .../domains/domain2D/shapely_polygon.py | 0 .../domains/domain2D/triangle.py | 0 .../domains/domain3D/__init__.py | 0 .../domains/domain3D/sphere.py | 0 .../domains/domain3D/trimesh_polyhedron.py | 0 .../domains/domainoperations/cut.py | 0 .../domains/domainoperations/intersection.py | 0 .../domains/domainoperations/product.py | 0 .../domains/domainoperations/rotate.py | 0 .../domainoperations/sampler_helper.py | 0 .../domains/domainoperations/translate.py | 0 .../domains/domainoperations/union.py | 0 .../domains/functionsets/__init__.py | 0 .../domains/functionsets/functionset.py | 0 .../samplers/__init__.py | 0 .../samplers/data_samplers.py | 0 .../samplers/grid_samplers.py | 0 .../samplers/plot_samplers.py | 0 .../samplers/random_samplers.py | 0 .../samplers/sampler_base.py | 0 DeepINN/geometry/spaces/__init__.py | 18 +- .../spaces/functionspace.py | 0 .../spaces/points.py | 0 DeepINN/geometry/spaces/space.py | 273 +++++++++++------- DeepINN/geometry_legacy/__init__.py | 5 - DeepINN/geometry_legacy/spaces/__init__.py | 17 -- DeepINN/geometry_legacy/spaces/space.py | 198 ------------- DeepINN/geometry_refactor/__init__.py | 1 + .../{geometry => geometry_refactor}/points.py | 0 DeepINN/geometry_refactor/spaces/__init__.py | 1 + DeepINN/geometry_refactor/spaces/space.py | 147 ++++++++++ DeepINN/model.py | 6 +- Tutorials/5. FCNN/3. model.ipynb | 150 +++++++--- todo.md | 4 +- 47 files changed, 454 insertions(+), 372 deletions(-) rename DeepINN/{geometry_legacy => geometry}/conditions/__init__.py (100%) rename DeepINN/{geometry_legacy => geometry}/conditions/condition.py (100%) rename DeepINN/{geometry_legacy => geometry}/conditions/deeponet_condition.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/__init__.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain0D/__init__.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain0D/point.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain1D/__init__.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain1D/interval.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain2D/__init__.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain2D/circle.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain2D/parallelogram.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain2D/shapely_polygon.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain2D/triangle.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain3D/__init__.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain3D/sphere.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domain3D/trimesh_polyhedron.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domainoperations/cut.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domainoperations/intersection.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domainoperations/product.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domainoperations/rotate.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domainoperations/sampler_helper.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domainoperations/translate.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/domainoperations/union.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/functionsets/__init__.py (100%) rename DeepINN/{geometry_legacy => geometry}/domains/functionsets/functionset.py (100%) rename DeepINN/{geometry_legacy => geometry}/samplers/__init__.py (100%) rename DeepINN/{geometry_legacy => geometry}/samplers/data_samplers.py (100%) rename DeepINN/{geometry_legacy => geometry}/samplers/grid_samplers.py (100%) rename DeepINN/{geometry_legacy => geometry}/samplers/plot_samplers.py (100%) rename DeepINN/{geometry_legacy => geometry}/samplers/random_samplers.py (100%) rename DeepINN/{geometry_legacy => geometry}/samplers/sampler_base.py (100%) rename DeepINN/{geometry_legacy => geometry}/spaces/functionspace.py (100%) rename DeepINN/{geometry_legacy => geometry}/spaces/points.py (100%) delete mode 100644 DeepINN/geometry_legacy/__init__.py delete mode 100644 DeepINN/geometry_legacy/spaces/__init__.py delete mode 100644 DeepINN/geometry_legacy/spaces/space.py create mode 100644 DeepINN/geometry_refactor/__init__.py rename DeepINN/{geometry => geometry_refactor}/points.py (100%) create mode 100644 DeepINN/geometry_refactor/spaces/__init__.py create mode 100644 DeepINN/geometry_refactor/spaces/space.py diff --git a/DeepINN/geometry/__init__.py b/DeepINN/geometry/__init__.py index fc80254..3fc0761 100644 --- a/DeepINN/geometry/__init__.py +++ b/DeepINN/geometry/__init__.py @@ -1 +1,5 @@ -pass \ No newline at end of file +# Make the subdirectory callable +from . import domains +#from . import conditions +from . import samplers +from . import spaces \ No newline at end of file diff --git a/DeepINN/geometry_legacy/conditions/__init__.py b/DeepINN/geometry/conditions/__init__.py similarity index 100% rename from DeepINN/geometry_legacy/conditions/__init__.py rename to DeepINN/geometry/conditions/__init__.py diff --git a/DeepINN/geometry_legacy/conditions/condition.py b/DeepINN/geometry/conditions/condition.py similarity index 100% rename from DeepINN/geometry_legacy/conditions/condition.py rename to DeepINN/geometry/conditions/condition.py diff --git a/DeepINN/geometry_legacy/conditions/deeponet_condition.py b/DeepINN/geometry/conditions/deeponet_condition.py similarity index 100% rename from DeepINN/geometry_legacy/conditions/deeponet_condition.py rename to DeepINN/geometry/conditions/deeponet_condition.py diff --git a/DeepINN/geometry_legacy/domains/__init__.py b/DeepINN/geometry/domains/__init__.py similarity index 100% rename from DeepINN/geometry_legacy/domains/__init__.py rename to DeepINN/geometry/domains/__init__.py diff --git a/DeepINN/geometry_legacy/domains/domain.py b/DeepINN/geometry/domains/domain.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain.py rename to DeepINN/geometry/domains/domain.py diff --git a/DeepINN/geometry_legacy/domains/domain0D/__init__.py b/DeepINN/geometry/domains/domain0D/__init__.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain0D/__init__.py rename to DeepINN/geometry/domains/domain0D/__init__.py diff --git a/DeepINN/geometry_legacy/domains/domain0D/point.py b/DeepINN/geometry/domains/domain0D/point.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain0D/point.py rename to DeepINN/geometry/domains/domain0D/point.py diff --git a/DeepINN/geometry_legacy/domains/domain1D/__init__.py b/DeepINN/geometry/domains/domain1D/__init__.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain1D/__init__.py rename to DeepINN/geometry/domains/domain1D/__init__.py diff --git a/DeepINN/geometry_legacy/domains/domain1D/interval.py b/DeepINN/geometry/domains/domain1D/interval.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain1D/interval.py rename to DeepINN/geometry/domains/domain1D/interval.py diff --git a/DeepINN/geometry_legacy/domains/domain2D/__init__.py b/DeepINN/geometry/domains/domain2D/__init__.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain2D/__init__.py rename to DeepINN/geometry/domains/domain2D/__init__.py diff --git a/DeepINN/geometry_legacy/domains/domain2D/circle.py b/DeepINN/geometry/domains/domain2D/circle.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain2D/circle.py rename to DeepINN/geometry/domains/domain2D/circle.py diff --git a/DeepINN/geometry_legacy/domains/domain2D/parallelogram.py b/DeepINN/geometry/domains/domain2D/parallelogram.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain2D/parallelogram.py rename to DeepINN/geometry/domains/domain2D/parallelogram.py diff --git a/DeepINN/geometry_legacy/domains/domain2D/shapely_polygon.py b/DeepINN/geometry/domains/domain2D/shapely_polygon.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain2D/shapely_polygon.py rename to DeepINN/geometry/domains/domain2D/shapely_polygon.py diff --git a/DeepINN/geometry_legacy/domains/domain2D/triangle.py b/DeepINN/geometry/domains/domain2D/triangle.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain2D/triangle.py rename to DeepINN/geometry/domains/domain2D/triangle.py diff --git a/DeepINN/geometry_legacy/domains/domain3D/__init__.py b/DeepINN/geometry/domains/domain3D/__init__.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain3D/__init__.py rename to DeepINN/geometry/domains/domain3D/__init__.py diff --git a/DeepINN/geometry_legacy/domains/domain3D/sphere.py b/DeepINN/geometry/domains/domain3D/sphere.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain3D/sphere.py rename to DeepINN/geometry/domains/domain3D/sphere.py diff --git a/DeepINN/geometry_legacy/domains/domain3D/trimesh_polyhedron.py b/DeepINN/geometry/domains/domain3D/trimesh_polyhedron.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domain3D/trimesh_polyhedron.py rename to DeepINN/geometry/domains/domain3D/trimesh_polyhedron.py diff --git a/DeepINN/geometry_legacy/domains/domainoperations/cut.py b/DeepINN/geometry/domains/domainoperations/cut.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domainoperations/cut.py rename to DeepINN/geometry/domains/domainoperations/cut.py diff --git a/DeepINN/geometry_legacy/domains/domainoperations/intersection.py b/DeepINN/geometry/domains/domainoperations/intersection.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domainoperations/intersection.py rename to DeepINN/geometry/domains/domainoperations/intersection.py diff --git a/DeepINN/geometry_legacy/domains/domainoperations/product.py b/DeepINN/geometry/domains/domainoperations/product.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domainoperations/product.py rename to DeepINN/geometry/domains/domainoperations/product.py diff --git a/DeepINN/geometry_legacy/domains/domainoperations/rotate.py b/DeepINN/geometry/domains/domainoperations/rotate.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domainoperations/rotate.py rename to DeepINN/geometry/domains/domainoperations/rotate.py diff --git a/DeepINN/geometry_legacy/domains/domainoperations/sampler_helper.py b/DeepINN/geometry/domains/domainoperations/sampler_helper.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domainoperations/sampler_helper.py rename to DeepINN/geometry/domains/domainoperations/sampler_helper.py diff --git a/DeepINN/geometry_legacy/domains/domainoperations/translate.py b/DeepINN/geometry/domains/domainoperations/translate.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domainoperations/translate.py rename to DeepINN/geometry/domains/domainoperations/translate.py diff --git a/DeepINN/geometry_legacy/domains/domainoperations/union.py b/DeepINN/geometry/domains/domainoperations/union.py similarity index 100% rename from DeepINN/geometry_legacy/domains/domainoperations/union.py rename to DeepINN/geometry/domains/domainoperations/union.py diff --git a/DeepINN/geometry_legacy/domains/functionsets/__init__.py b/DeepINN/geometry/domains/functionsets/__init__.py similarity index 100% rename from DeepINN/geometry_legacy/domains/functionsets/__init__.py rename to DeepINN/geometry/domains/functionsets/__init__.py diff --git a/DeepINN/geometry_legacy/domains/functionsets/functionset.py b/DeepINN/geometry/domains/functionsets/functionset.py similarity index 100% rename from DeepINN/geometry_legacy/domains/functionsets/functionset.py rename to DeepINN/geometry/domains/functionsets/functionset.py diff --git a/DeepINN/geometry_legacy/samplers/__init__.py b/DeepINN/geometry/samplers/__init__.py similarity index 100% rename from DeepINN/geometry_legacy/samplers/__init__.py rename to DeepINN/geometry/samplers/__init__.py diff --git a/DeepINN/geometry_legacy/samplers/data_samplers.py b/DeepINN/geometry/samplers/data_samplers.py similarity index 100% rename from DeepINN/geometry_legacy/samplers/data_samplers.py rename to DeepINN/geometry/samplers/data_samplers.py diff --git a/DeepINN/geometry_legacy/samplers/grid_samplers.py b/DeepINN/geometry/samplers/grid_samplers.py similarity index 100% rename from DeepINN/geometry_legacy/samplers/grid_samplers.py rename to DeepINN/geometry/samplers/grid_samplers.py diff --git a/DeepINN/geometry_legacy/samplers/plot_samplers.py b/DeepINN/geometry/samplers/plot_samplers.py similarity index 100% rename from DeepINN/geometry_legacy/samplers/plot_samplers.py rename to DeepINN/geometry/samplers/plot_samplers.py diff --git a/DeepINN/geometry_legacy/samplers/random_samplers.py b/DeepINN/geometry/samplers/random_samplers.py similarity index 100% rename from DeepINN/geometry_legacy/samplers/random_samplers.py rename to DeepINN/geometry/samplers/random_samplers.py diff --git a/DeepINN/geometry_legacy/samplers/sampler_base.py b/DeepINN/geometry/samplers/sampler_base.py similarity index 100% rename from DeepINN/geometry_legacy/samplers/sampler_base.py rename to DeepINN/geometry/samplers/sampler_base.py diff --git a/DeepINN/geometry/spaces/__init__.py b/DeepINN/geometry/spaces/__init__.py index 1515c26..3606008 100644 --- a/DeepINN/geometry/spaces/__init__.py +++ b/DeepINN/geometry/spaces/__init__.py @@ -1 +1,17 @@ -from .space import Space, R1, R2, R3 \ No newline at end of file +"""Contains the Spaces and Points classes. + +Spaces + It's purpose is to define variable names and dimensions that can + be used in functions, domains, models and more. + +Points + The ``Points`` object is a central part of TorchPhysics. They consit of a PyTorch-Tensor + and a space. ``Points`` store data in a tensor with 2-axis, the first corresponding + the batch-dimension in a batch of multiple points. + The second axis collects the space dimensionalities. +""" + +from .space import (Space, + R1, R2, R3, Rn) +from .points import Points +from .functionspace import FunctionSpace \ No newline at end of file diff --git a/DeepINN/geometry_legacy/spaces/functionspace.py b/DeepINN/geometry/spaces/functionspace.py similarity index 100% rename from DeepINN/geometry_legacy/spaces/functionspace.py rename to DeepINN/geometry/spaces/functionspace.py diff --git a/DeepINN/geometry_legacy/spaces/points.py b/DeepINN/geometry/spaces/points.py similarity index 100% rename from DeepINN/geometry_legacy/spaces/points.py rename to DeepINN/geometry/spaces/points.py diff --git a/DeepINN/geometry/spaces/space.py b/DeepINN/geometry/spaces/space.py index 0512b90..c3f10ba 100644 --- a/DeepINN/geometry/spaces/space.py +++ b/DeepINN/geometry/spaces/space.py @@ -1,147 +1,198 @@ from collections import Counter, OrderedDict -""" -* A Counter is a dict subclass for counting hashable objects. It is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values. -* An OrderedDict is a dictionary subclass that remembers the order in which items are inserted. -""" class Space(Counter, OrderedDict): - """ - Base class to define the dimensions of the variables in the differential equation. - + """A Space defines (and assigns) the dimensions of the variables + that appear in the differentialequation. This class sholud not be instanced + directly, rather the corresponding child classes. + Parameters ---------- - variables_dims: dict - A dict containing name of variables and the dimension of each variable. + variables_dims : dict + A dictionary containing the name of the variables and the dimension + of the respective variable. """ def __init__(self, variables_dims): # set counter of variable names and their dimensionalities - # Since the Counter is inherited first, if the super().__init__ is consumed by Counter then the second super class won't receive the call. super().__init__(variables_dims) - # # Adding a magic method to overload the multiply operator using __mul__ - # def __mul__(self, additional_space): - # """ - # Combine two spaces to create higher dimension spaces. - # E.g R1('x')*R1('y') is a two dimensional space where one axis is 'x' - # and the other stands for 'y'. - # """ - # assert isinstance(additional_space, Space), "The additional dimension isn't an instance of Space" - # # Since we haven't defined __add__. Python will use Counter's __add__ method - # return Space(self + additional_space) - - # # __contains__ is a predefined method checks if the key (a string) is present in the counter. - # # whenever we use `in` keyword with if condition involving instances of Space object, this self.__contains__ will run be override python's default __contains__. - # # here we override this functionpython's default __contains__ - # # So if we do addition __add__ we will end up executing self.__contains__ - # def __contains__(self, space): - # """ - # Check if the variables of other space are container in this space. - # There are two possibilities. - # * method executed for internal dictionary operations such as addition - # * method executed when checking if intersection of space and self is space. - # That is why we need to modify python default __contains__ for instances of Space. - - # ChatGPT's description: - # Override the membership test (in) for the Space class. - # - If `space` is a string: Checks if the variable name (key) exists in this Space. - # This is useful for both direct membership tests and internal operations - # (e.g., during dictionary-style key checking in addition). - - # - If `space` is another Space object: Determines if the provided Space is - # entirely contained within the current Space (i.e., if it's a subset). - # """ - # if isinstance(space,str): - # #print("Flag: string") - # # check if the space already contains the variable names. - # return super().__contains__(space) - # if isinstance(space, Space): - # #print("Flag: Space") - # return (self & space) == space - # else: - # return False - - # # This is a special method in Python which is invoked when we try to access items from containers like array or dictionary. - # # It's what gets called when you use square bracket notation to access elements, such as with lists, dictionaries, and strings. - # def __getitem__(self, val): - # """ - # Since __getitem__ is used to retrieve items. There are three ways to retrieve items. str, slice, list or tuple. - - # 1. In the case of a slice. - # space_obj = Space({'a': 1, 'b': 2, 'c': 3, 'd': 4}) - # sub_space = space_obj['a':'c'] # returns a Space with {'a': 1, 'b': 2, 'c': 3} - - # 2. In the case of a tuple or a list - # space_obj = Space({'a': 1, 'b': 2, 'c': 3, 'd': 4}) - # sub_space = space_obj[['a', 'c']] # returns a Space with {'a': 1, 'c': 3} - - # 3. In all other cases then use Counter's __getitem__. - # space_obj = Space({'a': 1, 'b': 2, 'c': 3, 'd': 4}) - # value = space_obj['a'] # returns 1 - - # Parameters - # ---------- - # val : str, slice, list or tuple - # The keys that correspond to the variables that should be used in the - # subspace. - # """ - # if isinstance(val, slice): # if val is a slice - # keys = list(self.keys()) - # new_slice = slice(keys.index(val.start) if val.start is not None else None, - # keys.index(val.stop) if val.stop is not None else None, - # val.step) - # new_keys = keys[new_slice] - # return Space({k: self[k] for k in new_keys}) - # if isinstance(val, list) or isinstance(val, tuple): - # return Space({k: self[k] for k in val}) - # else: - # return super().__getitem__(val) + def __mul__(self, other): + """Creates the product space of the two input spaces. Allows the + construction of higher dimensional spaces with 'mixed' variable names. + E.g R1('x')*R1('y') is a two dimensional space where one axis is 'x' + and the other stands for 'y'. + """ + assert isinstance(other, Space) + return Space(self + other) + + def __contains__(self, space): + """Checks if the variables of the other space are contained in this + space. + + Parameters + ---------- + space : torchphysics.spaces.Space + The other Space that should be checked if this is included. + """ + if isinstance(space, str): + return super().__contains__(space) + if isinstance(space, Space): + return (self & space) == space + else: + return False - # # To promote encapsulation, @property decorator allows you to print internal read-only attributes of choice. - # # @property also allows you to call a function without the parentheses. This is useful when these isn't any input attribute. - # @property - # def dim(self): - # """ - # Return the dimension of the space. - # """ - # # self is the class Space inheriting Counter, which inherits dict, so values() will return list of values for each key of variables_dims. then sum will sum them up. - # return sum(self.values()) + def __getitem__(self, val): + """Returns a part of the Space dicitionary, specified in the + input. Mathematically, this constructs a subspace. + + Parameters + ---------- + val : str, slice, list or tuple + The keys that correspond to the variables that should be used in the + subspace. + """ + if isinstance(val, slice): + keys = list(self.keys()) + new_slice = slice(keys.index(val.start) if val.start is not None else None, + keys.index(val.stop) if val.stop is not None else None, + val.step) + new_keys = keys[new_slice] + return Space({k: self[k] for k in new_keys}) + if isinstance(val, list) or isinstance(val, tuple): + return Space({k: self[k] for k in val}) + else: + return super().__getitem__(val) + + @property + def dim(self): + """Returns the dimension of the space (sum of factor spaces) + """ + return sum(self.values()) -class R1(Space): + @property + def variables(self): + """ + A unordered (!) set of variables. + """ + return set(self.keys()) + + def __eq__(self, o: object) -> bool: + # use OrderedDict equal methode to get order-sensitive comparision + return OrderedDict.__eq__(self, o) + + def __ne__(self, o: object) -> bool: + return OrderedDict.__ne__(self, o) + """ - Space to define 1D domain. - + Python recipe (see official Python docs) to maintain the insertion order. + This way, dimensions with identical variable names will be joined, all + other dimensions will be kept in the order of their creation by products + or __init__. + """ + def __repr__(self): + return '%s(%r)' % (self.__class__.__name__, dict(OrderedDict(self))) + + def __reduce__(self): + return self.__class__, (OrderedDict(self),) + + def check_values_in_space(self, values): + """Checks if a given tensor is valid to belong to this space. + + Parameters + ---------- + values : torch.tensor + A tensor of values that should be checked. + Generally the last dimension of the tensor has to fit + the dimension of this space. + + Returns + ------- + torch.tensor + In the case, that the values have not the corrected shape, but can + be reshaped, thet reshaped values are returned. + This is used in the matrix-space. + """ + assert values.shape[-1] == self.dim + return values + + +class R1(Space): + """The space for one dimensional real numbers. + Parameters ---------- variable_name: str The name of the variable that belongs to this space. - It can be any string for coordinate axes. """ def __init__(self, variable_name): - super().__init__(variable_name, 1) + super().__init__({variable_name: 1}) + class R2(Space): - """ - Space to define 2D domain. - + """The space for two dimensional real numbers. + Parameters ---------- variable_name: str The name of the variable that belongs to this space. - It can be any string for coordinate axes. """ def __init__(self, variable_name): - super().__init__(variable_name, 2) + super().__init__({variable_name: 2}) + class R3(Space): - """ - Space to define 3D domain. - + """The space for three dimensional real numbers. + Parameters ---------- variable_name: str The name of the variable that belongs to this space. - It can be any string for coordinate axes. """ def __init__(self, variable_name): - super().__init__(variable_name, 3) \ No newline at end of file + super().__init__({variable_name: 3}) + + +class Rn(Space): + """The space for n dimensional real numbers. + + Parameters + ---------- + variable_name: str + The name of the variable that belongs to this space. + n : int + The dimension of this space. + """ + def __init__(self, variable_name, n : int): + super().__init__({variable_name: n}) + + +# class M(Space): +# """The space for n x m matricies. (currently only real numbers) + +# Parameters +# ---------- +# variable_name: str +# The name of the variable that belongs to this space. +# n : int +# The number of rows of the matricies. +# m : int +# The number of columns. +# """ +# def __init__(self, variable_name, n : int, m : int): +# self.rows = n +# self.columns = m +# super().__init__({variable_name: n*m}) + +# def __mul__(self, other): +# raise NotImplementedError("Matrix-spaces can not be multiplied!") + +# def check_values_in_space(self, values): +# v_shape = values.shape +# if len(v_shape) >= 3 and v_shape[-2] == self.rows and v_shape[-1] == self.columns: +# # values aready in correct shape +# return values +# if values.shape[-1] == self.dim: +# # maybe values are given as a vector with correct dimension +# # -> reshape to matrix +# return values.reshape(-1, self.rows, self.columns) +# raise AssertionError("Values do not belong to a matrix-space") \ No newline at end of file diff --git a/DeepINN/geometry_legacy/__init__.py b/DeepINN/geometry_legacy/__init__.py deleted file mode 100644 index 3fc0761..0000000 --- a/DeepINN/geometry_legacy/__init__.py +++ /dev/null @@ -1,5 +0,0 @@ -# Make the subdirectory callable -from . import domains -#from . import conditions -from . import samplers -from . import spaces \ No newline at end of file diff --git a/DeepINN/geometry_legacy/spaces/__init__.py b/DeepINN/geometry_legacy/spaces/__init__.py deleted file mode 100644 index 3606008..0000000 --- a/DeepINN/geometry_legacy/spaces/__init__.py +++ /dev/null @@ -1,17 +0,0 @@ -"""Contains the Spaces and Points classes. - -Spaces - It's purpose is to define variable names and dimensions that can - be used in functions, domains, models and more. - -Points - The ``Points`` object is a central part of TorchPhysics. They consit of a PyTorch-Tensor - and a space. ``Points`` store data in a tensor with 2-axis, the first corresponding - the batch-dimension in a batch of multiple points. - The second axis collects the space dimensionalities. -""" - -from .space import (Space, - R1, R2, R3, Rn) -from .points import Points -from .functionspace import FunctionSpace \ No newline at end of file diff --git a/DeepINN/geometry_legacy/spaces/space.py b/DeepINN/geometry_legacy/spaces/space.py deleted file mode 100644 index c3f10ba..0000000 --- a/DeepINN/geometry_legacy/spaces/space.py +++ /dev/null @@ -1,198 +0,0 @@ -from collections import Counter, OrderedDict - - -class Space(Counter, OrderedDict): - """A Space defines (and assigns) the dimensions of the variables - that appear in the differentialequation. This class sholud not be instanced - directly, rather the corresponding child classes. - - Parameters - ---------- - variables_dims : dict - A dictionary containing the name of the variables and the dimension - of the respective variable. - """ - def __init__(self, variables_dims): - # set counter of variable names and their dimensionalities - super().__init__(variables_dims) - - def __mul__(self, other): - """Creates the product space of the two input spaces. Allows the - construction of higher dimensional spaces with 'mixed' variable names. - E.g R1('x')*R1('y') is a two dimensional space where one axis is 'x' - and the other stands for 'y'. - """ - assert isinstance(other, Space) - return Space(self + other) - - def __contains__(self, space): - """Checks if the variables of the other space are contained in this - space. - - Parameters - ---------- - space : torchphysics.spaces.Space - The other Space that should be checked if this is included. - """ - if isinstance(space, str): - return super().__contains__(space) - if isinstance(space, Space): - return (self & space) == space - else: - return False - - def __getitem__(self, val): - """Returns a part of the Space dicitionary, specified in the - input. Mathematically, this constructs a subspace. - - Parameters - ---------- - val : str, slice, list or tuple - The keys that correspond to the variables that should be used in the - subspace. - """ - if isinstance(val, slice): - keys = list(self.keys()) - new_slice = slice(keys.index(val.start) if val.start is not None else None, - keys.index(val.stop) if val.stop is not None else None, - val.step) - new_keys = keys[new_slice] - return Space({k: self[k] for k in new_keys}) - if isinstance(val, list) or isinstance(val, tuple): - return Space({k: self[k] for k in val}) - else: - return super().__getitem__(val) - - @property - def dim(self): - """Returns the dimension of the space (sum of factor spaces) - """ - return sum(self.values()) - - @property - def variables(self): - """ - A unordered (!) set of variables. - """ - return set(self.keys()) - - def __eq__(self, o: object) -> bool: - # use OrderedDict equal methode to get order-sensitive comparision - return OrderedDict.__eq__(self, o) - - def __ne__(self, o: object) -> bool: - return OrderedDict.__ne__(self, o) - - """ - Python recipe (see official Python docs) to maintain the insertion order. - This way, dimensions with identical variable names will be joined, all - other dimensions will be kept in the order of their creation by products - or __init__. - """ - def __repr__(self): - return '%s(%r)' % (self.__class__.__name__, dict(OrderedDict(self))) - - def __reduce__(self): - return self.__class__, (OrderedDict(self),) - - def check_values_in_space(self, values): - """Checks if a given tensor is valid to belong to this space. - - Parameters - ---------- - values : torch.tensor - A tensor of values that should be checked. - Generally the last dimension of the tensor has to fit - the dimension of this space. - - Returns - ------- - torch.tensor - In the case, that the values have not the corrected shape, but can - be reshaped, thet reshaped values are returned. - This is used in the matrix-space. - """ - assert values.shape[-1] == self.dim - return values - - -class R1(Space): - """The space for one dimensional real numbers. - - Parameters - ---------- - variable_name: str - The name of the variable that belongs to this space. - """ - def __init__(self, variable_name): - super().__init__({variable_name: 1}) - - -class R2(Space): - """The space for two dimensional real numbers. - - Parameters - ---------- - variable_name: str - The name of the variable that belongs to this space. - """ - def __init__(self, variable_name): - super().__init__({variable_name: 2}) - - -class R3(Space): - """The space for three dimensional real numbers. - - Parameters - ---------- - variable_name: str - The name of the variable that belongs to this space. - """ - def __init__(self, variable_name): - super().__init__({variable_name: 3}) - - -class Rn(Space): - """The space for n dimensional real numbers. - - Parameters - ---------- - variable_name: str - The name of the variable that belongs to this space. - n : int - The dimension of this space. - """ - def __init__(self, variable_name, n : int): - super().__init__({variable_name: n}) - - -# class M(Space): -# """The space for n x m matricies. (currently only real numbers) - -# Parameters -# ---------- -# variable_name: str -# The name of the variable that belongs to this space. -# n : int -# The number of rows of the matricies. -# m : int -# The number of columns. -# """ -# def __init__(self, variable_name, n : int, m : int): -# self.rows = n -# self.columns = m -# super().__init__({variable_name: n*m}) - -# def __mul__(self, other): -# raise NotImplementedError("Matrix-spaces can not be multiplied!") - -# def check_values_in_space(self, values): -# v_shape = values.shape -# if len(v_shape) >= 3 and v_shape[-2] == self.rows and v_shape[-1] == self.columns: -# # values aready in correct shape -# return values -# if values.shape[-1] == self.dim: -# # maybe values are given as a vector with correct dimension -# # -> reshape to matrix -# return values.reshape(-1, self.rows, self.columns) -# raise AssertionError("Values do not belong to a matrix-space") \ No newline at end of file diff --git a/DeepINN/geometry_refactor/__init__.py b/DeepINN/geometry_refactor/__init__.py new file mode 100644 index 0000000..fc80254 --- /dev/null +++ b/DeepINN/geometry_refactor/__init__.py @@ -0,0 +1 @@ +pass \ No newline at end of file diff --git a/DeepINN/geometry/points.py b/DeepINN/geometry_refactor/points.py similarity index 100% rename from DeepINN/geometry/points.py rename to DeepINN/geometry_refactor/points.py diff --git a/DeepINN/geometry_refactor/spaces/__init__.py b/DeepINN/geometry_refactor/spaces/__init__.py new file mode 100644 index 0000000..1515c26 --- /dev/null +++ b/DeepINN/geometry_refactor/spaces/__init__.py @@ -0,0 +1 @@ +from .space import Space, R1, R2, R3 \ No newline at end of file diff --git a/DeepINN/geometry_refactor/spaces/space.py b/DeepINN/geometry_refactor/spaces/space.py new file mode 100644 index 0000000..0512b90 --- /dev/null +++ b/DeepINN/geometry_refactor/spaces/space.py @@ -0,0 +1,147 @@ +from collections import Counter, OrderedDict + +""" +* A Counter is a dict subclass for counting hashable objects. It is a collection where elements are stored as dictionary keys and their counts are stored as dictionary values. +* An OrderedDict is a dictionary subclass that remembers the order in which items are inserted. +""" + +class Space(Counter, OrderedDict): + """ + Base class to define the dimensions of the variables in the differential equation. + + Parameters + ---------- + variables_dims: dict + A dict containing name of variables and the dimension of each variable. + """ + def __init__(self, variables_dims): + # set counter of variable names and their dimensionalities + # Since the Counter is inherited first, if the super().__init__ is consumed by Counter then the second super class won't receive the call. + super().__init__(variables_dims) + + # # Adding a magic method to overload the multiply operator using __mul__ + # def __mul__(self, additional_space): + # """ + # Combine two spaces to create higher dimension spaces. + # E.g R1('x')*R1('y') is a two dimensional space where one axis is 'x' + # and the other stands for 'y'. + # """ + # assert isinstance(additional_space, Space), "The additional dimension isn't an instance of Space" + # # Since we haven't defined __add__. Python will use Counter's __add__ method + # return Space(self + additional_space) + + # # __contains__ is a predefined method checks if the key (a string) is present in the counter. + # # whenever we use `in` keyword with if condition involving instances of Space object, this self.__contains__ will run be override python's default __contains__. + # # here we override this functionpython's default __contains__ + # # So if we do addition __add__ we will end up executing self.__contains__ + # def __contains__(self, space): + # """ + # Check if the variables of other space are container in this space. + # There are two possibilities. + # * method executed for internal dictionary operations such as addition + # * method executed when checking if intersection of space and self is space. + # That is why we need to modify python default __contains__ for instances of Space. + + # ChatGPT's description: + # Override the membership test (in) for the Space class. + # - If `space` is a string: Checks if the variable name (key) exists in this Space. + # This is useful for both direct membership tests and internal operations + # (e.g., during dictionary-style key checking in addition). + + # - If `space` is another Space object: Determines if the provided Space is + # entirely contained within the current Space (i.e., if it's a subset). + # """ + # if isinstance(space,str): + # #print("Flag: string") + # # check if the space already contains the variable names. + # return super().__contains__(space) + # if isinstance(space, Space): + # #print("Flag: Space") + # return (self & space) == space + # else: + # return False + + # # This is a special method in Python which is invoked when we try to access items from containers like array or dictionary. + # # It's what gets called when you use square bracket notation to access elements, such as with lists, dictionaries, and strings. + # def __getitem__(self, val): + # """ + # Since __getitem__ is used to retrieve items. There are three ways to retrieve items. str, slice, list or tuple. + + # 1. In the case of a slice. + # space_obj = Space({'a': 1, 'b': 2, 'c': 3, 'd': 4}) + # sub_space = space_obj['a':'c'] # returns a Space with {'a': 1, 'b': 2, 'c': 3} + + # 2. In the case of a tuple or a list + # space_obj = Space({'a': 1, 'b': 2, 'c': 3, 'd': 4}) + # sub_space = space_obj[['a', 'c']] # returns a Space with {'a': 1, 'c': 3} + + # 3. In all other cases then use Counter's __getitem__. + # space_obj = Space({'a': 1, 'b': 2, 'c': 3, 'd': 4}) + # value = space_obj['a'] # returns 1 + + # Parameters + # ---------- + # val : str, slice, list or tuple + # The keys that correspond to the variables that should be used in the + # subspace. + # """ + # if isinstance(val, slice): # if val is a slice + # keys = list(self.keys()) + # new_slice = slice(keys.index(val.start) if val.start is not None else None, + # keys.index(val.stop) if val.stop is not None else None, + # val.step) + # new_keys = keys[new_slice] + # return Space({k: self[k] for k in new_keys}) + # if isinstance(val, list) or isinstance(val, tuple): + # return Space({k: self[k] for k in val}) + # else: + # return super().__getitem__(val) + + # # To promote encapsulation, @property decorator allows you to print internal read-only attributes of choice. + # # @property also allows you to call a function without the parentheses. This is useful when these isn't any input attribute. + # @property + # def dim(self): + # """ + # Return the dimension of the space. + # """ + # # self is the class Space inheriting Counter, which inherits dict, so values() will return list of values for each key of variables_dims. then sum will sum them up. + # return sum(self.values()) + +class R1(Space): + """ + Space to define 1D domain. + + Parameters + ---------- + variable_name: str + The name of the variable that belongs to this space. + It can be any string for coordinate axes. + """ + def __init__(self, variable_name): + super().__init__(variable_name, 1) + +class R2(Space): + """ + Space to define 2D domain. + + Parameters + ---------- + variable_name: str + The name of the variable that belongs to this space. + It can be any string for coordinate axes. + """ + def __init__(self, variable_name): + super().__init__(variable_name, 2) + +class R3(Space): + """ + Space to define 3D domain. + + Parameters + ---------- + variable_name: str + The name of the variable that belongs to this space. + It can be any string for coordinate axes. + """ + def __init__(self, variable_name): + super().__init__(variable_name, 3) \ No newline at end of file diff --git a/DeepINN/model.py b/DeepINN/model.py index f74611d..5cc21cc 100644 --- a/DeepINN/model.py +++ b/DeepINN/model.py @@ -26,7 +26,7 @@ def compile(self, optimiser_string : str, lr : float, metrics_string : str, devi self.compile_network() def compile_domain(self): - # sample collcation points + # sample collocation points self.collocation_point_sample, self.collocation_point_labels = self.domain.sample_collocation_labels() # sample boundary points @@ -54,7 +54,7 @@ def train(self, iterations : int = None, display_every : int = None): self.config.apply_float_type() self.config.default_device() - # In 1D problem we need to combine the BCs as there is only one point for each BC, which returns an underfined feature scaling because the ub and lb are same in the denominator + # In 1D problem we need to combine the BCs as there is only one point for each BC, which returns an undefined feature scaling because the ub and lb are same in the denominator, so we get infinity # For problem with multiple points on each boundary, we don't need to combine them. if self.boundary_point_sample[0].size()[0] == 1: # if row is 1 in the particular boundary tensor self.boundary_point_sample = torch.cat(self.boundary_point_sample, dim=0) @@ -80,7 +80,7 @@ def train(self, iterations : int = None, display_every : int = None): # backprop the total loss self.total_loss.backward() - # Update model parameters based on the older values and the backproped gradient + # Update model parameters based on the older values and the backprop gradient self.optimiser.step() if self.iter % (self.iterations/10) == 0: print(f"Iteration: {self.iter+1} \t BC Loss: {self.BC_loss:0.4f}\t PDE Loss: {self.PDE_loss:0.4f} \t Loss: {self.total_loss:0.4f}") diff --git a/Tutorials/5. FCNN/3. model.ipynb b/Tutorials/5. FCNN/3. model.ipynb index 5ef4669..a47a5c8 100644 --- a/Tutorials/5. FCNN/3. model.ipynb +++ b/Tutorials/5. FCNN/3. model.ipynb @@ -9,18 +9,9 @@ }, { "cell_type": "code", - "execution_count": 1, + "execution_count": 21, "metadata": {}, - "outputs": [ - { - "name": "stderr", - "output_type": "stream", - "text": [ - "Using default backend: PyTorch\n", - "Using Pytorch: 2.0.1+cu117\n" - ] - } - ], + "outputs": [], "source": [ "# This is only valid when the package is not installed\n", "import sys\n", @@ -38,7 +29,7 @@ }, { "cell_type": "code", - "execution_count": 2, + "execution_count": 22, "metadata": {}, "outputs": [], "source": [ @@ -49,7 +40,7 @@ }, { "cell_type": "code", - "execution_count": 3, + "execution_count": 23, "metadata": {}, "outputs": [], "source": [ @@ -70,7 +61,7 @@ }, { "cell_type": "code", - "execution_count": 4, + "execution_count": 24, "metadata": {}, "outputs": [], "source": [ @@ -88,7 +79,7 @@ }, { "cell_type": "code", - "execution_count": 5, + "execution_count": 25, "metadata": {}, "outputs": [], "source": [ @@ -105,7 +96,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 26, "metadata": {}, "outputs": [], "source": [ @@ -123,7 +114,7 @@ }, { "cell_type": "code", - "execution_count": 7, + "execution_count": 27, "metadata": {}, "outputs": [], "source": [ @@ -134,7 +125,7 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 28, "metadata": {}, "outputs": [], "source": [ @@ -144,7 +135,7 @@ }, { "cell_type": "code", - "execution_count": 9, + "execution_count": 29, "metadata": {}, "outputs": [ { @@ -171,7 +162,7 @@ }, { "cell_type": "code", - "execution_count": 10, + "execution_count": 30, "metadata": {}, "outputs": [ { @@ -180,7 +171,7 @@ "(torch.optim.adam.Adam, 0.001, MSELoss())" ] }, - "execution_count": 10, + "execution_count": 30, "metadata": {}, "output_type": "execute_result" } @@ -191,41 +182,130 @@ }, { "cell_type": "code", - "execution_count": 11, + "execution_count": 31, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "Iteration: 1 \t BC Loss: 2.1174\t PDE Loss: 12.3646 \t Loss: 14.4820\n", - "Iteration: 11 \t BC Loss: 1.9977\t PDE Loss: 11.2331 \t Loss: 13.2308\n", - "Iteration: 21 \t BC Loss: 1.8826\t PDE Loss: 10.1766 \t Loss: 12.0593\n", - "Iteration: 31 \t BC Loss: 1.7726\t PDE Loss: 9.2003 \t Loss: 10.9729\n", - "Iteration: 41 \t BC Loss: 1.6678\t PDE Loss: 8.3045 \t Loss: 9.9723\n", - "Iteration: 51 \t BC Loss: 1.5684\t PDE Loss: 7.4863 \t Loss: 9.0548\n", - "Iteration: 61 \t BC Loss: 1.4745\t PDE Loss: 6.7411 \t Loss: 8.2156\n", - "Iteration: 71 \t BC Loss: 1.3859\t PDE Loss: 6.0632 \t Loss: 7.4491\n", - "Iteration: 81 \t BC Loss: 1.3025\t PDE Loss: 5.4470 \t Loss: 6.7495\n", - "Iteration: 91 \t BC Loss: 1.2241\t PDE Loss: 4.8870 \t Loss: 6.1111\n", - "Iteration: 101 \t BC Loss: 1.1505\t PDE Loss: 4.3783 \t Loss: 5.5287\n", + "Iteration: 1 \t BC Loss: 0.2236\t PDE Loss: 1.2173 \t Loss: 1.4410\n", + "Iteration: 501 \t BC Loss: 0.2387\t PDE Loss: 0.0058 \t Loss: 0.2445\n", + "Iteration: 1001 \t BC Loss: 0.2386\t PDE Loss: 0.0054 \t Loss: 0.2440\n", + "Iteration: 1501 \t BC Loss: 0.2385\t PDE Loss: 0.0055 \t Loss: 0.2440\n", + "Iteration: 2001 \t BC Loss: 0.2385\t PDE Loss: 0.0055 \t Loss: 0.2440\n", + "Iteration: 2501 \t BC Loss: 0.2385\t PDE Loss: 0.0055 \t Loss: 0.2440\n", + "Iteration: 3001 \t BC Loss: 0.2384\t PDE Loss: 0.0055 \t Loss: 0.2439\n", + "Iteration: 3501 \t BC Loss: 0.2384\t PDE Loss: 0.0055 \t Loss: 0.2439\n", + "Iteration: 4001 \t BC Loss: 0.2383\t PDE Loss: 0.0055 \t Loss: 0.2439\n", + "Iteration: 4501 \t BC Loss: 0.2383\t PDE Loss: 0.0056 \t Loss: 0.2438\n", + "Iteration: 5001 \t BC Loss: 0.2382\t PDE Loss: 0.0056 \t Loss: 0.2438\n", "Training finished\n" ] } ], "source": [ - "model.train(iterations = 100)" + "model.train(iterations = 5000)" ] }, { "cell_type": "code", - "execution_count": 12, + "execution_count": 32, "metadata": {}, "outputs": [], "source": [ "# model.iter = 1\n", "# model.train(iterations = 2000)" ] + }, + { + "cell_type": "code", + "execution_count": 33, + "metadata": {}, + "outputs": [], + "source": [ + "import matplotlib.pyplot as plt" + ] + }, + { + "cell_type": "code", + "execution_count": 34, + "metadata": {}, + "outputs": [ + { + "data": { + "text/plain": [ + "tensor([[0.0476],\n", + " [0.0952],\n", + " [0.1429],\n", + " [0.1905],\n", + " [0.2381],\n", + " [0.2857],\n", + " [0.3333],\n", + " [0.3810],\n", + " [0.4286],\n", + " [0.4762],\n", + " [0.5238],\n", + " [0.5714],\n", + " [0.6190],\n", + " [0.6667],\n", + " [0.7143],\n", + " [0.7619],\n", + " [0.8095],\n", + " [0.8571],\n", + " [0.9048],\n", + " [0.9524]], device='cuda:0', requires_grad=True)" + ] + }, + "execution_count": 34, + "metadata": {}, + "output_type": "execute_result" + } + ], + "source": [ + "model.collocation_point_sample" + ] + }, + { + "cell_type": "code", + "execution_count": 35, + "metadata": {}, + "outputs": [ + { + "ename": "TypeError", + "evalue": "can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first.", + "output_type": "error", + "traceback": [ + "\u001b[0;31m---------------------------------------------------------------------------\u001b[0m", + "\u001b[0;31mTypeError\u001b[0m Traceback (most recent call last)", + "\u001b[1;32m/home/hell/Desktop/repos/DeepINN/Tutorials/5. FCNN/3. model.ipynb Cell 19\u001b[0m line \u001b[0;36m1\n\u001b[0;32m----> 1\u001b[0m plt\u001b[39m.\u001b[39;49mscatter(model\u001b[39m.\u001b[39;49mcollocation_point_sample, model\u001b[39m.\u001b[39;49mBC_forward)\n", + "File \u001b[0;32m~/Desktop/repos/DeepINN/.venv/lib/python3.8/site-packages/matplotlib/pyplot.py:2862\u001b[0m, in \u001b[0;36mscatter\u001b[0;34m(x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, edgecolors, plotnonfinite, data, **kwargs)\u001b[0m\n\u001b[1;32m 2857\u001b[0m \u001b[39m@_copy_docstring_and_deprecators\u001b[39m(Axes\u001b[39m.\u001b[39mscatter)\n\u001b[1;32m 2858\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39mscatter\u001b[39m(\n\u001b[1;32m 2859\u001b[0m x, y, s\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, c\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, marker\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, cmap\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, norm\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m,\n\u001b[1;32m 2860\u001b[0m vmin\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, vmax\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, alpha\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, linewidths\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, \u001b[39m*\u001b[39m,\n\u001b[1;32m 2861\u001b[0m edgecolors\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, plotnonfinite\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m, data\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs):\n\u001b[0;32m-> 2862\u001b[0m __ret \u001b[39m=\u001b[39m gca()\u001b[39m.\u001b[39;49mscatter(\n\u001b[1;32m 2863\u001b[0m x, y, s\u001b[39m=\u001b[39;49ms, c\u001b[39m=\u001b[39;49mc, marker\u001b[39m=\u001b[39;49mmarker, cmap\u001b[39m=\u001b[39;49mcmap, norm\u001b[39m=\u001b[39;49mnorm,\n\u001b[1;32m 2864\u001b[0m vmin\u001b[39m=\u001b[39;49mvmin, vmax\u001b[39m=\u001b[39;49mvmax, alpha\u001b[39m=\u001b[39;49malpha, linewidths\u001b[39m=\u001b[39;49mlinewidths,\n\u001b[1;32m 2865\u001b[0m edgecolors\u001b[39m=\u001b[39;49medgecolors, plotnonfinite\u001b[39m=\u001b[39;49mplotnonfinite,\n\u001b[1;32m 2866\u001b[0m \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49m({\u001b[39m\"\u001b[39;49m\u001b[39mdata\u001b[39;49m\u001b[39m\"\u001b[39;49m: data} \u001b[39mif\u001b[39;49;00m data \u001b[39mis\u001b[39;49;00m \u001b[39mnot\u001b[39;49;00m \u001b[39mNone\u001b[39;49;00m \u001b[39melse\u001b[39;49;00m {}), \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 2867\u001b[0m sci(__ret)\n\u001b[1;32m 2868\u001b[0m \u001b[39mreturn\u001b[39;00m __ret\n", + "File \u001b[0;32m~/Desktop/repos/DeepINN/.venv/lib/python3.8/site-packages/matplotlib/__init__.py:1442\u001b[0m, in \u001b[0;36m_preprocess_data..inner\u001b[0;34m(ax, data, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1439\u001b[0m \u001b[39m@functools\u001b[39m\u001b[39m.\u001b[39mwraps(func)\n\u001b[1;32m 1440\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39minner\u001b[39m(ax, \u001b[39m*\u001b[39margs, data\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs):\n\u001b[1;32m 1441\u001b[0m \u001b[39mif\u001b[39;00m data \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m-> 1442\u001b[0m \u001b[39mreturn\u001b[39;00m func(ax, \u001b[39m*\u001b[39;49m\u001b[39mmap\u001b[39;49m(sanitize_sequence, args), \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n\u001b[1;32m 1444\u001b[0m bound \u001b[39m=\u001b[39m new_sig\u001b[39m.\u001b[39mbind(ax, \u001b[39m*\u001b[39margs, \u001b[39m*\u001b[39m\u001b[39m*\u001b[39mkwargs)\n\u001b[1;32m 1445\u001b[0m auto_label \u001b[39m=\u001b[39m (bound\u001b[39m.\u001b[39marguments\u001b[39m.\u001b[39mget(label_namer)\n\u001b[1;32m 1446\u001b[0m \u001b[39mor\u001b[39;00m bound\u001b[39m.\u001b[39mkwargs\u001b[39m.\u001b[39mget(label_namer))\n", + "File \u001b[0;32m~/Desktop/repos/DeepINN/.venv/lib/python3.8/site-packages/matplotlib/axes/_axes.py:4581\u001b[0m, in \u001b[0;36mAxes.scatter\u001b[0;34m(self, x, y, s, c, marker, cmap, norm, vmin, vmax, alpha, linewidths, edgecolors, plotnonfinite, **kwargs)\u001b[0m\n\u001b[1;32m 4578\u001b[0m x, y \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m_process_unit_info([(\u001b[39m\"\u001b[39m\u001b[39mx\u001b[39m\u001b[39m\"\u001b[39m, x), (\u001b[39m\"\u001b[39m\u001b[39my\u001b[39m\u001b[39m\"\u001b[39m, y)], kwargs)\n\u001b[1;32m 4579\u001b[0m \u001b[39m# np.ma.ravel yields an ndarray, not a masked array,\u001b[39;00m\n\u001b[1;32m 4580\u001b[0m \u001b[39m# unless its argument is a masked array.\u001b[39;00m\n\u001b[0;32m-> 4581\u001b[0m x \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39;49mma\u001b[39m.\u001b[39;49mravel(x)\n\u001b[1;32m 4582\u001b[0m y \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39mma\u001b[39m.\u001b[39mravel(y)\n\u001b[1;32m 4583\u001b[0m \u001b[39mif\u001b[39;00m x\u001b[39m.\u001b[39msize \u001b[39m!=\u001b[39m y\u001b[39m.\u001b[39msize:\n", + "File \u001b[0;32m~/Desktop/repos/DeepINN/.venv/lib/python3.8/site-packages/numpy/ma/core.py:6852\u001b[0m, in \u001b[0;36m_frommethod.__call__\u001b[0;34m(self, a, *args, **params)\u001b[0m\n\u001b[1;32m 6849\u001b[0m args \u001b[39m=\u001b[39m \u001b[39mlist\u001b[39m(args)\n\u001b[1;32m 6850\u001b[0m a, args[\u001b[39m0\u001b[39m] \u001b[39m=\u001b[39m args[\u001b[39m0\u001b[39m], a\n\u001b[0;32m-> 6852\u001b[0m marr \u001b[39m=\u001b[39m asanyarray(a)\n\u001b[1;32m 6853\u001b[0m method_name \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39m\u001b[39m__name__\u001b[39m\n\u001b[1;32m 6854\u001b[0m method \u001b[39m=\u001b[39m \u001b[39mgetattr\u001b[39m(\u001b[39mtype\u001b[39m(marr), method_name, \u001b[39mNone\u001b[39;00m)\n", + "File \u001b[0;32m~/Desktop/repos/DeepINN/.venv/lib/python3.8/site-packages/numpy/ma/core.py:8132\u001b[0m, in \u001b[0;36masanyarray\u001b[0;34m(a, dtype)\u001b[0m\n\u001b[1;32m 8130\u001b[0m \u001b[39mif\u001b[39;00m \u001b[39misinstance\u001b[39m(a, MaskedArray) \u001b[39mand\u001b[39;00m (dtype \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m \u001b[39mor\u001b[39;00m dtype \u001b[39m==\u001b[39m a\u001b[39m.\u001b[39mdtype):\n\u001b[1;32m 8131\u001b[0m \u001b[39mreturn\u001b[39;00m a\n\u001b[0;32m-> 8132\u001b[0m \u001b[39mreturn\u001b[39;00m masked_array(a, dtype\u001b[39m=\u001b[39;49mdtype, copy\u001b[39m=\u001b[39;49m\u001b[39mFalse\u001b[39;49;00m, keep_mask\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m, subok\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m)\n", + "File \u001b[0;32m~/Desktop/repos/DeepINN/.venv/lib/python3.8/site-packages/numpy/ma/core.py:2820\u001b[0m, in \u001b[0;36mMaskedArray.__new__\u001b[0;34m(cls, data, mask, dtype, copy, subok, ndmin, fill_value, keep_mask, hard_mask, shrink, order)\u001b[0m\n\u001b[1;32m 2811\u001b[0m \u001b[39m\u001b[39m\u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 2812\u001b[0m \u001b[39mCreate a new masked array from scratch.\u001b[39;00m\n\u001b[1;32m 2813\u001b[0m \n\u001b[0;32m (...)\u001b[0m\n\u001b[1;32m 2817\u001b[0m \n\u001b[1;32m 2818\u001b[0m \u001b[39m\"\"\"\u001b[39;00m\n\u001b[1;32m 2819\u001b[0m \u001b[39m# Process data.\u001b[39;00m\n\u001b[0;32m-> 2820\u001b[0m _data \u001b[39m=\u001b[39m np\u001b[39m.\u001b[39;49marray(data, dtype\u001b[39m=\u001b[39;49mdtype, copy\u001b[39m=\u001b[39;49mcopy,\n\u001b[1;32m 2821\u001b[0m order\u001b[39m=\u001b[39;49morder, subok\u001b[39m=\u001b[39;49m\u001b[39mTrue\u001b[39;49;00m, ndmin\u001b[39m=\u001b[39;49mndmin)\n\u001b[1;32m 2822\u001b[0m _baseclass \u001b[39m=\u001b[39m \u001b[39mgetattr\u001b[39m(data, \u001b[39m'\u001b[39m\u001b[39m_baseclass\u001b[39m\u001b[39m'\u001b[39m, \u001b[39mtype\u001b[39m(_data))\n\u001b[1;32m 2823\u001b[0m \u001b[39m# Check that we're not erasing the mask.\u001b[39;00m\n", + "File \u001b[0;32m~/Desktop/repos/DeepINN/.venv/lib/python3.8/site-packages/torch/_tensor.py:968\u001b[0m, in \u001b[0;36mTensor.__array__\u001b[0;34m(self, dtype)\u001b[0m\n\u001b[1;32m 966\u001b[0m \u001b[39mdef\u001b[39;00m \u001b[39m__array__\u001b[39m(\u001b[39mself\u001b[39m, dtype\u001b[39m=\u001b[39m\u001b[39mNone\u001b[39;00m):\n\u001b[1;32m 967\u001b[0m \u001b[39mif\u001b[39;00m has_torch_function_unary(\u001b[39mself\u001b[39m):\n\u001b[0;32m--> 968\u001b[0m \u001b[39mreturn\u001b[39;00m handle_torch_function(Tensor\u001b[39m.\u001b[39;49m__array__, (\u001b[39mself\u001b[39;49m,), \u001b[39mself\u001b[39;49m, dtype\u001b[39m=\u001b[39;49mdtype)\n\u001b[1;32m 969\u001b[0m \u001b[39mif\u001b[39;00m dtype \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m 970\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnumpy()\n", + "File \u001b[0;32m~/Desktop/repos/DeepINN/.venv/lib/python3.8/site-packages/torch/overrides.py:1534\u001b[0m, in \u001b[0;36mhandle_torch_function\u001b[0;34m(public_api, relevant_args, *args, **kwargs)\u001b[0m\n\u001b[1;32m 1530\u001b[0m \u001b[39mif\u001b[39;00m _is_torch_function_mode_enabled():\n\u001b[1;32m 1531\u001b[0m \u001b[39m# if we're here, the mode must be set to a TorchFunctionStackMode\u001b[39;00m\n\u001b[1;32m 1532\u001b[0m \u001b[39m# this unsets it and calls directly into TorchFunctionStackMode's torch function\u001b[39;00m\n\u001b[1;32m 1533\u001b[0m \u001b[39mwith\u001b[39;00m _pop_mode_temporarily() \u001b[39mas\u001b[39;00m mode:\n\u001b[0;32m-> 1534\u001b[0m result \u001b[39m=\u001b[39m mode\u001b[39m.\u001b[39;49m__torch_function__(public_api, types, args, kwargs)\n\u001b[1;32m 1535\u001b[0m \u001b[39mif\u001b[39;00m result \u001b[39mis\u001b[39;00m \u001b[39mnot\u001b[39;00m \u001b[39mNotImplemented\u001b[39m:\n\u001b[1;32m 1536\u001b[0m \u001b[39mreturn\u001b[39;00m result\n", + "File \u001b[0;32m~/Desktop/repos/DeepINN/.venv/lib/python3.8/site-packages/torch/utils/_device.py:62\u001b[0m, in \u001b[0;36mDeviceContext.__torch_function__\u001b[0;34m(self, func, types, args, kwargs)\u001b[0m\n\u001b[1;32m 60\u001b[0m \u001b[39mif\u001b[39;00m func \u001b[39min\u001b[39;00m _device_constructors() \u001b[39mand\u001b[39;00m kwargs\u001b[39m.\u001b[39mget(\u001b[39m'\u001b[39m\u001b[39mdevice\u001b[39m\u001b[39m'\u001b[39m) \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[1;32m 61\u001b[0m kwargs[\u001b[39m'\u001b[39m\u001b[39mdevice\u001b[39m\u001b[39m'\u001b[39m] \u001b[39m=\u001b[39m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mdevice\n\u001b[0;32m---> 62\u001b[0m \u001b[39mreturn\u001b[39;00m func(\u001b[39m*\u001b[39;49margs, \u001b[39m*\u001b[39;49m\u001b[39m*\u001b[39;49mkwargs)\n", + "File \u001b[0;32m~/Desktop/repos/DeepINN/.venv/lib/python3.8/site-packages/torch/_tensor.py:970\u001b[0m, in \u001b[0;36mTensor.__array__\u001b[0;34m(self, dtype)\u001b[0m\n\u001b[1;32m 968\u001b[0m \u001b[39mreturn\u001b[39;00m handle_torch_function(Tensor\u001b[39m.\u001b[39m__array__, (\u001b[39mself\u001b[39m,), \u001b[39mself\u001b[39m, dtype\u001b[39m=\u001b[39mdtype)\n\u001b[1;32m 969\u001b[0m \u001b[39mif\u001b[39;00m dtype \u001b[39mis\u001b[39;00m \u001b[39mNone\u001b[39;00m:\n\u001b[0;32m--> 970\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39;49m\u001b[39m.\u001b[39;49mnumpy()\n\u001b[1;32m 971\u001b[0m \u001b[39melse\u001b[39;00m:\n\u001b[1;32m 972\u001b[0m \u001b[39mreturn\u001b[39;00m \u001b[39mself\u001b[39m\u001b[39m.\u001b[39mnumpy()\u001b[39m.\u001b[39mastype(dtype, copy\u001b[39m=\u001b[39m\u001b[39mFalse\u001b[39;00m)\n", + "\u001b[0;31mTypeError\u001b[0m: can't convert cuda:0 device type tensor to numpy. Use Tensor.cpu() to copy the tensor to host memory first." + ] + }, + { + "data": { + "image/png": "iVBORw0KGgoAAAANSUhEUgAAAi4AAAGiCAYAAADA0E3hAAAAOXRFWHRTb2Z0d2FyZQBNYXRwbG90bGliIHZlcnNpb24zLjcuMSwgaHR0cHM6Ly9tYXRwbG90bGliLm9yZy/bCgiHAAAACXBIWXMAAA9hAAAPYQGoP6dpAAAcw0lEQVR4nO3db2zdVf3A8U/b0VsItEzn2m0WKyiiAhturBYkiKk2gUz3wDjBbHPhj+AkuEZlY7CK6DoRyKIrLkwQH6ibEDDGLUOsLgapWdjWBGSDwMBNYwsT184iLWu/vweG+qvrYLf0z077eiX3wY7n3O+5Hkbf3H8tyLIsCwCABBSO9QYAAI6VcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSkXe4/OEPf4h58+bF9OnTo6CgIH75y1++5Zpt27bFRz7ykcjlcvG+970v7r///iFsFQCY6PIOl66urpg5c2Y0NTUd0/wXXnghLrvssrjkkkuitbU1vvrVr8ZVV10VjzzySN6bBQAmtoK380sWCwoK4uGHH4758+cfdc6NN94Ymzdvjqeeeqp/7POf/3wcPHgwtm7dOtRLAwAT0KSRvkBLS0vU1tYOGKurq4uvfvWrR13T3d0d3d3d/X/u6+uLV155Jd75zndGQUHBSG0VABhGWZbFoUOHYvr06VFYODxvqx3xcGlra4vy8vIBY+Xl5dHZ2Rn//ve/48QTTzxiTWNjY9x6660jvTUAYBTs378/3v3udw/LfY14uAzFihUror6+vv/PHR0dcdppp8X+/fujtLR0DHcGAByrzs7OqKysjFNOOWXY7nPEw6WioiLa29sHjLW3t0dpaemgz7ZERORyucjlckeMl5aWChcASMxwvs1jxL/HpaamJpqbmweMPfroo1FTUzPSlwYAxpm8w+Vf//pXtLa2Rmtra0T85+POra2tsW/fvoj4z8s8ixYt6p9/7bXXxt69e+Mb3/hG7NmzJ+6+++74xS9+EcuWLRueRwAATBh5h8sTTzwR5513Xpx33nkREVFfXx/nnXderFq1KiIi/v73v/dHTETEe9/73ti8eXM8+uijMXPmzLjzzjvjRz/6UdTV1Q3TQwAAJoq39T0uo6WzszPKysqio6PDe1wAIBEj8fPb7yoCAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZQwqXpqamqKqqipKSkqiuro7t27e/6fy1a9fGBz7wgTjxxBOjsrIyli1bFq+99tqQNgwATFx5h8umTZuivr4+GhoaYufOnTFz5syoq6uLl156adD5P/vZz2L58uXR0NAQu3fvjnvvvTc2bdoUN91009vePAAwseQdLnfddVdcffXVsWTJkvjQhz4U69evj5NOOinuu+++Qec//vjjceGFF8YVV1wRVVVV8alPfSouv/zyt3yWBgDgf+UVLj09PbFjx46ora397x0UFkZtbW20tLQMuuaCCy6IHTt29IfK3r17Y8uWLXHppZce9Trd3d3R2dk54AYAMCmfyQcOHIje3t4oLy8fMF5eXh579uwZdM0VV1wRBw4ciI997GORZVkcPnw4rr322jd9qaixsTFuvfXWfLYGAEwAI/6pom3btsXq1avj7rvvjp07d8ZDDz0Umzdvjttuu+2oa1asWBEdHR39t/3794/0NgGABOT1jMuUKVOiqKgo2tvbB4y3t7dHRUXFoGtuueWWWLhwYVx11VUREXHOOedEV1dXXHPNNbFy5cooLDyynXK5XORyuXy2BgBMAHk941JcXByzZ8+O5ubm/rG+vr5obm6OmpqaQde8+uqrR8RJUVFRRERkWZbvfgGACSyvZ1wiIurr62Px4sUxZ86cmDt3bqxduza6urpiyZIlERGxaNGimDFjRjQ2NkZExLx58+Kuu+6K8847L6qrq+O5556LW265JebNm9cfMAAAxyLvcFmwYEG8/PLLsWrVqmhra4tZs2bF1q1b+9+wu2/fvgHPsNx8881RUFAQN998c/ztb3+Ld73rXTFv3rz4zne+M3yPAgCYEAqyBF6v6ezsjLKysujo6IjS0tKx3g4AcAxG4ue331UEACRDuAAAyRAuAEAyhAsAkAzhAgAkQ7gAAMkQLgBAMoQLAJAM4QIAJEO4AADJEC4AQDKECwCQDOECACRDuAAAyRAuAEAyhAsAkAzhAgAkQ7gAAMkQLgBAMoQLAJAM4QIAJEO4AADJEC4AQDKECwCQDOECACRDuAAAyRAuAEAyhAsAkAzhAgAkQ7gAAMkQLgBAMoQLAJAM4QIAJEO4AADJEC4AQDKECwCQDOECACRDuAAAyRAuAEAyhAsAkAzhAgAkQ7gAAMkQLgBAMoQLAJAM4QIAJEO4AADJEC4AQDKECwCQDOECACRDuAAAyRAuAEAyhAsAkAzhAgAkQ7gAAMkQLgBAMoQLAJAM4QIAJEO4AADJEC4AQDKECwCQDOECACRDuAAAyRAuAEAyhhQuTU1NUVVVFSUlJVFdXR3bt29/0/kHDx6MpUuXxrRp0yKXy8WZZ54ZW7ZsGdKGAYCJa1K+CzZt2hT19fWxfv36qK6ujrVr10ZdXV0888wzMXXq1CPm9/T0xCc/+cmYOnVqPPjggzFjxoz4y1/+Eqeeeupw7B8AmEAKsizL8llQXV0d559/fqxbty4iIvr6+qKysjKuv/76WL58+RHz169fH9/73vdiz549ccIJJwxpk52dnVFWVhYdHR1RWlo6pPsAAEbXSPz8zuulop6entixY0fU1tb+9w4KC6O2tjZaWloGXfOrX/0qampqYunSpVFeXh5nn312rF69Onp7e496ne7u7ujs7BxwAwDIK1wOHDgQvb29UV5ePmC8vLw82traBl2zd+/eePDBB6O3tze2bNkSt9xyS9x5553x7W9/+6jXaWxsjLKysv5bZWVlPtsEAMapEf9UUV9fX0ydOjXuueeemD17dixYsCBWrlwZ69evP+qaFStWREdHR/9t//79I71NACABeb05d8qUKVFUVBTt7e0Dxtvb26OiomLQNdOmTYsTTjghioqK+sc++MEPRltbW/T09ERxcfERa3K5XORyuXy2BgBMAHk941JcXByzZ8+O5ubm/rG+vr5obm6OmpqaQddceOGF8dxzz0VfX1//2LPPPhvTpk0bNFoAAI4m75eK6uvrY8OGDfGTn/wkdu/eHdddd110dXXFkiVLIiJi0aJFsWLFiv751113Xbzyyitxww03xLPPPhubN2+O1atXx9KlS4fvUQAAE0Le3+OyYMGCePnll2PVqlXR1tYWs2bNiq1bt/a/YXffvn1RWPjfHqqsrIxHHnkkli1bFueee27MmDEjbrjhhrjxxhuH71EAABNC3t/jMhZ8jwsApGfMv8cFAGAsCRcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIxpDCpampKaqqqqKkpCSqq6tj+/btx7Ru48aNUVBQEPPnzx/KZQGACS7vcNm0aVPU19dHQ0ND7Ny5M2bOnBl1dXXx0ksvvem6F198Mb72ta/FRRddNOTNAgATW97hctddd8XVV18dS5YsiQ996EOxfv36OOmkk+K+++476pre3t74whe+ELfeemucfvrpb3mN7u7u6OzsHHADAMgrXHp6emLHjh1RW1v73zsoLIza2tpoaWk56rpvfetbMXXq1LjyyiuP6TqNjY1RVlbWf6usrMxnmwDAOJVXuBw4cCB6e3ujvLx8wHh5eXm0tbUNuuaxxx6Le++9NzZs2HDM11mxYkV0dHT03/bv35/PNgGAcWrSSN75oUOHYuHChbFhw4aYMmXKMa/L5XKRy+VGcGcAQIryCpcpU6ZEUVFRtLe3Dxhvb2+PioqKI+Y///zz8eKLL8a8efP6x/r6+v5z4UmT4plnnokzzjhjKPsGACagvF4qKi4ujtmzZ0dzc3P/WF9fXzQ3N0dNTc0R888666x48skno7W1tf/26U9/Oi655JJobW313hUAIC95v1RUX18fixcvjjlz5sTcuXNj7dq10dXVFUuWLImIiEWLFsWMGTOisbExSkpK4uyzzx6w/tRTT42IOGIcAOCt5B0uCxYsiJdffjlWrVoVbW1tMWvWrNi6dWv/G3b37dsXhYW+kBcAGH4FWZZlY72Jt9LZ2RllZWXR0dERpaWlY70dAOAYjMTPb0+NAADJEC4AQDKECwCQDOECACRDuAAAyRAuAEAyhAsAkAzhAgAkQ7gAAMkQLgBAMoQLAJAM4QIAJEO4AADJEC4AQDKECwCQDOECACRDuAAAyRAuAEAyhAsAkAzhAgAkQ7gAAMkQLgBAMoQLAJAM4QIAJEO4AADJEC4AQDKECwCQDOECACRDuAAAyRAuAEAyhAsAkAzhAgAkQ7gAAMkQLgBAMoQLAJAM4QIAJEO4AADJEC4AQDKECwCQDOECACRDuAAAyRAuAEAyhAsAkAzhAgAkQ7gAAMkQLgBAMoQLAJAM4QIAJEO4AADJEC4AQDKECwCQDOECACRDuAAAyRAuAEAyhAsAkAzhAgAkQ7gAAMkQLgBAMoQLAJAM4QIAJEO4AADJEC4AQDKECwCQjCGFS1NTU1RVVUVJSUlUV1fH9u3bjzp3w4YNcdFFF8XkyZNj8uTJUVtb+6bzAQCOJu9w2bRpU9TX10dDQ0Ps3LkzZs6cGXV1dfHSSy8NOn/btm1x+eWXx+9///toaWmJysrK+NSnPhV/+9vf3vbmAYCJpSDLsiyfBdXV1XH++efHunXrIiKir68vKisr4/rrr4/ly5e/5fre3t6YPHlyrFu3LhYtWjTonO7u7uju7u7/c2dnZ1RWVkZHR0eUlpbms10AYIx0dnZGWVnZsP78zusZl56entixY0fU1tb+9w4KC6O2tjZaWlqO6T5effXVeP311+Md73jHUec0NjZGWVlZ/62ysjKfbQIA41Re4XLgwIHo7e2N8vLyAePl5eXR1tZ2TPdx4403xvTp0wfEz/9asWJFdHR09N/279+fzzYBgHFq0mhebM2aNbFx48bYtm1blJSUHHVeLpeLXC43ijsDAFKQV7hMmTIlioqKor29fcB4e3t7VFRUvOnaO+64I9asWRO//e1v49xzz81/pwDAhJfXS0XFxcUxe/bsaG5u7h/r6+uL5ubmqKmpOeq622+/PW677bbYunVrzJkzZ+i7BQAmtLxfKqqvr4/FixfHnDlzYu7cubF27dro6uqKJUuWRETEokWLYsaMGdHY2BgREd/97ndj1apV8bOf/Syqqqr63wtz8sknx8knnzyMDwUAGO/yDpcFCxbEyy+/HKtWrYq2traYNWtWbN26tf8Nu/v27YvCwv8+kfPDH/4wenp64rOf/eyA+2loaIhvfvObb2/3AMCEkvf3uIyFkfgcOAAwssb8e1wAAMaScAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkCBcAIBnCBQBIhnABAJIhXACAZAgXACAZwgUASIZwAQCSIVwAgGQIFwAgGcIFAEiGcAEAkiFcAIBkDClcmpqaoqqqKkpKSqK6ujq2b9/+pvMfeOCBOOuss6KkpCTOOeec2LJly5A2CwBMbHmHy6ZNm6K+vj4aGhpi586dMXPmzKirq4uXXnpp0PmPP/54XH755XHllVfGrl27Yv78+TF//vx46qmn3vbmAYCJpSDLsiyfBdXV1XH++efHunXrIiKir68vKisr4/rrr4/ly5cfMX/BggXR1dUVv/71r/vHPvrRj8asWbNi/fr1g16ju7s7uru7+//c0dERp512Wuzfvz9KS0vz2S4AMEY6OzujsrIyDh48GGVlZcNyn5PymdzT0xM7duyIFStW9I8VFhZGbW1ttLS0DLqmpaUl6uvrB4zV1dXFL3/5y6Nep7GxMW699dYjxisrK/PZLgBwHPjHP/4xNuFy4MCB6O3tjfLy8gHj5eXlsWfPnkHXtLW1DTq/ra3tqNdZsWLFgNg5ePBgvOc974l9+/YN2wNnaN6oZ89+jT1ncfxwFscX53H8eOMVk3e84x3Ddp95hctoyeVykcvljhgvKyvzD+FxorS01FkcJ5zF8cNZHF+cx/GjsHD4PsSc1z1NmTIlioqKor29fcB4e3t7VFRUDLqmoqIir/kAAEeTV7gUFxfH7Nmzo7m5uX+sr68vmpubo6amZtA1NTU1A+ZHRDz66KNHnQ8AcDR5v1RUX18fixcvjjlz5sTcuXNj7dq10dXVFUuWLImIiEWLFsWMGTOisbExIiJuuOGGuPjii+POO++Myy67LDZu3BhPPPFE3HPPPcd8zVwuFw0NDYO+fMTochbHD2dx/HAWxxfncfwYibPI++PQERHr1q2L733ve9HW1hazZs2K73//+1FdXR0RER//+Mejqqoq7r///v75DzzwQNx8883x4osvxvvf//64/fbb49JLLx22BwEATAxDChcAgLHgdxUBAMkQLgBAMoQLAJAM4QIAJOO4CZempqaoqqqKkpKSqK6uju3bt7/p/AceeCDOOuusKCkpiXPOOSe2bNkySjsd//I5iw0bNsRFF10UkydPjsmTJ0dtbe1bnh3HLt+/F2/YuHFjFBQUxPz580d2gxNIvmdx8ODBWLp0aUybNi1yuVyceeaZ/j01TPI9i7Vr18YHPvCBOPHEE6OysjKWLVsWr7322ijtdvz6wx/+EPPmzYvp06dHQUHBm/4Owjds27YtPvKRj0Qul4v3ve99Az6BfMyy48DGjRuz4uLi7L777sv+/Oc/Z1dffXV26qmnZu3t7YPO/+Mf/5gVFRVlt99+e/b0009nN998c3bCCSdkTz755CjvfPzJ9yyuuOKKrKmpKdu1a1e2e/fu7Itf/GJWVlaW/fWvfx3lnY8/+Z7FG1544YVsxowZ2UUXXZR95jOfGZ3NjnP5nkV3d3c2Z86c7NJLL80ee+yx7IUXXsi2bduWtba2jvLOx598z+KnP/1plsvlsp/+9KfZCy+8kD3yyCPZtGnTsmXLlo3yzsefLVu2ZCtXrsweeuihLCKyhx9++E3n7927NzvppJOy+vr67Omnn85+8IMfZEVFRdnWrVvzuu5xES5z587Nli5d2v/n3t7ebPr06VljY+Og8z/3uc9ll1122YCx6urq7Etf+tKI7nMiyPcs/tfhw4ezU045JfvJT34yUlucMIZyFocPH84uuOCC7Ec/+lG2ePFi4TJM8j2LH/7wh9npp5+e9fT0jNYWJ4x8z2Lp0qXZJz7xiQFj9fX12YUXXjii+5xojiVcvvGNb2Qf/vCHB4wtWLAgq6ury+taY/5SUU9PT+zYsSNqa2v7xwoLC6O2tjZaWloGXdPS0jJgfkREXV3dUedzbIZyFv/r1Vdfjddff31YfxPoRDTUs/jWt74VU6dOjSuvvHI0tjkhDOUsfvWrX0VNTU0sXbo0ysvL4+yzz47Vq1dHb2/vaG17XBrKWVxwwQWxY8eO/peT9u7dG1u2bPElqGNguH52j/lvhz5w4ED09vZGeXn5gPHy8vLYs2fPoGva2toGnd/W1jZi+5wIhnIW/+vGG2+M6dOnH/EPJ/kZylk89thjce+990Zra+so7HDiGMpZ7N27N373u9/FF77whdiyZUs899xz8eUvfzlef/31aGhoGI1tj0tDOYsrrrgiDhw4EB/72Mciy7I4fPhwXHvttXHTTTeNxpb5f472s7uzszP+/e9/x4knnnhM9zPmz7gwfqxZsyY2btwYDz/8cJSUlIz1diaUQ4cOxcKFC2PDhg0xZcqUsd7OhNfX1xdTp06Ne+65J2bPnh0LFiyIlStXxvr168d6axPOtm3bYvXq1XH33XfHzp0746GHHorNmzfHbbfdNtZbY4jG/BmXKVOmRFFRUbS3tw8Yb29vj4qKikHXVFRU5DWfYzOUs3jDHXfcEWvWrInf/va3ce65547kNieEfM/i+eefjxdffDHmzZvXP9bX1xcREZMmTYpnnnkmzjjjjJHd9Dg1lL8X06ZNixNOOCGKior6xz74wQ9GW1tb9PT0RHFx8YjuebwaylnccsstsXDhwrjqqqsiIuKcc86Jrq6uuOaaa2LlypVRWOi/30fL0X52l5aWHvOzLRHHwTMuxcXFMXv27Ghubu4f6+vri+bm5qipqRl0TU1NzYD5ERGPPvroUedzbIZyFhERt99+e9x2222xdevWmDNnzmhsddzL9yzOOuusePLJJ6O1tbX/9ulPfzouueSSaG1tjcrKytHc/rgylL8XF154YTz33HP98RgR8eyzz8a0adNEy9swlLN49dVXj4iTN4Iy86v6RtWw/ezO733DI2Pjxo1ZLpfL7r///uzpp5/OrrnmmuzUU0/N2trasizLsoULF2bLly/vn//HP/4xmzRpUnbHHXdku3fvzhoaGnwcepjkexZr1qzJiouLswcffDD7+9//3n87dOjQWD2EcSPfs/hfPlU0fPI9i3379mWnnHJK9pWvfCV75plnsl//+tfZ1KlTs29/+9tj9RDGjXzPoqGhITvllFOyn//859nevXuz3/zmN9kZZ5yRfe5znxurhzBuHDp0KNu1a1e2a9euLCKyu+66K9u1a1f2l7/8JcuyLFu+fHm2cOHC/vlvfBz661//erZ79+6sqakp3Y9DZ1mW/eAHP8hOO+20rLi4OJs7d272pz/9qf9/u/jii7PFixcPmP+LX/wiO/PMM7Pi4uLswx/+cLZ58+ZR3vH4lc9ZvOc978ki4ohbQ0PD6G98HMr378X/J1yGV75n8fjjj2fV1dVZLpfLTj/99Ow73/lOdvjw4VHe9fiUz1m8/vrr2Te/+c3sjDPOyEpKSrLKysrsy1/+cvbPf/5z9Dc+zvz+978f9N//b/z/v3jx4uziiy8+Ys2sWbOy4uLi7PTTT89+/OMf533dgizzXBkAkIYxf48LAMCxEi4AQDKECwCQDOECACRDuAAAyRAuAEAyhAsAkAzhAgAkQ7gAAMkQLgBAMoQLAJCM/wM9kKRvAVrZIAAAAABJRU5ErkJggg==", + "text/plain": [ + "
" + ] + }, + "metadata": {}, + "output_type": "display_data" + } + ], + "source": [ + "plt.scatter(model.collocation_point_sample, model.BC_forward)" + ] } ], "metadata": { diff --git a/todo.md b/todo.md index 7eba18e..9f14fe2 100644 --- a/todo.md +++ b/todo.md @@ -2,9 +2,10 @@ Last work : `DeepINN/constraint/gradients.py` ## Geometry -- [ ] Geometry added but lot of bloats from TorchPhysics. Clean up geometry folder. +- [ ] Geometry added but lot of bloats from TorchPhysics. Clean up geometry folder. In progress in "DeepINN/geometry_refactor". - [ ] Clean up utils folder. - [ ] Implement anchor points. +- [ ] Add prediction plot function. ## Gradients - [x] Implement basic gradients. @@ -26,6 +27,7 @@ Last work : `DeepINN/constraint/gradients.py` - [x] Basic geometry tutorials. - [x] Constraints tutorials. - [ ] Add template PDE in constraint directory. +- [ ] There is some problem with FCNN tutorial. probably the feature scaling isn't working. ## Misc - [x] Migrate to JupyterBooks.