GithubHelp home page GithubHelp logo

Comments (13)

Datseris avatar Datseris commented on June 14, 2024

Hello Takafumi,

I really like some parts of this proposal. However, I am really sorry to say that I don't really like parts other parts...

Here are my issues:

  1. Makes the source code very much more complicated, without much of a benefit. One of the main goals of this DynamicalSystems.jl ecosystem is to have source code as clear as possible. Sometimes of course this comes with a sacrifice of flexibility, but for me this is one of the most important aspects of the library. I want anybody that goes to the source code to be able to understand what a function does instantly. With your change, the single function e.g. lyapunov, which has a source code of only 20 lines, is then "expanded" into 3 functions and 1 struct.
  2. Please correct me if I am wrong here, but from this change the only benefit can be that users get the convergence timeseries of lyapunovs (and then use them for other stuff)? In fact we have already done that in the past, check out this: JuliaDynamics/DynamicalSystems.jl#18. After some point I decided to remove it because it was just so trivial to modify the source code so if some advanced user wanted it, they can get the result with adding only 3 lines of code (see end of message).
  3. I don't see (at least on-the-spot) how this interface can be shared between lyapunovs and lyapunov, since they use fundamentally different algorithms.

On the other hand, these are the benefits:

  1. My implementation that I decided to drop was pretty stupid, because I was re-writting a lot of lines of code to keep type stability and whatever. In short, it was bad. You proposal is better.
  2. Allows one to use lyapunov_exponents_solver which I think is a great idea, since it allows you to chooce different qr for large system and other things depending on the system.

But my question is, can;t lyapunov_exponents_solver dispatch given only the system? You can deduce Types and dimensionality only from it?

Change required to get timeseries

