Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Rewritten rescale in lyapunovs.jl #214

Closed
wants to merge 3 commits into from

Conversation

SudoMishra
Copy link

I rewrote the rescale function in lyapunov.jl with get_state and set_state functions as you had mentioned.
In the current form of the rescale function, we no longer need multiple rescale functions as that can be handled by the multiple dispatches of get_state and set_state for different scenarios.

I'm unsure about the type of declarations that would go with the new rescale function but I think as now it handles both vector and matrix scenarios, the type declaration might not be needed.

I'm new to Julia and git. This is my first PR. I'm quite interested in contributing more to this package.
Thank you.

Copy link
Member

@Datseris Datseris left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

That's a good start. However, now each time rescale! is called it allocates a new vector r. The best is to pre-allocate r = copy(u). Then, you can use broadcasting r .= u .+ (...)... so that you overwrite an existing r in-place instead of creating a new one each time.

@SudoMishra SudoMishra closed this Sep 17, 2021
@SudoMishra SudoMishra deleted the edit_rescale branch September 17, 2021 05:42
@@ -269,16 +269,18 @@ end
function lyapunov(pinteg, T, Ttr, Δt, d0, ut, lt)
# transient
t0 = pinteg.t
# array to preallocate state for rescale
r = [get_state(pinteg,1)]
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't understand. Why is this a vector of vectors, instead of just copy(get_state(pinteg, 2))...?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I was trying this copy(get_state(pinteg,2)) but then I get an r as an SVector. With that when I try to do
@. r=get_state(integ,1) + (get_state(integ,2)-get_state(integ,1))/a I get a set_index error as you cannot change the contents of an SVector.

set_state!(integ,r,2)
function rescale!(integ,a,r)
# r =[get_state(pinteg,1)] for preallocated computation
r[1] = get_state(integ,1) + (get_state(integ,2)-get_state(integ,1))./a
Copy link
Member

@Datseris Datseris Sep 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is still allocating. A lot. You need to broadcast the operations by adding . after the opereators, r .= u .+ v....

(and you will replace r[1] with r, as there is no reason to define r as a vector of vectors.)

@Datseris
Copy link
Member

Huh, why was this PR closed? It was going good with only a small amount of tweaking needed.

@SudoMishra
Copy link
Author

SudoMishra commented Sep 17, 2021

Oh sorry, I was trying to make a PR on my forked repo and I think I messed up and closed this PR. I'll reopen it.

@Datseris
Copy link
Member

@SudoMishra test fail so something is going wrong with the way you rescale, can you have a closer look?

Comment on lines 334 to 340
function rescale!(integ,a,r)
r .= get_state(integ,1) .+ (get_state(integ,2).-get_state(integ,1))./a
set_state!(integ,r,2)
Copy link
Member

@Datseris Datseris Sep 17, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You need two versions of this function that dispatch via multiple dispatch on r. If r::SVector then you cannot use .= and you just type r = (no dots in any formula). If instead r::AbstractArray then you use the above version.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've added the multiple dispatched rescale function. So test 5 is failing in lyapunov_exponents.jl and its a bit strange why that is happening. It is the case where r::Abstract_Array
When I do rescale with no preallocation i.e.
r = get_state(integ,1) .+ (get_state(integ,2).-get_state(integ,1))./a
the test is passing and I'm getting the correct lyapunov exponent.
However, when I simply change the above line to use the preallocated r, i.e.
r .= get_state(integ,1) .+ (get_state(integ,2).-get_state(integ,1))./a
The test fails as the lyapunov value that I get is wrong (around 18.3..).
I'm trying to figure out why this is happening.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @Datseris , I was trying to resolve this issue but its getting a bit strange. So, in the lyapunov function I've created a new variable r=copy(get_state(pinteg,2)). As I've used copy() for creating r, it should now be independent of pinteg. So it should only change when the rescale! function is called, where it used as a placeholder for preallocation. However, that is not the case, and it even changes outside the rescale!. Due to this, during the set_state! in rescale! a wrong value is being passed on which results in the test failing. I'm not sure why this is happening, I've also used deepcopy instead of copy but the problem still persists. Am I missing some basic thing here? I would be grateful if you could give some advice on how to resolve this.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you repeat the same with deepcopy on r?

Copy link
Author

@SudoMishra SudoMishra Sep 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yeah, it is happening even with deepcopy. I was visualising the variables using the debugger and even with deepcopy the r variable gets updated during step! . And apparently this is only affecting one of the test cases. It should only get updated during rescale because that is the only place where I use it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actually, I"m still struggling to understand what exactly is your problem with respect to the algorithm. Why does it matter if r changes? r is a dummy variable. Its correct value is set exactly before giving this to set_state. Even if r and the 2nd state are referencing each other, we still don't care. ...?

Copy link
Author

@SudoMishra SudoMishra Sep 23, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm actually a bit confused myself. Even I think that since the correct value of r is getting changed just before being sent to set_state it shouldn't matter and the algorithm should work. But for some reason, test 5 in lyapunov_exponents was failing. I tried to figure out why this was happening and the only wierd thing that I saw happening was that r was changing outside rescale. I still think my code should be working just by set_state!(integ,r,2) but its failing for that specific case. I'll try to add the dispatch method to DynamicalSystemsBase.jl .

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. I'll look over this locally over the weekend and will identify the error. Thanks for investigating as well.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have fixed the set_state! and opened a PR in DynamicalSystemsBase.jl. Using the corrected set_state, set_state!(integ,r,2) is working properly and its passing all tests. I can commit the proper rescale function once the DynamicalSystemsBase.jl PR is merged and ChaosTools uses that.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I have added the updated rescale function without copy(r) in set_state. One test case will not pass currently as ChaosTools.jl currently uses the wrong set_state function from DynamicalSystemsBase.jl . I have added a PR to fix that in DynamicalSystemsBase.jl. For u::AbstractVector, set_state should use .=.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants