pythonnumpyoptimizationwaveform

How to get a square wave with specific tails length by using numpy?


I'm trying to represent a special square ware characterized by some feature as represented here: square wave features

all values are related to thick parameter. Tails are related to the thick parameter and to the total length (the size of the tail is equal to three times the thickness plus a remainder which depends on the number of notches that can be placed in the total length).

here is the code that allowed me to obtain some good results:

import numpy as np

thick = 4
length =  60
gap = 2*thick
remain = length % thick
tail = 3*thick + remain 

half_floor_division = int(((length-tail) // (thick*2)))
motif = np.full(half_floor_division,gap)
motif = np.concatenate([[tail],motif[:-1],[tail]])

x = np.cumsum(motif)
x = np.insert(x, 0, 0., axis=0)

x = np.repeat(x,2 )[1:-1]
y = np.tile([0,0,thick,thick],int(np.ceil(len(x)/4)))[:len(x)]

and here are some results obtained with different lengths and thicknesses:

some examples

Well the code seems a little complicated to me... I have the impression that there is a way to make it simpler... and in addition it is unstable since for certain values ​​the end of the pattern is no longer correct.

Anyone have any advice? or another approach to correct the situation?


Solution

  • In your "OK" examples the parts do not add up to the length...

    I don't fully understand what numpy array you are trying to build, but to compute the values of the parameters, I think the easiest way is to take away from length the two default tails and one gap. What's left will be an unknonwn number of gap pairs including a valley and a crest, plus the two remains to add to each tail.

    In code, this would look like:

    def get_motif(length, thick):
        gap = 2 * thick
        tail = 3 * thick
        n, remain = divmod(length - 2 * tail - gap, 2 * gap)
        tail += remain / 2
        motif = [tail] + [gap] * (2 * n + 1) + [tail]
        assert sum(motif) == length
        return motif
    

    Running this on your first and last examples:

    >>> get_motif(60, 4)
    [18.0, 8, 8, 8, 18.0]
    >>> get_motif(75, 3)
    [10.5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 10.5]