change this: λ += log.(abs.(diag(R)))
to this: push!(λ, λ[end] + log.(abs.(diag(R)))
and add 2 more lines:
λ = T[]; tvec = T[];

and inside the loop put push!(tvec, t).

It is literally 3 lines of code and you get lyapunov converngence.

On the other hand, it would be nice to be able to offer that?
Let me tell you: let's wait for Julia 0.7 on this one, and then we revisit, ok?

(Because 0.7 brings this IPO thingy and may make everything much easier)

edit (in case it wasn't clear)

Obviously having the possibility to return the convergence timeseries is a great thing to have. I didn't say that because it is just a blatant truth.

But can we do it and keep the source code simple? greedyness

from chaostools.jl.

Datseris avatar Datseris commented on June 14, 2024

Ah, now I see that there is even one more quite great merit to your proposal: It will be almost trivial solve #7

from chaostools.jl.

tkf avatar tkf commented on June 14, 2024

Cool. Thank you very much for the detailed review of my proposal!

One of the main goals of this DynamicalSystems.jl ecosystem is to have source code as clear as possible.

This and other similar comments clarify a lot about where DynamicalSystems.jl is going. Indeed, my proposal doesn't match with this goal. I also think that it is nice to have a well-tested clear code for complex topic like dynamical systems, too.

from this change the only benefit can be that users get the convergence timeseries of lyapunovs (and then use them for other stuff)?

Almost. Yea, that was the main goal I was explaining. But, for example, if you want to lower the number of orthonormalizations as much as possible (because that's the time-consuming part), it is hard to do in one-function approach you are taking. If you have a low-level API which allows you to step through the algorithm and mutate the temporary objects, it is possible to write up some algorithm to adaptively skip some orthonormalizations (say, when the Lyapunov vectors are not growing).

Anyway, as you said, it's simple to copy the code from ChaosTools.jl and add some lines. But in my workflow I just want to lower copy-and-paste if possible and import well-tested library.

So, I decided to write my own Julia library for this purpose:
https://github.com/tkf/LyapunovExponents.jl
As the description says, the goal is "a hackable Lyapunov exponents calculator".

I think it's better to implement it once anyway (even if I were to implement this proposal in ChaosTools.jl), since, in my experience, coming up with the right abstraction and interface is hard. Implementing similar library a few times really helps (not that I want, though). So, LyapunovExponents.jl is a library for experimenting with the interface which can help exploration in my research. If it is possible to simplify the code, maybe we can merge LyapunovExponents.jl into DynamicalSystems.jl/ChaosTools.jl.

In case you are interested in:
The main LE calculation is done in core.jl, especially the step! function:
https://github.com/tkf/LyapunovExponents.jl/blob/master/src/core.jl
Yes, it's a lot messy than your straight for-loop based code!
There is a small API/internal documentation here:
https://tkf.github.io/LyapunovExponents.jl/latest/api/#Low-level-API-1

from chaostools.jl.

Datseris avatar Datseris commented on June 14, 2024

Oh wow, this seems like a huge amount of code!

By the way, if you wanted you could set this up as a separate branch of this repo, I would give you forking access if you had asked. This way the interaction could be better seen.

I won't lie. It seems overly complicated at the moment, for something that could be done simpler. This is of course my take on it, and also my take on having simpler source code. If you are up for it, you can also compare benchmarks to see if your version is faster, which is another thing to consider.

The best part to keep is the step! function / approach. The existing code here can also be written to take advantage of that, having a setup function and a step function.

I do not see the advantage of the relaxers to be honest. I think I can see 2-3 types about relaxers and 5 functions? I achieve transient integration with a signle line:

st = Ttr != 0 ? evolve(ds, Ttr; diff_eq_kwargs = diff_eq_kwargs) : ds.prob.u0

Would you mind explaining the advantage of having dedicated types, abstract types and numerous functions for such a simple step?

from chaostools.jl.

tkf avatar tkf commented on June 14, 2024

It's not optimized in terms on runtime performance nor code readability yet. It's just me experimenting to search for the right abstraction of the problem. For example, I agree that there are some unnecessary abstract types. That's because of some coding history and Saturday+Sunday were not enough for the initial write-up and the refactoring.

About the relaxer stuff, the short answer is "because I'm not using DynamicalSystemsBase.jl" and the reason why so is JuliaDynamics/DynamicalSystemsBase.jl#17 (comment) .

The long "theoretical" answer starts by realizing both the transient-skipping part and the LE calculation are the kind of computations in which the terminating criterion is not clear. Then, for the full generality, I want to have three kinds of function: (1) one that sets it up (get_relaxer, LESolver), (2) one that does the core mutating part and can be called arbitrary number of times (relax!, solve!), (3) a utility function that calls (1) and then (2):

┌─ Problem 
│     │ 
│     │ get_relaxer, relaxed 
│     ▼ 
│   Relaxer ┄┄ ⟲ relax! 
│     │ 
│     │ LESolver 
│     │ 
│┄┄┄┄┄┄┄ init, solve 
│     │ 
│     ▼ 
└▶ Solver ┄┄ ⟲ solve!, step!

LE calculation is non-trivial so maybe having all of them makes sense. Having relaxer is just for reflecting this pattern to the code and see how it goes.

Another related reason why I wanted relaxer is that I want some way to configure the solver just before the setup. For example, you may want to use different ODE integrator for the LE solver. For this, I need a struct to just store the relaxed phase state and the inital LE Problem.

from chaostools.jl.

tkf avatar tkf commented on June 14, 2024

By the way, if you wanted you could set this up as a separate branch of this repo, I would give you forking access if you had asked.

I don't think a branch of ChaosTools.jl is a good place for this to sit. My aim is to have a hackable research platform, not a clean code sample (which is of course important as well!).

Maybe having LyapunovExponents.jl in JuliaDynamics organization makes sense? I don't know how you want to organize JuliaDynamics, though. My plan is to make LyapunovExponents.jl only rely on DifferentialEquations.jl, since ODEProblem and DiscreteProblem are enough. But it is very easy to make LyapunovExponents.jl understand the DS types provided by DynamicalSystemsBase.jl.

from chaostools.jl.

Datseris avatar Datseris commented on June 14, 2024

from chaostools.jl.

tkf avatar tkf commented on June 14, 2024

the source code is clear and understandable it follows directly that it is more easy to be modified.

I don't want to modify the code. As I said in my earlier comment (#14 (comment)), "I just want to lower (the number of) copy-and-paste" of non-trivial code blocks. That's what the DRY principle is all about.

(Of course, I know that's not always the best choice and I like the Go Proverb "A little copying is better than a little dependency." by Rob Pike. However, I do argue that LE calculation is a non-trivial code that requires some amount of testing. Modifying the code requires additional test code. That's not ideal. So, I think DRY wins here.)

I don't think I understand what you mean by hackable

So, what I mean by "hackable" is that LE calculation can be intercepted in many ways without editing the code block that does the LE calculation. In other words, I want a library, not a code sample.

from chaostools.jl.

Datseris avatar Datseris commented on June 14, 2024

from chaostools.jl.

Datseris avatar Datseris commented on June 14, 2024

from chaostools.jl.

tkf avatar tkf commented on June 14, 2024

OK. So what I learn here is that hackable can mean different things. Let's forget about what it means then.

Anyway, I hope my argument is clear:

I want a library, not a code sample.

Then you would understand why mentioning DRY does matter here. Providing LE computation as a code sample as you do it in ChaosTools.jl oppose to DRY. I don't want copy-and-paste some functions in my ~/.julia/. I want use them by just using them.

There are plenty of tests for the lyapunkv exponents for all system types.

I'm saying that you have to redo the testing everytime copy-and-paste. OK. Maybe that's me. I don't trust my hands.

from chaostools.jl.

Datseris avatar Datseris commented on June 14, 2024

from chaostools.jl.

Datseris avatar Datseris commented on June 14, 2024

I am splitting this issue into 2 different ones, #15 and #16, because it will make solving them easier (and because they actually are different issues in my eyes).

from chaostools.jl.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.