-
Notifications
You must be signed in to change notification settings - Fork 11
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
Skeletonization of RPs and border effect correction. #98
Comments
(I don't think I will have much time to contribute here, besides leaving some helpful tips on the PR...) |
Thanks. A small but important detail: if the plan is writing a Julia implementation of this method based on the Matlab code that you linked, I think that it is not possible to do it in this package, because the Matlab code is GPL-licensed, and this package is published with MIT license. That being said, I don't think that this is a big problem - probably it's a better idea to devise a fresh new Julia code based on the description of the algorithm in the paper, rather than on Matlab's particular implementation. |
Hey,
Sure! My intention was only to illustrate the main procedure. Of course it will be totally different in Julia, structurewise - way more auxiliary functions. I only posted it, in order to see if you agree on the main concept. Maybe you have a totally different idea of the implementation? |
No, I have not had time to look at it yet, sorry. |
Hey @heliosdrm , it is time now to implement this :) Of course, I could simply start hacking something, probably sticking to my Matlab-implementation, but as you mentioned before: it might be beneficial to make a plan beforehand, using the structure you implemented for the RQA. In my Matlab-implementation I first transformed the Recurrence Matrix into a close returns map, i.e. some special rotation by 45 degrees, so that all diagonal lines become horizontal lines. Then I wrote a function, which extracts all the horizontal (diagonal) lines from the rotated Recurrence Matrix and stores them in a ( Then I iterate over this sorted ( I think I would be fine to implement it like I outlined it, but I kindly ask for your comment if this makes sense at all. Specifically, the Recurrence Matrices are in a I appreciate any help. |
Hi, the extraction of lines (both vertical and diagonal) from sparse matrices is coded in
Maybe that code might serve as starting point. If this is done, we might look for a smart way for re-using those operations. I mean: once you have that (
|
An alternative to transforming the matrix with |
An additional question for @hkraemer: will the skeletonization preserve symmetry? I think that this is a desirable property, specially if we want to return a transformed matrix. |
Yepp, it does. In case of symmetry, it also checks and renderes the lines of one triangle of the RP. |
I am very much in favour of the idea to extend A few comments:
I will start with trying to extract the ( Let me know what you think. Cheers |
recurrencestructures takes as kwarg border. I am not quite sure what this is meant to be. From my point of view it would be beneficial if we add another keyword regarding the treatmeant of border-lines. As pointed out in Kraemer & Marwan, Phys. Lett. A (2019) <https://publications.pik-potsdam.de/pubman/faces/ViewItemOverviewPage.jsp?itemId=item_23376>, there are several ideas to treat lines, which cut the border of the RP. In conclusion there were two main strategies, which are also not too complicated to implement: 1) assign all border diagonals the length of the LOI (Censi correction) or 2) all (semi-)border diagonals are discarded, but the longest one (Kelo correction). Since these corrections can be crucial for an unbiased RQA and they have to be incorporated in diagonalhistogram (as far as I have understood) anyway, these keyword arguments should also be applicable in the rqa-method. And as you pointed out earlier: It makes sense to write a rqa-method that takes the value returned by recurrencestructures (or recurrencestructures!) anyway.
Great to start implementing this! I remember that we had already the discussion here to implement the border correction.
One correction: the Censi correction is not to replace the line lengths of the border lines by the length of the LOI but with the one of the longest border line.
|
Censi et al. is actually replacing border lines with the LOI. "The first correction we introduced concerns the border effect: we considered a border diagonal to be as long as the main diagonal (N samples), by introducing a diagonal length correction (corrected diagonal length, CDL) [...]" (p. 857). Anyway, it does not matter much, but for semi-border lines, which only cut one border for the RP, I guess. |
This was implemented in #128 if I understood that correctly. |
Hi there,
the finite size of a recurrence plot (RP) can cause border effects in the RQA-quantifiers. Also the samplingrate of the data and the chosen recurrence threshold selection method (
fixed
,fixedrate
,fan
) plays a crucial role. They can cause the thickening of diagonal lines in the RP. Both problems lead to biased line-based RQA-quantifiers and is discussed in Kraemer & Marwan, Phys. Lett. A (2019). The proposed methods are implemented in Matlab and are open source.According to the above mentioned two major problems, there are two methods needed, which will fix them. In the first case one simply needs to supress lines in the diagonal line length histogram, which cross the borders of the RP in an appropriate way (in the paper we compared four different ways, but the
kelo=keep longest line
-approach will do - see attachement). The second problem is way trickier to tackle. The problem corresponds to applying a Theiler window, but not only for the fiducial point on the trajectory, but also for its nearest neighbours falling within the recurrence threshold. We proposed a skeletonization scheme, which seems to work well (rp_diagonal
, attached).Basically, we
first transform the RP by rotating it by 90°. This way the diagonal lines become horizontal lines. That might also speed up computation.
We pick the longest line from the diagonal line length histogram and iterate over each point of this line. At each point, we check if there is a neighbouring point/line. If yes, we repeat the same operation on this line until we do not find any neighbouring points and recursively delete all these adjacent lines from the histogram and the RP.
Then we pick the second longest line from the histogram and repeat the mentioned procedure.
We do this until there is no more line to pick from the histogram.
This leaves us with a RP only consisting of diagonal lines of thickness 1. Since the algorithm is not so complicated and basically consists of iterating over a histogram over and over agai,n I assume it could be way more performant than the Matlab implementation, what do you think?
I would be very grateful to get any help, while implementing this in Julia.
Cheers,
Hauke
Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.
The text was updated successfully, but these errors were encountered: