hgrecco / numbakit-ode

Leveraging numba to speed up ODE integration
Other
68 stars 3 forks source link

Better introspection #7

Open hgrecco opened 4 years ago

hgrecco commented 4 years ago

Alternative 1: subclass

class Implicit:
    pass

class Explicit
    pass

class FixedStep:
    pass

class VariableStep
    pass

and then

class Solver:

    @classproperty
    def is_implicit(cls):
        return issubclass(cls, Implicit)

and the same for others.

Pros:

Cons:

Alternative 2: enums


Step = Enum("Step", "FIXED VARIABLE")
Implicitness = Enum("Implicitness", "EXPLICIT IMPLICIT DIAGONALLY_IMPLICT")

(names and members might differ)

In the solver, add the following attributes and classproperties


class Solver:
    IMPLICITNESS

    @classproperty
    def is_implicit(cls):
        return cls.IMPLICITNESS in (Implicitness.IMPLICIT, Implicitness.DIAGONALLY_IMPLICT)

and the same for others.

Pros:

Cons:

maurosilber commented 4 years ago

In the case of implicitness, it can be introspected from the coefficients, which would let us check that there are no misclassifications or typos in coefficients:

class RungeKutta:
    def is_implicit(cls):
        """The method is implicit if any coefficient of A's upper triangle is not 0."""
        return np.any(np.triu(cls.A) != 0)

class Multistep:
    def is_implicit(cls):
        """The method is implicit if Bn is not 0."""
        return cls.Bn != 0

In Multistep, IMPLICIT is implemented as a class property.

RungeKutta doesn't have that method, but each of its specializations has a class property (explicit, implicit, diagonally_implicit) which is checked by __init_subclass__.

hgrecco commented 3 years ago

+1 on having classification done by inspecting the coefficients. +1 on adding a is_implicit classproperty -1 on having a explicit, implicit, diagonally_implicit, etc property as provides a non homogeneous API in different solvers. I lke the Implicitness (in certain cases set automatically at __init_class__)