Transforming a sawtooth into a sinus with one parameter

150 Views Asked by At

Can you help me in finding the analytical expression of a function $f_\alpha(\theta)$, with one parameter $\alpha=(0,1)$ by which one can continously transform a sawtooth curve into a sinus?

With $\alpha=0$, I'd like to have $f_0(\theta)=\sin(2\theta)$.

With $\alpha=1$, I'd like to have $f_1(\theta)=sawtooth(\theta)$.

where $sawtooth(2\theta)$ is the 100% asymmetric sawtooth, $\pi$ periodic, like $sawtooth(t) = 2(\frac{t}{\pi}-floor(0.5+\frac{t}{\pi}))$

I've been trying adding Fourier components, low pass and other filters, but I cannot get a smooth change from one to the other when changing $\alpha$.

This animation (from wikipedia) can be an example, but I don't want the little ripples due to the finite number of Fourier components.

Thanks

1

There are 1 best solutions below

0
On

I post my own answer, hoping it can be useful. It is a script (in python), which builds what I need from Fourier components and filtering. The output is a curve with one parameter $m$ which can go from a $sin(2\theta)$ to a sawtooth$(2\theta)$. However it's not an analytical function, so the question remains open. GRAPH here

def sin2sawtooth(m, sawint=1, plots=False):

    ''' calculate the curve f_m(theta), 
    function of theta=(0,2pi), with free parameter 'm'.
    m = [0,100] is the symmetry of the curve, 
    with m = 1, it gives a sawtooth(2 theta) curve, 
    and  m = 100, it gives a sin(2 theta).
    sawint = intensity of the curve
    plots = False|True : plot result
    '''

    import numpy as np
    import matplotlib.pyplot as plt
    import scipy.ndimage.filters

    # define variable theta:
    theta = np.linspace(0, 2*np.pi, 1000)
    # force m to be an integer in [1,100]:
    m = int(np.clip(m, 1, 100))
    # define number of fourier components to build the sawtooth 'L' :
    if m == 100: L = 1
    else: L = 200
    # make theta longer to avoid edge effects:
    theta_conc = np.append(theta-2*np.pi, np.append(theta, theta+2*np.pi))
    saw = np.zeros(len(theta_conc))
    # build 'saw' by sum of fourier components:
    for k in range(1, L+1):
        saw = saw + 1/np.pi*(np.sin(2*k*theta_conc)/k )
    # gaussian filter: 
    saw = scipy.ndimage.filters.gaussian_filter(saw, m)
    # crop theta in 0,2pi:
    saw = saw[len(theta): 2*len(theta)]
    # normalize 'saw' between 0-1 :
    saw = (saw-np.min(saw))/(np.max(saw)-np.min(saw))
    if plots:
        plt.figure(3241)
        plt.plot(theta, saw)
        plt.grid(True)
    return saw