Source code for perturb

"""
Base Control Profiles for System excitation
"""

import numpy as np
import random as rd
from scipy import interpolate
from scipy import signal as sig


[docs]def RandomWalk(nx=1, nsim=100, xmax=1, xmin=0, sigma=0.05, rseed=1): """ :param nx: (int) State space dimension :param nsim: (int) Number of simulation steps :param xmax: (float) Upper bound on state values :param xmin: (float) Lower bound on state values :param sigma: (float) Variance of normal distribution :param rseed: (int) Set random seed :return: """ rd.seed(rseed) if type(xmax) is not np.ndarray: xmax = np.asarray(nx*[xmax]).ravel() if type(xmin) is not np.ndarray: xmin = np.asarray(nx*[xmin]).ravel() Signals = [] for k in range(nx): Signal = [0] for t in range(1, nsim): yt = Signal[t - 1] + np.random.normal(0, sigma) if (yt > 1): yt = Signal[t - 1] - abs(np.random.normal(0, sigma)) elif (yt < 0): yt = Signal[t - 1] + abs(np.random.normal(0, sigma)) Signal.append(yt) Signals.append(xmin[k] + (xmax[k] - xmin[k])*np.asarray(Signal)) return np.asarray(Signals).T
[docs]def WhiteNoise(nx=1, nsim=100, xmax=1, xmin=0, rseed=1): """ White Noise :param nx: (int) Number signals :param nsim: (int) Number time steps :param xmax: (int/list/ndarray) signal maximum value :param xmin: (int/list/ndarray) signal minimum value :param rsee: (int) Set random seed """ rd.seed(rseed) if type(xmax) is not np.ndarray: xmax = np.asarray(nx*[xmax]).ravel() if type(xmin) is not np.ndarray: xmin = np.asarray(nx*[xmin]).ravel() Signal = [] for k in range(nx): signal = xmin[k] + (xmax[k] - xmin[k])*np.random.rand(nsim) Signal.append(signal) return np.asarray(Signal).T
[docs]def Step(nx=1, nsim=100, tstep=50, xmax=1, xmin=0, rseed=1): """ step change :param nx: (int) Number signals :param nsim: (int) Number time steps :param tstep: (int) time of the step :param xmax: (int/list/ndarray) signal maximum value :param xmin: (int/list/ndarray) signal minimum value :param rseed: (int) Set random seed """ rd.seed(rseed) if type(xmax) is not np.ndarray: xmax = np.asarray(nx * [xmax]).ravel() if type(xmin) is not np.ndarray: xmin = np.asarray(nx * [xmin]).ravel() Signal = [] for k in range(nx): signal = np.ones(nsim) signal[0:tstep] = xmin[k] signal[tstep:] = xmax[k] Signal.append(signal) return np.asarray(Signal).T
[docs]def Steps(nx=1, nsim=100, values=None, randsteps=5, xmax=1, xmin=0, rseed=1): """ :param nx: (int) Number signals :param nsim: (int) Number time steps :param values: (list/ndarray) sequence of step changes, e.g., [0.4, 0.8, 1, 0.7, 0.3, 0.0] :param randsteps: (int) number of random step changes if values is None :param xmax: (int/ndarray) signal maximum value :param xmin: (int/ndarray) signal minimum value :param rseed: (int) Set random seed :return: """ rd.seed(rseed) if values is None: values = np.round(np.random.rand(randsteps), 3) if type(values) is not np.ndarray: values = np.asarray([values]).ravel() if type(xmax) is not np.ndarray: xmax = np.asarray(nx*[xmax]).ravel() if type(xmin) is not np.ndarray: xmin = np.asarray(nx*[xmin]).ravel() step_length = int(np.ceil(nsim/len(values))) signal = np.ones([nx, nsim]) for j in range(nx): for k in range(len(values)): signal[j, k*step_length:(k+1)*step_length] = values[k]*(xmax[j]-xmin[j])+xmin[j] return signal.T
[docs]def sawtooth(nx=1, nsim=100, numPeriods=1, xmax=1, xmin=0, rseed=1): """ ramp change :param nx: (int) Number signals :param nsim: (int) Number time steps :param numPeriods: (int) Number of periods :param xmax: (int/list/ndarray) signal maximum value :param xmin: (int/list/ndarray) signal minimum value :param rseed: (int) Set random seed """ rd.seed(rseed) assert nsim >= numPeriods, 'numPeriods must be smaller than nsim' if type(xmax) is not np.ndarray: xmax = np.asarray([xmax] * nx).ravel() if type(xmin) is not np.ndarray: xmin = np.asarray([xmin] * nx).ravel() xmax = xmax.reshape(nx) xmin = xmin.reshape(nx) t = np.linspace(0, 1, nsim) Signal = [] for k in range(nx): signal = xmin[k] + (xmax[k] - xmin[k])*(0.5 * (sig.sawtooth(2 * np.pi * numPeriods * t) + 1)) Signal.append(signal) return np.asarray(Signal).T
[docs]def Periodic(nx=1, nsim=100, numPeriods=1, xmax=1, xmin=0, form='sin', rseed=1): """ periodic signals, sine, cosine :param nx: (int) Number signals :param nsim: (int) Number time steps :param numPeriods: (int) Number of periods :param xmax: (int/list/ndarray) signal maximum value :param xmin: (int/list/ndarray) signal minimum value :param form: (str) form of the periodic signal 'sin' or 'cos' :param rseed: (int) Set random seed """ rd.seed(rseed) assert nsim >= numPeriods, 'numPeriods must be smaller than nsim' if type(xmax) is not np.ndarray: xmax = np.asarray([xmax]*nx).ravel() if type(xmin) is not np.ndarray: xmin = np.asarray([xmin]*nx).ravel() xmax = xmax.reshape(nx) xmin = xmin.reshape(nx) samples_period = nsim// numPeriods leftover = nsim % numPeriods Signal = [] extraPeriods = 0 if leftover > samples_period: extraPeriods = leftover//samples_period leftover = leftover % samples_period for k in range(nx): if form == 'sin': base = xmin[k] + (xmax[k] - xmin[k])*(0.5 + 0.5 * np.sin(np.arange(0, 2 * np.pi, 2 * np.pi / samples_period))) elif form == 'cos': base = xmin[k] + (xmax[k] - xmin[k])*(0.5 + 0.5 * np.cos(np.arange(0, 2 * np.pi, 2 * np.pi / samples_period))) signal = np.tile(base, numPeriods+extraPeriods) signal = np.append(signal, base[0:leftover]) Signal.append(signal) return np.asarray(Signal).T
[docs]def SplineSignal(nsim=500, values=None, xmin=0, xmax=1, rseed=1): """ Generates a smooth cubic spline trajectory by interpolating between data points :param nsim: (int) Number of simulation steps :param values: (np.array) values to interpolate :param xmin: (float) Minimum value of time series :param xmax: (float) Maximum value of time series :param rseed: (int) Set random seed. :return: """ if values is None: rd.seed(rseed) values = [rd.triangular(xmin, xmax) for _ in range(30)] dt = int(np.ceil(nsim / len(values))) dt_time = np.arange(0, nsim, dt) cs = interpolate.CubicSpline(dt_time, values[:len(dt_time)], extrapolate='periodic') time = np.arange(0, nsim) return cs(time)