Skip to content

Instantly share code, notes, and snippets.

@santiago-salas-v
Last active May 4, 2025 08:48
Show Gist options
  • Save santiago-salas-v/36a044cf0e7fe16dcab2d9af4247cd89 to your computer and use it in GitHub Desktop.
Save santiago-salas-v/36a044cf0e7fe16dcab2d9af4247cd89 to your computer and use it in GitHub Desktop.
calculate synthetic ramps given a series of time points and coefficients of unit steps at each time. \n convolution ramps
Display the source blob
Display the rendered blob
Raw
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
# ---
# jupyter:
# jupytext:
# cell_metadata_filter: -all
# formats: ipynb,py:percent
# text_representation:
# extension: .py
# format_name: percent
# format_version: '1.3'
# jupytext_version: 1.16.7
# kernelspec:
# display_name: main
# language: python
# name: python3
# ---
# %% [markdown]
# synthetic ramp method
#
# calculate synthetic ramps using convolution for a given series of time points:
# * define matrix $A$ with the coefficients $a_{i,j}$ of the unit steps in $n$ different series $i$ for each time $t_j$.
# * define matrix $\sigma(t-t_j)*\sigma(t)=(t-t_j)\cdot \sigma(t-t_j)$ which is lower triangular with permutations of $(t-t_j)\cdot \sigma(t-t_j)$
# * example with $t_0<t_1$: $(t_0-t_1)\cdot \sigma(t_0-t_1)=0$, and $(t_1-t_0)\cdot \sigma(t_1-t_0)=(t_1-t_0)$ due to step definition
# * the matrix $\sigma(t-t_j)\cdot A$ has then the slopes $\frac{dy_i}{dt}$ at times $t_j$ and $(t-t_j)\cdot \sigma(t-t_j)\cdot A$ has the synthetic ramps by convolution.
# $$
# \underbrace{\left[\begin{array}{cccc}
# 1 & 0 & 0 & ...\\
# 1 & 1 & 0 & ...\\
# 1 & 1 & 1 & ...\\
# ... & ... & ... & ...
# \end{array}\right]}_{\sigma(t-t_j)}\cdot
# \underbrace{\left[\begin{array}{ccc}
# a_{1,0} & a_{2,0} & ...\\
# a_{1,1} & a_{2,1} & ...\\
# a_{1,2} & a_{2,2} & ...\\
# ... & ... & ...\\
# \end{array}\right]}_{A} =
# \underbrace{\left[\begin{array}{ccc}
# a_{1,0} & a_{2,0} & ...\\
# a_{1,0}+a_{1,1} & a_{2,0}+a_{2,1} & ...\\
# a_{1,0}+a_{1,1}+a_{1,2} & a_{2,0}+a_{2,1}a_{2,2} & ...\\
# ... & ... & ...\\
# \end{array}\right]}_{\mathrm{slopes}}
# $$
#
# $$
# \underbrace{\left[\begin{array}{cccc}
# t_0-t_0 & 0 & 0 & ...\\
# t_1-t_0 & t_1-t_1 & 0 & ...\\
# t_2-t_0 & t_2-t_1 & t_2-t_2 & ...\\
# ... & ... & ... & ...
# \end{array}\right]}_{(t-t_j)\cdot \sigma(t-t_j)}\cdot
# \underbrace{\left[\begin{array}{ccc}
# a_{1,0} & a_{2,0} & ...\\
# a_{1,1} & a_{2,1} & ...\\
# a_{1,2} & a_{2,2} & ...\\
# ... & ... & ...\\
# \end{array}\right]}_{A} =
# \underbrace{\left[\begin{array}{ccc}
# a_{1,0}\cdot(t_0-t_0) & a_{2,0}\cdot(t_0-t_0) & ...\\
# a_{1,0}\cdot(t_1-t_0)+a_{1,1}\cdot(t_1-t_1) & a_{2,0}\cdot(t_1-t_0)+a_{2,1}\cdot(t_1-t_1) & ...\\
# a_{1,0}\cdot(t_2-t_0)+a_{1,1}\cdot(t_2-t_1)+a_{1,2}\cdot(t_2-t_2) & a_{2,0}\cdot(t_2-t_0)+a_{2,1}\cdot(t_2-t_1)+a_{2,2}\cdot(t_2-t_2) & ...\\
# ... & ... & ...\\
# \end{array}\right]}_{\mathrm{synth\ curves}}
# $$
#
# example below with two series $i=\{1,2\}$
# %%
from numpy import array,linspace
from matplotlib import pyplot as plt
steps_times=array([
[0,0,0],
[3,0,-1],
[4,0,1],
[6,3/5,0],
[8,0,2],
[8.5,0,-2],
[11,-3/5,0],
[14,-1.5/2,0],
[16,-1.5/2,0.5],
[17,1.5,-0.5],
[20,0,0]
])
times=steps_times[:,0]
steps=steps_times[:,[1,2]]
lt=array([[times[i]-times[j] if times[i]-times[j]>=0 else 0 for j in range(times.shape[0])] for i in range(times.shape[0])])
synth_ramps=array([2,1])+lt.dot(steps)
times_extended=linspace(times.min(),times.max(),1000)
sigma=array([[1 if times_extended[i]-times[j]>=0 else 0 for j in range(times.shape[0])] for i in range(times_extended.shape[0])])
slopes=sigma.dot(steps)
print('lower triangular (t-tj)sigma(t-tj)) \n',lt)
fig,ax_list=plt.subplots(nrows=3,ncols=1,height_ratios=[1,1/2,1/2],constrained_layout=True)
ax_list[0].plot(times,synth_ramps,'-o')
for j in range(steps.shape[1]):
ax_list[1].stem(times,steps[:,j],markerfmt=['blue','orange'][j],label=f'series i={j+1}')
ax_list[2].plot(times_extended,slopes[:,j],label=f'series i={j+1}')
for j in range(len(times)):
ax_list[2].axvline(times[j],linestyle='--',color=[0.7,0.7,0.7])
ax_list[-1].set_xlabel('time $t_j$')
ax_list[0].set_ylabel('$y_i$')
ax_list[1].set_ylabel('$a_{i,j}$')
ax_list[2].set_ylabel(r'$\frac{dy_i}{dt}$')
ax_list[0].legend([f'series i={j+1}' for j in range(steps.shape[1])],loc='center left',bbox_to_anchor=[1.01,0.5]);
ax_list[1].legend(loc='center left',bbox_to_anchor=[1.01,0.5])
ax_list[2].legend(loc='center left',bbox_to_anchor=[1.01,0.5]);
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment