Talk to an expert
January 6th, 2020

    SIGN FOR NEWS

    sign for news

    Lorem ipsum dolor amet, consectetur adipiscing elit, sed do eiusmod tempor.


    Intro

    Computational mathematics comes in different flavours, symbolic, numerical and graphical. Numerical computations are the workhorse of computations. Graphical computations are great for visualizations. Symbolic or algebraic computations are great for getting an intuition for a mathematical problem. As an addition to the previous post, I’m going to examine SymPy and symbolic mathematics in Python and to help with guiding the conversation, SymPy will be used to create a simplified ECG model.

    Test Notebook – https://www.translucentcomputing.com/2020/01/sympy-and-ecg-notebook/

    ECG

    Electrocardiography is the process of producing an electrocardiogram (ECG or EKG), a recording – a graph of voltage versus time – of the electrical activity of the heart using electrodes placed on the skin. These electrodes detect the small electrical changes that are a consequence of cardiac muscle depolarization followed by repolarization during each cardiac cycle (heartbeat).

    An ECG is a test that checks how your heart is functioning by recording the electrical activity that passed through your heart. Here is an example of ECG from a healthy individual.

    Real ECG result.
    A 12-lead ECG of a 26-year-old male with an incomplete RBBB
    https://en.wikipedia.org/wiki/Electrocardiography#/media/File:12leadECG.jpg

    ECG is periodic time-series data. You can see a pattern in the image above. Such an output would be compared to known health or unhealthy patterns to help in detecting heart problems.

    For this post, we will only be focusing on modelling a normal sinus rhythm. A healthy individual pattern. Here is an example of a single heartbeat pattern with given segments in the waveform.

    ECG waveform with segments
    Schematic diagram of normal sinus rhythm for a human heart as seen on ECG
    https://en.wikipedia.org/wiki/Electrocardiography#/media/File:SinusRhythmLabels.svg

    Problem

    Create synthetic time-series data that models sinus rhythm for a human heart as seen on ECG. Include the different ECG segments in your model including the P, Q, R, S, T segments.

    SymPy

    SymPy is a Python library that was created for symbolic mathematics. SymPy has a lot of features and it really shines when it comes to calculus. Before we dive into the code for ECG here is a basic example that shows the main features of SymPy.

    The example creates a symbol “x” and the function “f” is defined with the symbol “x”. The following plot has been created from different values of “x”. After the function is differentiated, both the function and its derivative are plot together.

    ECG Model

    There are a few different methods used to generate ECG models. Here is the research paper that we use to show how one could use the formulas defined there and SymPy to develop a model.

    Research Paper – https://www.researchgate.net/publication/328097407_MODEL_FOR_GENERATING_SIMPLE_SYNTHETIC_ECG_SIGNALS

    First, we define the symbols required by the mathematical formulas.

    # create symbols for sympy processing
    k,K_B,A_P,K_P,K_PQ,A_Q,K_Q,A_R,K_R,A_S,K_S,K_CS,s_m,A_T,K_T,K_ST,s_I,K_I= symbols('k K_B A_P K_P K_PQ A_Q K_Q A_R K_R A_S K_S K_CS s_m A_T K_T K_ST s_I K_I')

    We then get to work defining the formulas in terms of the symbols.

    # P wave
    P=-A_P/2*cos((2*pi*k + 15)/K_P)+A_P/2
    ECG P waveform equation
    P waveform equation

    Once we have the formula defined we can plug in some values and plot it. The Piecewise function is used to define an interval for the function.

    # P wave
    I_K_B=124
    V_A_P=0.01
    I_K_P=79
    P_SUB = P.subs([(A_P,V_A_P),(K_P,I_K_P)])
    P_P = Piecewise((P_SUB, Interval(0, I_K_P).contains(k)), (0, True))
    plot(P_P,(k,0,I_K_P))
    P waveform
    P Waveform

    TC ECG Model

    The model defined in the research paper strives to be as accurate as possible and customizable for different heart conditions. By contrast, in our simplified model, our goal is to approximate only the ideal version of the model.

    To reduce the complexity of the model we limit the segments of our model to simple sinusoidal signals. Using only the properties of trigonometric functions with time-shifting and time-scaling we approximate and generate an ideal version of the ECG model.

    def createECGModel():
        p=0.1*sin((pi*k+120)/80)
        p_p=Piecewise((p,Interval(120,200).contains(k)),(0,True))
        q=-0.03*cos((pi*k-30)/20)
        q_p=Piecewise((q,Interval(240,260).contains(k)),(0,True))
        r=1.1*cos((pi*k+31.2)/20)
        r_p=Piecewise((r,Interval(260,280).contains(k)),(0,True))
        s=-0.06*sin(pi*k/10)
        s_p=Piecewise((s,Interval(280,290).contains(k)),(0,True))
        t=0.4*sin((pi*k-215)/110)
        t_p=Piecewise((t,Interval(290,400).contains(k)),(0,True))
        return p_p+q_p+r_p+s_p+t_p

    We then graph it to see how close we are to the ideal version.

    TC ECG model waveform
    TC ECG Model

    After we create the initial model, we want to use that in some data science tasks. We first prepare the SymPy formula and use it with our data analysis tool, pandas.

    Performance

    SymPy also supports vectorization, you can run the formulas directly with substitutions or you can define a vectorized version of the formula. Here is the non-vectorized version:

     period = np.arange(0,500)
     data = []
     for t in period:
         data.append(ecg.subs(k,t))

    The code loops through the values of k and generates a value for each data point. Using this code the ECG waveform generation function runs on average in 4 seconds. Here is the vectorized version:

    ecg_lam = lambdify(k,ecg,'numpy')
    period = np.arange(0,500)
    data = ecg_lam(period)

    Here we use the lambdify function to create a vectorized version of the formula. We then apply the formula to all the data points in the array. This version runs in 0.02 seconds.

    Once we have the data for a single heartbeat in pandas, we duplicate the data to generate a continuous waveform for multiple heartbeats.

    df = pd.DataFrame(data=data)
    # duplicate data - this is for visualization only
    df = df.append(df,ignore_index=True)
    df = df.append(df,ignore_index=True)
    df = df.append(df,ignore_index=True)

    Here is how the ECG waveform looks, generated by our simplified model.

    Generated synthetic TC ECG signal
    Generate ECG waveform

    For comparison here is the output from my Apple watch ECG.

    Apple watch ECG result
    The output from My Apple Watch ECG

    Conclusion

    SymPy is one of my favourite libs to use and to play around with. Often you can reduce the complexity of your model and generate an idealized version of it. Such a model can be used to drive the initial development of your AI. It can also be used to benchmark your machine learning code.

    5 1 vote
    Article Rating

    We treat your business like our own.

    Let's talk!
    0
    Would love your thoughts, please comment.x
    ()
    x