close
Skip to content

[New] HRV: adding indices of Symbolic Dynamics #1057

Merged
DominiqueMakowski merged 13 commits into
neuropsychology:devfrom
mrosol:dev
Feb 22, 2026
Merged

[New] HRV: adding indices of Symbolic Dynamics #1057
DominiqueMakowski merged 13 commits into
neuropsychology:devfrom
mrosol:dev

Conversation

@mrosol

@mrosol mrosol commented Dec 12, 2024

Copy link
Copy Markdown

Description

This PR aims at adding calculation of symbolic dynamics HRV parameters [1-5]

[1] Cysarz, D., Edelhäuser, F., Javorka, M., Montano, N., and Porta, A. (2018). On the relevance of symbolizing heart rate variability by means of a percentile-based coarse graining approach. Physiol. Meas. 39:105010. doi: 10.1088/1361-6579/aae302
[2] Cysarz, D., Porta, A., Montano, N., Leeuwen, P. V., Kurths, J., and Wessel, N. (2013). Quantifying heart rate dynamics using different approaches of symbolic dynamics. Eur. Phys. J. Spec. Top. 222, 487–500. doi: 10.1140/epjst/e2013-01854-7
[3] Wessel, N., Malberg, H., Bauernschmitt, R., and Kurths, J. (2007). Nonlinear methods of cardiovascular physics and their clinical applicability. Int. J. Bifurc. Chaos 17, 3325–3371. doi: 10.1142/s0218127407019093
[4] Porta, A., Tobaldini, E., Guzzetti, S., Furlan, R., Montano, N., and Gnecchi-Ruscone, T. (2007). Assessment of cardiac autonomic modulation during graded head-up tilt by symbolic analysis of heart rate variability. Am. J. Physiol. Heart Circ. Physiol. 293, H702–H708. doi: 10.1152/ajpheart.00006.2007
[5] Gąsior, J. S., Rosoł, M., Młyńczak, M., Flatt, A. A., Hoffmann, B., Baranowski, R., Werner, B. (2022). Reliability of Symbolic Analysis of Heart Rate Variability and Its Changes During Sympathetic Stimulation in Elite Modern Pentathlon Athletes: A Pilot Study. Front. Physiol. 13, doi: 10.3389/fphys.2022.829887

Proposed Changes

I added neurokit2/hrv/hrv_symdyn.py and changed the following files neurokit2/hrv/hrv.py, neurokit2/hrv/__init__.py, tests/tests_hrv.py, docs/functions/hrv.rst

Checklist

Here are some things to check before creating the PR. If you encounter any issues, do let us know :)

  • [+] I have read the CONTRIBUTING file.
  • [+] My PR is targeted at the dev branch (and not towards the master branch).
  • [+] I ran the CODE CHECKS on the files I added or modified and fixed the errors.
  • [NA] I have added the newly added features to News.rst (if applicable)

@welcome

welcome Bot commented Dec 12, 2024

Copy link
Copy Markdown

Thanks for opening this pull request! We'll make sure it's perfect before merging 🤗 force
Make sure to read the contributing guide. Also, if you think that your contribution is worthy of it, you can consider adding yourself to the Contributors list (feel free to ask us if you have any doubts).

@DominiqueMakowski

Copy link
Copy Markdown
Member

@Tam-Pham kind bump

@DominiqueMakowski

Copy link
Copy Markdown
Member

@Tam-Pham bump x2

@DominiqueMakowski

Copy link
Copy Markdown
Member

@mrosol thanks a lot for that very interesting paper (and sorry for the delay in reviewing it 😩)
quick question, wouldn't that symbolic dynamics approach fits under non-linear instead of its own separate "domain" ?

@mrosol

mrosol commented Feb 11, 2025

Copy link
Copy Markdown
Author

@DominiqueMakowski I thought to separate it from the code clarity perspective, not to extend the file with nonlinear parameters too much, but it might go over there as well. Do you want me to move it from hrv_symdyn.py to hrv_nonlinear.py? :)

@Tam-Pham Tam-Pham left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Hi @mrosol

