Closed Datseris closed 11 months ago
This is very good question. Right now the mode of operation is number 1: you keep collecting points of the attractor until you have a number mx_chk_loc_att
of consecutive recurrences on the attractor.
The problem is the stopping criterion of the algorithm. When do we stop collecting points? So the idea is to continue on the attractor enough consecutive steps without finding an new cell. If there is a newly found cell, then we store the point and reset the counter. This is especially important for chaotic attractors.
The other option is to set another stopping criterion. It can be a fixed amount of steps: the algorithm goes on for a sufficiently long time and stops. This is OK when combined with store_once_per_cell = false
to store more points of the attractor if needed. Since attractors are processed only once, the mx_chk_loc_att
can be a big number like 1e5 iterations by default. It should be compared with basics benchmarks.
There are tradeofs, the first method guarantees to have a good description of the attractor but it can be stuck in some situations. Especially in high dimension (I got some problems with the coupled Kuramotos at the time). The second is more intuitive and direct. But I think it leaves the number mx_chk_loc_att
to the user.
This is a breaking change, but it is worth thinking about it.
@awage I think we should do this change. But first, let's organize ourselves.
I am arguing we should go for the second method, because it is more intuitive. First method is unintuitive for me. It is unintuitive to me that the algorithm resets in second phase; we have already collected enough recurrences to claim that we are on an attractor, so why do it again...? The algorithm resets already in the first phase, why do it in the second as well? Additionally, even in the limit of extremely high mx_chk_fnd_att
, the algorithm, where every single cell the attractor covers has already been visited, even then, the first method needs to make several more "loops" around the attractor, to first label the cells as attractor cells, and then start incrementing the counter. Isn't this second loop a waste?
My other problem with method 1 is: both mx_chk_fnd_att
and mx_chk_loc_att
keywords tune the precision with which we find attractors. While in method 2 only mx_chk_fnd_att
does. The loc
keyword is really only about how many atttractor cells we will record, and has nothing to do with recurrences. I just find this more intuitive.
So the idea is to continue on the attractor enough consecutive steps without finding an new cell. If there is a newly found cell, then we store the point and reset the counter. This is especially important for chaotic attractors.
Why is this important for chaotic attractors? I don't see the argument. We have already ensured that there are enough recurrences in the first phase of the algorithm. We can increase accuracy by demanding more recurrences before going into storing attractor points. I just don't see how searching for recurrences a second time makes things more accurate in this scenario, or why this would be important for chaotic attractors.
The second is more intuitive and direct. But I think it leaves the number
mx_chk_loc_att
to the user.
But this number is anyways left to the user. It is a keyword argument. Doesn't matter if we change things or not.
This is a breaking change, but it is worth thinking about it.
Technically, you are right, this is techinically breaking. I am not sure if this is actually worth a breaking release though. In principle, the two methods have equivalent results by adjusting their keywords. And I believe that changing keyword arguments should not count as a breaking change. And indeed this is declared in the way DynamicalSystems.jl handles versioning: https://juliadynamics.github.io/DynamicalSystemsDocs.jl/dynamicalsystems/stable/#Version-numbers
Besides, Method 1 becomes method 2 in the limit of increasing the recurrence threshold mx_chk_fnd_att
.
Lastly, for a long long time, I thought the algorithm was doing method 2 !!!!! Only now it is perfectly clear to me that we do method 1.
I will do a PR that changes to method 2, and we will see how it goes. How many tests it breaks without adjusting keyword arguments.
I think the method 2 is better also. I am convinced that it will be clearer for the user. I believe that in 90% of the cases it will not make any difference in the basins found. The other 10% would need some meta-parameter tuning.
Alright, @awage I think we should discuss this. At the moment, the mode of operation
:att_found
of the Finite State Machine (FSM) is as follows:This means that, once we enter
:att_found
, we start labelling all encountered cells as "attractor cells". However, the counter is incremented only the second time we encounter the attractor cells. And each time we do not encounter an attractor cell, we reset the counter and start again from scratch.For a long time now I thought that the mode of operation is a second option: "every subsequent visited cell is labelled an attractor cell, and each time the counter is incremented." That's not what we have.
But my argument is: shouldn't we do the second option...? The way things are right now we are searching for recurrences twice: We first search for recurrences once to trigger the
:att_found
phase. But then we search for recurrences again during the:att_found
phase, as only when a second recurrence occurs, we increment the counter.So, isn't it better if we do the second option? This way, we only search for recurrences once. Additionally, this way, the user has much better clarity of what value to give to
mx_chk_fnd_att
. It is the only parameter that relates with recurrences in state space.Now, if we do go with the second option, it is not clear to me what
mx_chk_loc_att
should do... My guess is that it simply counts how many steps to take after having found an attractor to label cells as attractor cells.Anyways, I am wondering, why did we do things this way. We search for recurrences twice. But it doesn't "improve the accuracy" of the algorithm if you think about it, because
:att_found
is a state one can never escape from.I am not sure. I hope you know this better and remember things better so you can tell me why the code is the way 1 instead of the way 2...