pik-copan / pyunicorn

Unified Complex Network and Recurrence Analysis Toolbox
http://pik-potsdam.de/~donges/pyunicorn/
Other
195 stars 86 forks source link

ENH: Support circular variable in recurrence plot distance function #113

Open hsharrison opened 5 years ago

hsharrison commented 5 years ago

I'm looking for an RQA implementation that supports circular variables. It appears none exist. Since this project is in active development, I thought I'd try here.

Basically, we'd like to perform RQA on angle timeseries where -pi = pi. Therefore distances must be calculated differently.

If there is agreement that this a feature that could be included, I'd be willing to put together a pull request but I will need some guidance on this project's organization. I also have never worked with C extensions before so if the distance calculation happens there, I may need some help.

But nevertheless, I think this should be a relatively simple feature.

jdonges commented 5 years ago

Dear Henry,

this would be a relevant contribution from our perspective. We would be happy to give advise on the implementation if possible.

Best, Jonathan

Am 14.08.2018 um 11:44 schrieb Henry S. Harrison notifications@github.com:

I'm looking for an RQA implementation that supports circular variables. It appears none exist. Since this project is in active development, I thought I'd try here.

Basically, we'd like to perform RQA on angle timeseries where -pi = pi. Therefore distances must be calculated differently.

If there is agreement that this a feature that could be included, I'd be willing to put together a pull request but I will need some guidance on this project's organization. I also have never worked with C extensions before so if the distance calculation happens there, I may need some help.

But nevertheless, I think this should be a relatively simple feature.

— You are receiving this because you are subscribed to this thread. Reply to this email directly, view it on GitHub https://github.com/pik-copan/pyunicorn/issues/113, or mute the thread https://github.com/notifications/unsubscribe-auth/ADCbe7i0aRFKK7rtHI5vWbqauoYFKu2Bks5uQvBygaJpZM4V8sT1.

hsharrison commented 5 years ago

That's great to hear.

I suppose the implementation strategy would be to replace the subtraction in the distance calculation with a function that can be changed with a keyword argument. I guess, in pyunicorn/pyunicorn/timeseries/_ext/numerics.pyx, the line following every comment # Use ____ norm (12 places). I've never used Cython before but can I just pass a keyword flag into all these functions and use an if statement to determine which kind of subtraction to use? And then I suppose propagate the flag from RecurrencePlot.__init__.

Let me know if you have a better idea. I've taken a look through the code but don't yet have a complete understanding of its organization and internals.

hsharrison commented 5 years ago

In any case, I think the implementation would look something like this. Again, I'm new to Cython but I don't think this needs any cdefs.

from libc.math cimport M_PI

def default_diff(a, b):
    return b - a

def angle_diff(a, b):
    return (default_diff(a, b) + M_PI) % (2 * M_PI) - M_PI

And then replace all occurrences of

abs(embedding[i, l] - embedding[j, l])

with

abs(diff(embedding[i, l], embedding[j, l]))

with diff being one of default_diff or angle_diff selected by a flag.

But based on the code in timeseries/_ext/numerics.pyx, I'm guessing you're trying to avoid function calls or conditionals in the distance matrix functions. So would it better to implement a second version of every distance matrix function?