I'm so so so sorry for the late review. It has been a few hectic months for me.

Thank you for your contribution to the package. Symbolic dynamic metrics are indeed interesting and novel parameters for the ANS activities.

I agree that they could be placed under the non-linear domain as similar to other metrics there, they are capturing the dynamics in the signal that are distinct from the traditional statistical or frequency-based metrics. However, I'm not sure how to incorporate them into the existing function.

@mrosol I have added just 2 comments - 1 of them would need @DominiqueMakowski inputs with the naming convention. Other than that, the code looks great :) Thanks so much

Comment thread neurokit2/hrv/hrv_symdyn.py Outdated
A dictionary with keys corresponding to the symbolic dynamics families ('0V', '1V', '2LV', '2UV')
and values representing the normalized counts of words belonging to each family.
"""
families = {'0V': 0, '1V': 0, '2LV': 0, '2UV': 0}

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Suggest making a few revisions to improve the efficiency of this function:

  1. using np.unique() instead of len(set(word)) to avoid processing one word at a time in a loop
words = np.array(words)  # Ensure input is a NumPy array
unique_counts = np.apply_along_axis(lambda w: len(np.unique(w)), 1, words) 
  1. accumulate raw count using np.sum() without looping
families = {
        '0V': np.sum(unique_counts == 1),
        '1V': np.sum(unique_counts == 2),
        '2LV': np.sum((unique_counts == 3) & ((words[:, 1] > words[:, 0]) & (words[:, 2] > words[:, 1]) |
                                             (words[:, 1] < words[:, 0]) & (words[:, 2] < words[:, 1]))),
        '2UV': np.sum((unique_counts == 3) & ~((words[:, 1] > words[:, 0]) & (words[:, 2] > words[:, 1]) |
                                               (words[:, 1] < words[:, 0]) & (words[:, 2] < words[:, 1]))),
    }
  1. calculate len(words) just once
total_words = len(words)
for key in families:
      families[key] /= total_words

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Thank you, @Tam-Pham, for the revision. I have implemented the suggested changes. :)

Please let me know, if there is anything else I can do to move this PR further.

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Hi @Tam-Pham, @DominiqueMakowski, is there anything more I should do to push those changes to the main branch? My colleagues and I would like to state in the paper that the symdyn HRV parameters were also calculated using Neurokit. :)

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Comment thread neurokit2/hrv/hrv_symdyn.py Outdated
@DominiqueMakowski

Copy link
Copy Markdown
Member

@mrosol thanks so much and sorry for the ridiculous delay in finally reviewing this and merging it. It's great, note that I integrated that into nonlinear file as it is where it conceptually belongs as far as I understood, and renamed the function to hrv_symbolic for more consistency with the other function

Thanks again!

@DominiqueMakowski DominiqueMakowski changed the title Dev - Symbolic dynamics HRV parameters added [New] HRV: adding indices of Symbolic Dynamics Feb 22, 2026
@DominiqueMakowski

Copy link
Copy Markdown
Member

also changed the default so that it doesn't add too many indices when using the master functions.

Please don't hesitate to reach out for any suggestions or further improvement :)

@DominiqueMakowski DominiqueMakowski merged commit 2be9868 into neuropsychology:dev Feb 22, 2026
8 checks passed
@welcome

welcome Bot commented Feb 22, 2026

Copy link
Copy Markdown

landing
Congrats on merging your first pull request! 🎉🍾 We're looking forward to your next one!

@mrosol

mrosol commented Feb 23, 2026

Copy link
Copy Markdown
Author

@DominiqueMakowski Great to hear that those changes have been merged — I can already see them in the main branch. 🙂 If any additional ideas come to mind based on our ongoing research, I’ll be happy to contribute further to this project.
One final question: when do you plan to update the package on PyPI? The latest available version is 0.2.12 from July 8, 2025.

@DominiqueMakowski

Copy link
Copy Markdown
Member

One final question: when do you plan to update the package on PyPI?

We are in the process of fixing that to update it on pypi asap :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants