dysts icon indicating copy to clipboard operation
dysts copied to clipboard

Consider consolidating data and equations into one place

Open shoyer opened this issue 2 years ago • 4 comments

I'm sure there are reasons why the separate JSON file is convenient, but I found it made it hard to understand exactly what dynamical systems are being solved without installing the Python package.

shoyer avatar Oct 13 '21 17:10 shoyer

Thank you so much for your comment on the code—I am always open to any suggestions on how to make the behind the scenes set up more intuitive!

The basic issue I have is that I want most information to be accessible through an object representing each dynamical system, but I want that object to include (1) a callable RHS for the diffeq and (2) fun facts about the system like its default parameters, estimated Lyapunov exponent, estimated integration timestep, citation reference, whether it’s conservative, etc

For the former, storing the information in a .py file made sense. However, I didn’t like the idea of hard-coding system-specific numbers (especially since I want to retain the ability to write to the file). Conversely, I thought about storing the RHS within the JSON database and loading into Python code when the object is initiated, but that seemed a bit messy. So I ended up splitting it into two files.

Let me know if you have any suggestions! cheers

williamgilpin avatar Oct 14 '21 02:10 williamgilpin

Hi and thank you for the very interesting work! Why not writing the system "fun facts" as object attributes? This would have the advantage of keeping RHS and system parameters close to each other in the code. I see your point of not wanting to write data in the code but I think it is quite ok to write default values in code, which can be overridden at run time if needed. Or am I missing something?

Another advantage would be that you might save momory space (currently the package is quite large) creating a template for "fun facts" which is overridden by each class only if needed.

If this makes sense to you, I could give it a try and propose an implementation.

The Lorenz class could look something like (almost pseudocode, might be some bug there)

class Lorenz(DynSys):

    def __init__(self):
        super().__init__()
        self.bifurcation_parameter = None
        self.citation = "Lorenz, Edward N (1963). Deterministic nonperiodic flow. Journal of the atmospheric sciences 20.2 (1963): 130-141."
        self.correlation_dimension = 1.993931310517824
        self.delay = False
        self.description = "A minimal weather model based on atmospheric convection."
        self.dt = 0.0001801
        self.embedding_dimension = 3
        self.hamiltonian = False
        self.initial_conditions = [-9.7869288, -15.03852, 20.533978]
        self.kaplan_yorke_dimension = 2.075158758095728
        self.lyapunov_spectrum_estimated = [1.0910931847726466, 0.02994120961308413, -14.915552395875103]
        self.maximum_lyapunov_estimated = 1.0910931847726466
        self.multiscale_entropy = 1.1541457906835575
        self.nonautonomous = False
        self.beta = 2.667
        self.rho = 28
        self.sigma = 10
        self.period = 1.5008
        self.pesin_entropy = 1.121034394385731
        self.unbounded_indices = []

    @staticjit
    def _rhs(x, y, z, t, beta, rho, sigma):
        xdot = sigma * (y - x)
        ydot = x * (rho - z) - y
        zdot = x * y - beta * z
        return xdot, ydot, zdot

giaco5988 avatar Oct 18 '21 15:10 giaco5988

Some of these values are computed from the attractor (e.g., the Lypaunov spectrum), which I agree would be weird to put into the Python code. So my inclination would be to put everything that describes the system and how to solve it into the class, and to put the variables computed from the system into the JSON data.

shoyer avatar Oct 18 '21 16:10 shoyer

I see, I got confused Input/Output, I think understand now, so the code read/write to the Json. Right? E.g. from scripts which are external to the package like find_attractor_properties.py

I still think estimated values might be attributes of the class (initialized to None) which are assigned when computed from the attractor. This, to me, seems conceptually sound in the sense that "estimated values" are a property of the system, so it could make sense for them to belong to the system class.

If one want, it would be possible to save all results (parameters + estimated values) to Json. Even more, one might want to load estimated values (corresponding to current parameters) from a database of pre-computed ones (either local or remote).

I think this would clarify the dependecies between parameters, rhs and estimated values. It could also facilitate to keep data outside the repository. What do you think?

giaco5988 avatar Oct 18 '21 18:10 giaco5988

I'm closing this issue for now, because I still haven't found a an alternative design pattern that does everything I need it to.

I played around with putting the function definitions themselves into the JSON file, since that could be useful for symbolic regression algos that want to work with parseable definitions. But importing the strings into python functions caused a lot of bugs, and I couldn't get it to play well with numba.

Happy to re-open if a better approach jumps out. cheers, william

williamgilpin avatar Apr 26 '23 18:04 williamgilpin