Closed DominiqueMakowski closed 2 years ago
Also, in the same paper, they suggest a global measure hFI:
What do you think of it? I'd like to add that to NK, but I'm not sure how does it translate to python 🙈
EDIT: in Urda-Benitez, R. D., Castro-Ospina, A. E., & Orozco-Duque, A. (2021). Characterization and classification of intracardiac atrial fibrillation signals using the time-singularity multifractal spectrum distribution. Communications in Nonlinear Science and Numerical Simulation, 96, 105675., it says that it's... delta**2 * alpha
?🤔
I gave it a try, but let me know if you find the time to give it a look! I really think it needs a double check :)
Hey @DominiqueMakowski! Sorry, I totally missed the notification!
So, to your first question: The formulation in Orozco-Duque et al. is based on the scaling of the partition function Z, which is slightly different that our formulation in DFA and MFDFA. There is nothing incorrect in that paper, Orozco-Duque et al. are simply introducing an identical formulation based on the notion of the Hausdorff dimension (it's that very interesting question of, e.g., taking a map of the UK and measuring the shoreline, measuring the total lenght of the shoreline, progressively with smaller and smaller sticks).
If you continue down you find Eq. (14):
wherein you find the relation of the fluctuation function from MFDFA with h(q). Which then leads us to a construction wherein τ(q) = q*h(q) - 1. So our formulation is correct :).
Now to the question on the hFI:
From the edit that you included, you can actually get this fairly easily from the singularity spectrum f(α) in L. 166-228. Then you have h(q) and you can apply a derivative twice :). Personally I don't like this measure too much for a simple reason. If you check their Fig. 3:
you can see Δ²h(q), from which hFI is simply the difference between the minimum and maximum. Now you only see a real change in the left plots as you get close to q=0, which is also where both MFDFA and WTMM don't work (or work very poorly). Whether this measure has any physical meaning, I cannot judge, but it could be fraught with numerical uncertainties. But from the paper it actually seems they get something meaningful out of it, so that's good :). Anyway, your implementation seems correct to me :).
Suggestion:
Maybe it is better to use np.gradient()
in L.361, which should be smoother:
np.sum(np.gradient(np.gradient(out["h"])) ** 2) / (2 * np.max(np.abs(q)) + 2)
But overall it all seems correct to me :).
Hope it helps!
P.S.: Indeed this new paper from 2021 says hFI = Δ²α, and that does not seem correct to me :/. Odd.
Thanks a lot @LRydin for the clarification!
PS: I'm almost done with a big overhaul of all the complexity functions in NK for its next 2.0 release, with a new website documentation and all, feel free to hop by anytime if you have any suggestions for improvements or features :)
Also, if you have any idea how to translate the modified formula to compute the slope when q = 0 (in Faini 2021) let me know 😁
Hi @LRydin! Just a quick check,
If I'm not mistaken, here you compute Tau(q) as :
https://github.com/LRydin/MFDFA/blob/a6e9bfdc88157baafc04e72aea6ff6a833a0cfa9/MFDFA/singspect.py#L163
However, in Orozco-Duque, A., Novak, D., Kremen, V., & Bustamante, J. (2015). Multifractal analysis for grading complex fractionated electrograms in atrial fibrillation. Physiological Measurement, 36(11), 2269–2284. doi:10.1088/0967-3334/36/11/2269 they compute it as:
which would be
(q-1) * slopes
?Is it equivalent or is there something I missed?