# Reference

`CedarWaves.hanning`

— Constanthanning

A hanning windowing function over the domain -0.5..0.5

`CedarWaves.Bandpass`

— TypeBandpass(f1, f2)

Represents a band-pass filter with a pass band between frequencies w1 and w2

`CedarWaves.Bandstop`

— TypeBandstop(f1, f2)

Represents a band-stop filter with a stop band between frequencies w1 and w2

Band-stop FIR filters require an impulse function that hampers integration. Consider using other filter types where possible.

`CedarWaves.CrossMeasure`

— Type`CrossMeasure(signal, x; yth, options...)`

Measurement of an X at an intersecting y-threshold (`yth`

).

`CedarWaves.DxMeasure`

— Type`DxMeasure(point1, point2; options...)`

Measurement of a difference (`point2.x - point1.x`

) in two X values on the same signal (period, frequency, etc).

`CedarWaves.DyMeasure`

— Type`DyMeasure(point1, point2; options...)`

Measurement of a difference (`point2.y - point1.y`

) in two Y values on the same signal (`peak2peak`

, etc.)

`CedarWaves.Highpass`

— TypeHighpass(f)

Represents a high-pass filter with cut-off frequency w

High-pass FIR filters require an impulse function that hampers integration. Consider using a band-pass filter where possible.

`CedarWaves.Interval`

— Type`Interval(start, stop)`

Defines an interval from the `start`

`to`

stop``value. Can also be written as`

start .. stop` to create an Interval.

**Examples**

```
julia> a = 1 .. 3
[1 .. 3]
julia> first(a) == 1
true
julia> last(a) == 3
true
julia> 1.2 in a
true
julia> 10 in a
false
```

`CedarWaves.Lowpass`

— TypeLowpass(f)

Represents a low-pass filter with cut-off frequency w

`CedarWaves.OnlineSignalFactory`

— Method```
OnlineSignalFactory([buffersize])
OnlineSignalFactory{XT, YT, DI}([buffersize])
```

Create a factory for online signals with an optional buffer size argument. It also accepts type parameters for the data types and interpolation type. These default to `Float64`

and `LinearInterpolation`

respectively.

An online signal is one that is backed by a `Channel`

and `CircularBuffer`

for samples. A simulator or parser can push `(x, y)`

samples onto the channel which get added to the buffer. (The buffer is shared between signals made in this factory) Iterative measures can then run `@async`

to analyse the data as it comes in.

Not all functions are compatible with online analysis. Online analysis works best with functions that return iterators. Functions based on integrals are not suitable.

An online signal must consume all its samples exactly once. Online signals that are not consumed will block the channel when it becomes full. Online signals that are consumed more than once will return incorrect results.

Example:

```
sf = OnlineSignalFactory(50)
@sync begin
@async for (x, y) in eachxy(new_online(sf))
if y > 0.8 || y < -0.8
println("signal exceeded limits at ", x)
end
end
for t in 0:0.1:10
put!(sf.ch, (t, sinpi(t^1.5)))
end
close(sf.ch)
end
pp = postprocess(sf)
println("rms: ", rms(pp))
```

A complete demo can be found in `/demos/online/online.jl`

.

See also `new_online`

, `postprocess`

,

`CedarWaves.Periodic`

— Type`Periodic(func, interval)`

Returns a function with input `x`

that wraps down to the base `interval`

and then applies function `func`

.

```
julia> f = Periodic(x->2x-3, 1 .. 2);
julia> f(0.0)
-1.0
julia> f(1.0)
-1.0
julia> f(2.0)
-1.0
julia> f(0.5)
0.0
julia> f(1.5)
0.0
julia> f(2.5)
0.0
```

`CedarWaves.SampledFunction`

— Type`SampledFunction`

Represents a function that is iteratable, used for wrapping an AbstractInterpolation

`CedarWaves.Signal`

— Type`Signal`

`Signal`

is the base type representing a `PWL`

, `PWC`

, `Series`

, or contiunous function (e.g. `SIN`

). The main properties are that it tracks transforms such that they may be performed lazily for perfomance and ease of debugging. In additon, it tracks the domains, interpolation types, and whether or not the signal is periodic.

**Construction**

The signal type can be treated as either a function or a vector of data. Piecewise-Linear (`PWL`

), Piecewise-constant (`PWC`

), Series (`Series`

) or a continuous function (`ContinuousFunction`

) can be created, as follows:

```
julia> s1 = PWL(1:5, 2:6);
julia> s2 = PWC(1:5, 2:6);
julia> s3 = Series(1:5, 2:6);
julia> s4 = ContinuousFunction(x->sin(x));
```

**Evaluation**

To get the value of the signal (including between indicies) call the signal with the `x`

value as follows. When calling the `Signal`

as a function, all `full_transform`

are applied, see below for (`y_transform`

) details.

```
julia> s1 = PWL(1:5, 2:6)^2; # `y_transform` to square the signal
julia> s1(1.5)
6.25
```

The key property of the `Signal`

type, is that it behaves like a function, and has selectable interpolations over the `base_y`

and `base_x`

values. This interpolation function is stored in the following field:

`full_transform`

For example, calling `abs`

on a `Signal`

, the `abs`

function will be lazily composed into the `y_transform`

field, returning a new `Signal`

The main domains are represent by three fields:

`base_x_interval`

: the underlying sampled data duration or period of the signal.`extrapolated_x_interval`

: the total domain of the signal, including repititions.`clipped_x_interval`

: represents constraints on the domain for clip-windowing opertations.

Note: that for non-period signals, the `base_x_interval`

and `extrapolated_x_interval`

are the same.

In additon, the follow fields is present:

`xshift`

`xscale`

These are used to represent shifts and scaling of the x axis.

**Clip**

When introspecting a signal, `clip`

functions allow for one to focus into an area of interest. When calling `clip`

on the signal the interval and indexing properties will change. This allows algorithms on a `Signal`

resultant from a `clip`

operation to only consider the area of interest, thereby improving performance. Note, that the `clip`

operation on piecewise `Signals`

will grow the indicies to cover the area of interest, though the intervals will be those requested in the clip operation.

```
julia> s1 = PWL(0:2, [1,-1,0]);
julia> s2 = clip(s1, 0.5 .. 1.5);
julia> s2(0.5)
0.0
julia> s2(1)
-1.0
julia> s2(1.5)
-0.5
```

Clips, compose by `intersect`

ion of the request intervals against the current `clipped_x_interval`

of the signal. To undo a clip, a restore it to the total domain of the signal, `clip(s)`

may be used.

**Internal**

In additon to these three intervals, if the signal is derived from some form of sampled data, the following additonal fields will be populated:

`base_indicies`

`extrapolated_indicies`

`clipped_indicies`

The purpose of these is to track the mathematical covering of the domain. For example, if we have data in the integral range 1:5, and we perform a clip, from 2.5...3.5, we will track these indicies as 2:4.

`CedarWaves.SlopeMeasure`

— Type`SlopeMeasure(point1, point2; options...)`

Measurement of a difference in two Y values on the same signal (slewrate, etc.)

`CedarWaves.Threshold`

— TypeA y-crossing with a direction of `rising`

, `falling`

or `either`

.

`CedarWaves.TwoPointMeasure`

— Type`abstract type TwoPointMeasure <: AbstractMeasure end`

A abstract result holder for a two-point measurement on a single signal. The measure will display a graphical preview of the signal and measurement and it can also be used like a regular number in math expressions. User should create their own type with the minimum fields below:

```
struct MyMeasure <: TwoPointMeasure
pt1::AbstractMeasure
pt2::AbstractMeasure
options::MeasureOptions
end
```

`CedarWaves.XMeasure`

— Type`XMeasure(signal, x; options...)`

Measurement of an X value with a corresponding Y value (such as a cross, xmin, xmax, etc).

`CedarWaves.YLevelMeasure`

— Type`YLevelMeasure(signal, y; options...)`

Measurement of a Y value (level) with no corresponding X value (mean, etc).

`CedarWaves.YMeasure`

— Type`YMeasure(signal, x; options...)`

Measurement of an X value with a corresponding Y value (such as a cross, xmin, xmax, etc).

`CedarWaves.ZeroPad`

— Type`ZeroPad(func, interval)`

Returns a function that wraps the input function `func`

such that it returns zero when outside the `interval`

.

```
julia> f = ZeroPad(cos, 0 .. 2pi);
julia> f(-1)
0.0
julia> f(0)
1.0
julia> f(pi)
-1.0
julia> f(10)
0.0
```

See also `clip`

.

`CedarWaves.ZeroPad`

— Method`ZeroPad(signal[, interval])`

Pads the left and right of a signal with zeros. If no `interval`

is defined for where the zero padding starts and ends then it uses the current signal domain. The zero padding extends the parent domain to infinity.

```
julia> pulse = clip(ZeroPad(PWL([0, 0.5], [1, 1])), 0 .. 1);
julia> pulse(0.75)
0.0
```

`CedarWaves.either`

— Type`either(yth)`

A rising or falling edge with a crossing threshold.

See also `pct`

.

**Examples:**

To trigger on either a rising or falling edge at y-value of 0.5

`either(0.5)`

To trigger on either a rising or falling edge at y-value of 90% of full swing

`either(90pct)`

`CedarWaves.either`

— MethodThe rising or falling edge threshold

`CedarWaves.falling`

— Type`falling(yth)`

A falling edge with a crossing threshold.

See also `pct`

.

**Examples:**

To trigger on a falling edge at y-value of 0.5

`falling(0.5)`

To trigger on a falling edge at y-value of 90% of full swing

`falling(90pct)`

`CedarWaves.falling`

— MethodThe falling edge threshold

`CedarWaves.rising`

— Type`rising(yth)`

A rising edge with a crossing threshold.

See also `pct`

.

**Examples:**

To trigger on a rising edge at y-value of 0.5

`rising(0.5)`

To trigger on a rising edge at y-value of 90% of full swing

`rising(90pct)`

`Base.Math.clamp`

— Method`clamp(signal, y_interval)`

Restrict the y-values to be between the `y_interval`

**Examples**

```
julia> c = clamp(PWL([1, 10], [-10, 10]), -3 .. 3);
julia> c(4)
-3.0
julia> c(7)
3.0
```

`Base.angle`

— Method```
angle(x)
angle(signal)
```

Returns a signal with the (complex) y-values converted to radians. Alias for `phase`

.

Since `pi`

is an approximate number it is better for accuracy to work in degrees, see `phased`

.

**Examples**

```
julia> angle(1)
0.0
julia> angle(1 + 1im) ≈ 2pi/8
true
julia> s = angle(PWL(0:1, [1, im]));
julia> s(0.5) ≈ 2pi/8
true
```

See also `abs`

, `real`

, `imag`

, `conj`

, `phase`

, `phased`

, `angle`

, `rad2deg`

, `deg2rad`

.

`Base.extrema`

— Method`extrema(signal)`

Faster version of `(ymin(sig), ymax(sig))`

. See also `peak2peak`

.

**Examples**

```
julia> extrema(PWL(0:3, [0,1,-1,1]))
(-1.0, 1.0)
```

See also `xmin`

, `xmax`

, `xspan`

, `ymin`

, `ymax`

, `minimum`

, `maximum`

, `peak2peak`

.

`Base.isfinite`

— Method`isfinite(signal)`

Returns true if the domain of a signal is not infinite.

```
julia> s = ContinuousFunction(sin);
julia> isfinite(s)
false
```

See also `clip`

, `ContinuousFunction`

, `PWL`

, `PWL`

, `Series`

.

`Base.maximum`

— Method`maximum(signal)`

Returns the maximum y-value of a signal. Alias for `ymax`

.

**Examples**

```
julia> maximum(PWL(0:3, [0,1,0,1]))
1.0
julia> maximum(Series(0:3, [0,1,0,1]))
1
```

See also `xmin`

, `xmax`

, `xspan`

, `ymin`

, `ymax`

, `minimum`

, `extrema`

, `peak2peak`

.

`Base.minimum`

— Method`minimum(signal)`

Returns the minimum y-value of a signal. Alias for `ymin`

.

**Examples**

```
julia> minimum(PWL(0:3, [0,1,-2,1]))
-2.0
julia> minimum(Series(0:3, [0,-11,-2,1]))
-11
```

See also `xmin`

, `xmax`

, `xspan`

, `ymin`

, `ymax`

, `maximum`

, `extrema`

, `peak2peak`

.

`Base.sum`

— Method`sum(discrete_signal)`

Returns the sum of a discrete signal's y-values over its domain acccording to the formula:

\[\mathrm{sum}(s)=\sum_{n=\mathrm{xmin}(s)}^{\mathrm{xmax}(s)} s[n]\]

**Examples**

```
julia> sum(eachy(Series(0:2, [0,12,0])))
12
```

`CedarWaves.Butterworth`

— Method`Butterworth(n)`

$n$ pole Butterworth filter.

`CedarWaves.Chebyshev1`

— Method`Chebyshev1(n, ripple)`

`n`

pole Chebyshev type I filter with `ripple`

dB ripple in the passband.

`CedarWaves.Chebyshev2`

— Method`Chebyshev2(n, ripple)`

`n`

pole Chebyshev type II filter with `ripple`

dB ripple in the stopband.

`CedarWaves.ContinuousFunction`

— Method`ContinuousFunction(func; domain=-Inf..Inf, period=Inf)`

Returns a continuous signal over the given domain.

**Examples**

```
julia> s = ContinuousFunction(turns -> sinpi(2turns); domain=-2 .. 2);
julia> s(1//4) # sine at 1/4 revolution
1.0
```

For the domain of the signal above `-2 .. 2`

is the notation for a continuous `Interval`

from `-2`

to `2`

.

Functions of infinite domain can aslo be created and then clipped to a finite domain. The benefit of this it allows the user to change the clip interval to any value since the parent signal has an infinite domain.

```
julia> COS = clip(ContinuousFunction(cos), 0 .. 8pi);
julia> COS(2pi)
1.0
```

See also `PWL`

, `PWQuadratic`

, `PWCubic`

, `PWAkima`

, `ContinuousFunction`

, `Series`

, `domain`

.

`CedarWaves.DFT`

— Method`DFT(s; N)`

Returns a Discrete Fourier Transform function of a continuous signal, `s`

, sampled at `N`

uniform points, according to the formula:

\[\big(\mathrm{DFT}(s)\big)(\mathit{freq}) = S(\mathit{freq}) = \frac{1}{N} \sum_{n=0}^{N-1} s(n T_\mathit{step}) \exp\left(-j 2\pi \mathit{freq}\, n T_\mathit{step}\right)\]

where:

`N`

is the number of uniform sampling points over the the`signal`

`freq`

is in Hertz and is a muliple of`Fmin = 1/xspan(signal)`

`Tstep`

is`xspan(signal)/N`

The input signal is assumed to be periodic outside of its (clipped) domain such that `s(t) = s(t+N*Tstep)`

for all `t`

.

**Options**

`N`

is the number of samples to use over the period.

The DFT is two-sided meaning the amplitude of a signal is half at the positive frequency and half at the negative frequency (except for DC).

**Examples**

```
julia> dft = DFT(signal);
julia> dft(0) # DC value
0.5 + 0.0im
julia> plot(dft) # plot the result
```

By default the domain of the transform is clipped to `0 .. 10`

. To change the domain use `clip`

like `clip(DFT(signal), 0 .. 100)`

. Infinite domains are not returned by default because they cannot be plotted (in finite time).

`CedarWaves.DTFT`

— Method`DTFT(signal; [, integral_options...])`

This is not yet implemented.

Returns a Discrete Time Fourier Transform function of a discrete signal, `signal`

, sampled at uniform points, according to the formula:

\[\big(\mathrm{DTFT}(s)\big)(\mathit{freq}) = S(\mathit{freq}) = \sum_{n=-\infty}^{\infty} s(n T_\mathit{step}) \exp\left(-j 2\pi \mathit{freq}\,n\right)\]

The Discrete Time Fourier Transform is for discrete aperiodic signals of infinite duration. Input signals with finite duration are automatically zero padded to ±infinity. The output is a function of the frequency `freq`

which is from -0.5 to 0.5. To get the value of the Discrete Time Fourier Transform call the transform with the frequency of interest:

```
julia> dtft = DTFT(signal);
julia> dtft(0) # DC value
0.5 + 0.0im
```

**Options**

`integral_options`

are options that can be passed to`integral`

.

`CedarWaves.Elliptic`

— Method`Elliptic(n, rp, rs)`

`n`

pole elliptic (Cauer) filter with `rp`

dB ripple in the passband and `rs`

dB attentuation in the stopband.

`CedarWaves.FFT`

— Method`FFT(s; N)`

Returns a Fast Fourier Transform of a signal evaluated at N points.

**Examples**

```
julia> freq = 100;
julia> t = 0:1e-3:1.025;
julia> y = sin.(2π * freq .* t);
julia> s = PWL(t, y);
julia> ft = FFT(s);
julia> ym = ymax(abs(ft));
julia> abs(freq - abs(ym.x)) < 1 / xspan(s)
true
```

`CedarWaves.FS`

— Method`FS(signal[, integral_options...])`

Returns a Fourier Series function of a continuous-time signal, `signal`

, with finite duration according to the formula:

\[\big(\mathrm{FS}(s)\big)(\mathit{freq}) = S(\mathit{freq}) = \frac{1}{T} \int_{0}^{T} s(x) \exp\left(-j 2\pi \mathit{freq}\, x\right) \,\mathrm{d}x\]

The frequency-domain series returned is discrete and infinite extent with components at `freq = k*Fmin`

where `k = ... -2, -1, 0, 1, 2 ...`

.

```
julia> T = 2
2
julia> pulse = clip(ZeroPad(PWL([-T/4, T/4], [1.0, 1.0])), -T/2 .. T/2);
julia> fs = real(FS(pulse));
julia> fs(0) # DC value
julia> fs(1) # 0.5 Hz
julia> fs(2) # 1.0 Hz
julia> fs(3) # 2.0 Hz
julia> fs(4) # 2.5 Hz
julia> fs(5) # 3.0 Hz
julia> fs = FS(signal);
julia> fs(0) # DC value
0.5 + 0.0im
julia> plot(fs) # plot the result
```

**Options**

`integral_options`

are options that can be passed to`integral`

.

By default the domain of the transform is clipped to `0 .. 10`

. To change the domain use `clip`

like `clip(FS(signal), 0 .. 100)`

. Infinite domains are not returned by default because they cannot be plotted (in finite time).

`CedarWaves.FT`

— Method`FT(signal[, integral_options...])`

Return a `Signal`

which is the Fourier Transform function of another continuous signal, `signal`

, with infinite duration, according to the formula:

\[\big(\mathrm{FT}(s)\big)(\mathit{freq}) = S(\mathit{freq}) = \int_{-\infty}^{+\infty} s(x) \exp(-j 2\pi \mathit{freq}\,x) \,\mathrm{d}x\]

The Fourier Transform is for aperiodic signals of infinite duration. Input signals with finite duration are automatically zero padded to ±infinity. To get the value of the Fourier Transform call the transform with the frequency of interest:

```
julia> ft = FT(signal);
julia> ft(0) # DC value
0.5 + 0.0im
```

**Options**

`integral_options`

are options that can be passed to`integral`

.

By default the output domain of the transform is clipped to `±10/xspan(signal)`

. To change the domain use `clip`

like `clip(FT(signal), 0 .. 1e6)`

. Infinite domains are not returned by default because they cannot be plotted (in finite time).

**Examples**

For an ideal pulse in the time domain of 2 seconds and amplitude 10 we use an ideal square wave (no risetime) and the Fourier Transforms assumes the signal is zero outside of its defined domain. Since the pulse is centered around zero it is an even function so the Fourier Transform will be real values only.

```
julia> A=10;
julia> w=2;
julia> pulse = PWL([-w/2, w/2], [A, A]);
julia> ft = FT(pulse);
julia> answer(f; A=A, w=w) = A*w*sinc(f*w);
julia> ft(0) == answer(0)
true
julia> ft(0.25) ≈ answer(0.25)
true
```

The following example uses the Fourier Transform to compute the Fourier Series components by dividing the FT by `xspan(s)`

to normalize the results to periodic sinusoid amplitudes:

```
julia> t = PWL(0 .. 2, 0 .. 2);
julia> s = 0.5 + 3sinpi(2*2t) + 2cospi(2*4t);
julia> ft = abs(FT(s)/xspan(s));
julia> abs(ft(0)) ≈ 0.5 # DC component
true
julia> abs(ft(2)) + abs(ft(-2)) ≈ 3 # 2 Hz component
true
julia> abs(ft(4)) + abs(ft(-4)) ≈ 2 # 4 Hz component
true
```

The above is useful if the Fourier Series components are wanted but with the x-axis being frequency instead of an integer multiplies of the fundamental harmonic `1/xspan(s)`

.

`CedarWaves.PWAkima`

— Function```
PWAkima(xs, ys)
PWAkima(x_interval, y_interval)
PWAkima(xs, signal)
PWAkima(xs, function)
```

Returns a non-smooth signal with piecewise-akima spline interpolation over the x-values. An Akima spline interpolation is realistic for analog signals and hits each sample point exactly.

The first form takes a vector of x- and corresponding y-values. The second form takes two intervals for the domain of the signal. The third form the y-values come from sampling a signal `signal`

at the x-values, `xs`

while the fourth form samles a `function`

.

**Examples**

```
julia> s = PWAkima(0:4, [0, 1, 1, 0, 3]);
julia> s(1) == 1.0 # samples maintained
true
julia> s(1.5)
1.0875
```

See also `PWC`

, `PWL`

, `PWQuadratic`

, `PWCubic`

, `PWAkima`

, `ContinuousFunction`

, `Series`

, `domain`

.

`CedarWaves.PWC`

— Function```
PWC(xs, ys)
PWC(xs, signal_or_function)
```

Returns a continuous signal with piecewise-constant interpolation between x-values. The first form takes a vector of x- and corresponding y-values. The second form the y-values come from sampling a signal `signal`

(or function) at the x-values, `xs`

.

**Examples**

```
julia> s1 = PWC(0:3, [true, false, false, true]);
julia> s1(0.5)
true
julia> s1(1)
false
julia> sample_and_hold = PWC(0:45:360, sind); # sin in degrees
julia> yvals(sample_and_hold)
9-element Vector{Float64}:
0.0
0.7071067811865476
1.0
0.7071067811865476
0.0
-0.7071067811865476
-1.0
-0.7071067811865476
0.0
```

See also `PWL`

, `PWQuadratic`

, `PWCubic`

, `PWAkima`

, `ContinuousFunction`

, `Series`

, `domain`

.

`CedarWaves.PWCubic`

— Function```
PWCubic(xs, ys)
PWCubic(x_interval, y_interval)
PWCubic(xs, signal)
PWCubic(xs, function)
```

Returns a continuous signal with piecewise-cubic spline interpolation over the x-values. A cubic spline interpolation is continuously differentiable and hits each sample point exactly.

The first form takes a vector of x- and corresponding y-values. The second form takes two intervals for the domain of the signal. The third form the y-values come from sampling a signal `signal`

at the x-values, `xs`

while the fourth form samles a `function`

.

**Examples**

```
julia> s = PWCubic(0:4, [0, 1, 1, 0, 3]);
julia> s(1) == 1.0 # samples maintained
true
julia> s(1.5)
1.2522321428571428
```

See also `PWC`

, `PWL`

, `PWQuadratic`

, `PWCubic`

, `PWAkima`

, `ContinuousFunction`

, `Series`

, `domain`

.

`CedarWaves.PWL`

— Function```
PWL(xs, ys)
PWL(x_interval, y_interval)
PWL(xs, signal)
PWL(xs, function)
```

Returns a continuous signal with piecewise-linear interpolation over the x-values. The first form takes a vector of x- and corresponding y-values. The second form takes two intervals for the domain of the signal. The third form the y-values come from sampling a signal `signal`

at the x-values, `xs`

while the fourth form samles a `function`

.

**Examples**

```
julia> s = PWL(0:3, [0,1,1,0]);
julia> t = PWL(0 .. 1, 0 .. 1); # time axis
julia> s2 = 1.5 + 3sin(2pi*t) + sin(2pi*3t);
julia> s3 = PWL(0:0.25:1, s2); # sample s2
```

See also `PWC`

, `PWQuadratic`

, `PWCubic`

, `PWAkima`

, `ContinuousFunction`

, `Series`

, `domain`

.

`CedarWaves.PWQuadratic`

— Function```
PWQuadratic(xs, ys)
PWQuadratic(x_interval, y_interval)
PWQuadratic(xs, signal)
PWQuadratic(xs, function)
```

Returns a continuous signal with piecewise-quadratic interpolation over the x-values. A quadradic interpolation is continuously differentiable and hits each sample point exactly.

The first form takes a vector of x- and corresponding y-values. The second form takes two intervals for the domain of the signal. The third form the y-values come from sampling a signal `signal`

at the x-values, `xs`

while the fourth form samles a `function`

.

**Examples**

```
julia> s = PWQuadratic(0:4, [0, 1, 1, 0, 3]);
julia> s(1) == 1.0 # samples maintained
true
julia> s(1.5)
1.125
```

See also `PWC`

, `PWL`

, `PWQuadratic`

, `PWCubic`

, `PWAkima`

, `ContinuousFunction`

, `Series`

, `domain`

.

`CedarWaves.SIN`

— Method`SIN(; amp, freq, offset=0, phi=0, cycle=Inf)`

Returns a signal defined by `amp*sinpi((2*freq*x + phi)+offset)`

. If `cycle`

is not `Inf`

, the signal clipped to the interval `0 .. cycle/freq`

.

**Examples**

```
julia> s = SIN(amp=3, freq=2, offset=1);
julia> s(1/2 * 1/4)
4.0
```

See also `PWC`

, `PWL`

, `PWQuadratic`

, `PWCubic`

, `ContinuousFunction`

, `Series`

, `impulse`

, `domain`

.

`CedarWaves.Series`

— Function```
Series(xs, ys)
Series(xs, signal)
```

Returns a discrete point-wise signal with no interpolation. The first form takes a vector of x- and corresponding y-values. The second form the y-values come from sampling a signal `signal`

at the x-values, `xs`

.

**Examples**

```
julia> s = Series(0:3, [0,1,1,0]);
julia> s2 = Series([0, 3], s); # sample s2
julia> s3 = Series(-360:360, cosd);
```

See also `PWL`

, `PWC`

, `PWQuadratic`

, `PWCubic`

, `PWAkima`

, `ContinuousFunction`

, `domain`

.

`CedarWaves._ylim`

— Function`_ylim(object, extra_points)`

Return the y-axis limits for the object (such as a signal or measurement). This is similar to `extrema`

but skips `NaN`

values.

`CedarWaves.autocorrelation`

— Method`autocorrelation(signal)`

Computes the autocorrelation of a signal.

**Examples**

```
julia> t = 0:0.005:1;
julia> freq = 1;
julia> y = @. sin(2pi*freq*t);
julia> s = PWL(t, y);
julia> autocorr = autocorrelation(s);
julia> ym = ymax(autocorr);
julia> isapprox(ym.x, 0, atol=1e-10)
true
julia> ≈(ym, 0.5, atol=1e-4)
true
```

`CedarWaves.balance`

— Function`S, P, B = balance(A[, perm=true])`

Compute a similarity transform `T = S*P`

resulting in `B = T\A*T`

such that the row and column norms of `B`

are approximately equivalent. If `perm=false`

, the transformation will only scale `A`

using diagonal `S`

, and not permute `A`

(i.e., set `P=I`

).

`CedarWaves.balance_statespace`

— Function`A, B, C, T = balance_statespace{S}(A::Matrix{S}, B::Matrix{S}, C::Matrix{S}, perm::Bool=false)`

`sys, T = balance_statespace(sys::StateSpace, perm::Bool=false)`

Computes a balancing transformation `T`

that attempts to scale the system so that the row and column norms of [T*A/T T*B; C/T 0] are approximately equal. If `perm=true`

, the states in `A`

are allowed to be reordered. This is not the same as finding a balanced realization with equal and diagonal observability and reachability gramians, see `balreal`

`CedarWaves.balance_transform`

— Function`T = balance_transform{R}(A::AbstractArray, B::AbstractArray, C::AbstractArray, perm::Bool=false)`

`T = balance_transform(sys::StateSpace, perm::Bool=false) = balance_transform(A,B,C,perm)`

Computes a balancing transformation `T`

that attempts to scale the system so that the row and column norms of [T*A/T T*B; C/T 0] are approximately equal. If `perm=true`

, the states in `A`

are allowed to be reordered. This is not the same as finding a balanced realization with equal and diagonal observability and reachability gramians, see `balreal`

See also `balance_statespace`

, `balance`

`CedarWaves.bandwidth`

— Method`bandwidth(signal, yth; band=:lowpass, name=band, options...)`

Returns the bandwidth of a frequency-domain `signal`

. The `yth`

will be automatically converted to `rising`

or `falling`

depending on the filter `band`

type. The `yth`

is threshold in same units as `signal`

, not a drop from the maximum.

The following types of `band`

filter responses are supported:

`:lowpass`

: a lowpass filter with exactly one falling edge (Default)`:highpass`

: a highpass filter with exactly one rising edge`:bandpass`

: a bandpass filter with exactly one rising edge followed by exactly one falling edge`:bandreject`

: a notch filter with exactly one falling edge followed by exactly one rising edge

An error is thrown if the number of crossings is unexpected.

**Examples**

To get 3dB bandwidth use:

```
# if `signal` is in dB:
bandwidth(signal, ymax(signal) - 3, band=:lowpass)
# if `signal` is in linear units:
bandwidth(signal, ymax(signal)/2, band=:lowpass)
```

`CedarWaves.basedomain`

— Method`basedomain(signal)`

Returns the base domain of a signal.

`CedarWaves.bitpattern`

— Method`bitpattern(digital_input; tbit, trise, tfall=trise, tdelay=0, lo=0, hi)`

Returns a PWL signal representing a bit pattern of `digital_input`

vector of bools.

Arguments:

`digital_input`

: vector of bools repersenting the sequence of bits`tbit`

: time between bits/pulses`trise`

: rise time of a pulse`tfall`

: fall time of a pulse (default is`trise`

)`tdelay`

: delay before the first bit`lo`

: value of the low state (default is 0)`hi`

: value of the high state

**Examples**

```
const n = 1e-9
s = bitpattern([false,true,false,true,true], tbit=10n, trise=1n, tfall=3n, tdelay=1n, lo=0, hi=1.2)
```

`CedarWaves.clip`

— Function```
clip(signal, from..to)
clip(signal)
```

Return a signal that is a window onto the original `signal`

between the `from`

and `to`

x-axis points. This function is very fast as no copies are made of the original signal. Successive clips can be used as a sliding window as long as the limits stay within the domain of the original signal. To unclip a signal back to the full domain use `clip(signal)`

without any bounds.

**Examples**

```
julia> pwl = PWL(0.0:3, [0.0, 1, -1, 0]);
julia> s1 = clip(pwl, 0.2 .. 2.5);
julia> s1(0.2)
0.2
julia> s1(2.5)
-0.5
julia> s1(2.8)
ERROR: DomainError with 2.8:
not in its clipped interval of [0.2 .. 2.5]
julia> series = Series(-10:10, sin);
julia> s2 = clip(series, -5 .. 5);
julia> s2(0)
0.0
julia> s2(8)
ERROR: DomainError with 8:
not in its clipped discrete interval of [-5.0 .. 5.0]
```

To unclip a signal back to the parent domain use `clip`

without any arguments:

```
julia> s2b = clip(s2);
julia> s2b(8)
0.9893582466233818
```

`CedarWaves.clipcrosses`

— Method`clipcrosses(signal, yth; options...)`

Clip a signal to the first and last crossing of `yth`

.

`CedarWaves.closest_index`

— Method`closest_index(vec, x)`

Returns the index of the closest element of vector `v`

to `x`

"

**Examples**

```
julia> closest_index(-5:5, -0.4)
6
```

`CedarWaves.convolution`

— Method`convolution(signal1, signal2)`

Returns the convolution of the two signals. Both signals are zero padded beyond their domains so they do not throw domain errors durring the convolution operation. See also `impulse`

.

**Examples**

```
julia> s = convolution(PWL(-1:1, [0,1,0]), PWL(-1:1, [0,1,0]));
julia> s(0) ≈ 2/3
true
```

Calculate the response of an RC circuit given the impulse response:

```
julia> R, C = 2000, 3e-6; # RC circuit
julia> τ = R*C
0.006
julia> t = PWL([0, 5τ], [0, 5τ]);
julia> hs = 1/τ * exp(-t/τ); # impulse response
julia> square_wave_input = PWL([0, τ], [1, 1]);
julia> yt = convolution(square_wave_input, hs);
julia> isapprox(yt(τ), 1 - exp(-1), atol=0.0001)
true
```

`CedarWaves.cross`

— Method`cross(s, yth; N=1, options...)`

Returns the Nth crossing (x-value) of a signal.

`CedarWaves.crosscorrelation`

— Method`crosscorrelation(sig1, sig2)`

Computes the cross-correlation of two signals.

**Examples**

```
julia> s1 = PWL([2, 3, 4], [0, 2, 4]);
julia> s2 = PWL([3, 4, 5], [6, 3, 0]);
julia> corr = crosscorrelation(s1, s2);
julia> (xmin(corr), xmax(corr)) == (-1, 3)
true
julia> corr.(xmin(corr):xmax(corr)) ≈ [0, 1, 8, 13, 0]
true
```

`CedarWaves.crosses`

— Method```
crosses(signal, yth; limit=Inf, trace=true, options...)
crosses(signal; yth, limit=Inf, trace=true, options...)
```

Return all crosses of `yth`

as a vector of x-values, up to a limit of `limit`

values.

See also `cross`

, `eachcross`

, Thresholds, and `pct`

.

**Examples**

To find the x-values for all the times the y-value crosses 0.5:

```
julia> crosses(PWL(0:3, [0, 1, 0, 1]), 0.5)
3-element Vector{CrossMeasure}:
0.5
1.5
2.5
```

To find the x-values for all the times the y-value rises above 50% of full swing:

```
julia> crosses(PWL(0:3, [0, 1, 0, 1]), rising(50pct))
3-element Vector{CrossMeasure}:
0.5
2.5
```

`CedarWaves.dB10`

— Function```
dB10(x)
dB10(signal)
```

Returns `10*log10(x)`

. For a signal it operates on the y-values. If the value is complex then `abs(x)`

is used. Typically used to convert a value in watts to dB.

**Examples**

```
julia> dB10(100)
20.0
julia> s = dB10(PWL([1, 10], [1, 10]));
julia> s(2)
3.010299956639812
julia> s(4)
6.020599913279624
julia> s(10)
10.0
```

`CedarWaves.dB20`

— Function```
dB20(x)
dB20(signal)
```

Returns `20*log10(x)`

. For a signal it operates on the y-values. If the value is complex then `abs(x)`

is used. Typically used to convert a signal in volts to dB.

**Examples**

```
julia> dB20(100)
40.0
julia> s = dB20(PWL([1, 10], [1, 10]));
julia> s(2)
6.020599913279624
julia> s(10)
20.0
```

`CedarWaves.dBm`

— Function```
dBm(x)
dBm(signal)
```

Returns `10*log10(x)+30`

. For signals it operates on the y-values. If the value is complex then `abs(x)`

is used. Typically used to convert to watts to decibel relative to 1 mW.

```
julia> dBm(100)
50.0
julia> dBm(PWL(1:10, 1:10));
julia> dBm(1)
30.0
julia> dBm(10)
40.0
```

`CedarWaves.delay`

— Method`delay(; signal1, yth1, signal2=signal, yth2=yth1, N1=1, N2=1, name="delay", sigdigits=4)`

Returns a delay measurement of a signal, `signal`

.

**Options**

`signal1`

: the signal to measure the first crossing`signal2`

: the signal to measure the second crossing (defaults to`signal`

)`yth1`

: the y-value at which to look for the first crossing.`yth2`

: the y-value at which to look for the second crossing (default`yth1`

).`N1`

: the number of edge crossings to find the first crossing (default`1`

).`N2`

: the number of edge crossings to find the second crossing (default`1`

). This is relative to the first crossing.`name`

: the name of the measure`sigdigits`

: the number of sigdigits to display

The delay measurement is an object containing the plot of the delay as well as attributes for measurements related to delay, such as:

`name`

: the name of the measurement`value`

: the value of the measurement`sigdigits`

: the number of sigdigits to display`signal1`

: the first signal that was measured`signal2`

: the second signal that was measured`x1`

: the first crossing (x-value) at yth1`y1`

: the first crossing (y-value) is yth1`x2`

: the second crossing (x-value) at yth2`y2`

: the second crossing (y-value) is yth2`dx`

: the transition time (`x2 - x1`

)`dy`

: the vertical change (`y2 - y1`

)`slope`

: the slew rate (`dy/dx`

)

The properties can be accessed as properties like `meas.dx`

to get the transition time.

**Examples**

```
t = 0:0.005:1
freq = 2
y = @. 0.5*(1 + sin(2pi*freq*t) + 1/3*sin(2pi*freq*3t) + 1/5*sin(2pi*freq*5t));
s1 = PWL(t, y)
s2 = 1 - s1
meas = delay(signal1=s1, signal2=s2, yth1=0.5)
meas.dy
```

In addition the risetime measure object returned acts as its value when used in a mathematical expression:

`meas/2`

`CedarWaves.derivative`

— Method`derivative(signal)`

Returns the derivative of continuous signal, `signal`

.

```
julia> s1 = derivative(PWL(0:3, [0, -2, -1, -1]));
julia> s1(0)
-2.0
julia> s1(0.5)
-2.0
julia> s1(1.5)
1.0
julia> s1(2.5)
0.0
```

`CedarWaves.domain`

— Method`domain(signal)`

Returns the domain of a signal. This can be used to check if an x-value is a valid value. Otherwise a DomainError will be thrown.

```
julia> s = PWL(0:3, 10:13);
julia> 0 in domain(s)
true
julia> 5 in domain(s)
false
julia> s2 = Series(-10:10, sin);
julia> 0 in domain(s2)
true
julia> 0.5 in domain(s2)
false
```

`CedarWaves.domains`

— Function```
domains(sampled_signal)
domains(function_signal, n=100)
```

Return an iterator of the domains of a signal. If a signal is sampled then domains over each pair of samples is returned, otherwise 100 domains are returned by default.

`CedarWaves.dutycycle`

— Method`dutycycle(signal, yth)`

Returns the duty cycle of `signal`

with a threshold `yth`

, in other words, the percentage of time `signal`

is above `yth`

.

```
julia> tri = PWL(1:3, [-1, 1, -1]);
julia> dutycycle(tri, 0)
0.5
julia> dutycycle(tri, 0.5)
0.25
julia> dutycycle(tri, -0.5)
0.75
```

`CedarWaves.dutycycles`

— Method`dutycycles(signal, yth, window)`

Computes `dutycycle`

over a sliding window.

```
julia> t = PWL(0:0.001:1, 0:0.001:1);
julia> s = (sinpi(100*t)+sinpi(4*t));
julia> extrema(dutycycles(s, 0, 0.1))
(0.10256410256410278, 0.8974358974358968)
```

`CedarWaves.eachcross`

— Method`eachcross(s, yth; trace=true, options...)`

Returns the crossings (x-values) of a signal.

`CedarWaves.eachx`

— Method`eachx(signal, [dx])`

Returns an iterator over the sampled x-values of a signal (continuous or discrete). Or the x values spaces at `dx`

intervals.

If you want a vector for indexing operations use `collect(eachx(s))`

or `xvals(s)`

– although this is much less memory efficient in most cases.

**Examples**

```
julia> s = PWL(1e-9 * [0, 0.05, 0.95, 1.0], [0, 1, 1, 0]);
julia> s2 = xscale(s, 1e9); # convert to ns
julia> xs = collect(eachx(s2))
4-element Vector{Float64}:
0.0
0.05
0.95
1.0
```

`CedarWaves.eachxy`

— Method`eachxy(signal, [dx])`

Returns an iterator over the sampled x- and y-values pairs of a signal (continuous or discrete). Or the xy pairs sampled at `dx`

intervals

If you want a vector for indexing operations use `collect(eachxy(s))`

– although this is much less memory efficient in most cases.

**Examples**

```
s = PWL([0, 0.05, 0.95, 1.0], [0, 1, 1, 0]);
for (x, y) in eachxy(s)
# Do something with each x and y
end
```

`CedarWaves.eachy`

— Method`eachy(signal, [dx])`

Returns an iterator over the sampled y-values of a signal (continuous or discrete). Or the y values sampled at `dx`

intervals

If you want a vector for indexing operations use `collect(eachy(s))`

or `yvals(s)`

– although this is much less memory efficient in most cases.

**Examples**

```
julia> s = PWL(1e-9 * [0, 0.05, 0.95, 1.0], [0, 1, 1, 0]);
julia> ys = collect(eachy(s))
4-element Vector{Float64}:
0.0
1.0
1.0
0.0
```

`CedarWaves.extrapolate`

— Method`extrapolate(signal, from..to)`

Converts an extrapolated signal (periodic, zero padded) to a finite signal.

Extrapolated signals are infinite, but only have a finite set of actual data that is for example padded or repeated. To work correctly, most measurements on infinite signals only consider this finite set of base data. This way you can for example find the RMS of an infinite periodic signal.

However, clipping an extrapolated signal can lead to unexpected results. You might for example expect measurements to consider the whole clipped signal. Or the base samples of the signal may lay entirely outside the clipped domain. Or a periodic signal might not actually be periodic anymore.

So instead of clipping the signal, `extrapolate`

turns an infinite signal into a finite one, with samples throughout. This leads to measurements treating the signal as any other finite signal. For example, the RMS of a zero-padded signal will now include the finite padding. And all the crossings of a periodic signal in the interval will be detected.

**Examples**

```
julia> s = Periodic(PWL(1:3, [0, 1, 0]));
julia> crosses(s, 0.5)
2-element Vector{CrossMeasure}:
1.5
2.5
julia> crosses(extrapolate(s, 3..7), 0.5)
4-element Vector{CrossMeasure}:
3.5
4.5
5.5
6.5
```

`CedarWaves.falltime`

— Method`falltime(signal, yth1, yth2; name="falltime", options...)`

Returns a falltime measurement of a signal, `signal`

, from falling threshold `yth1`

to `yth2`

.

**Options**

`name`

: the name of the measure`sigdigits`

: the number of sigdigits to display (default 5)`trace`

: if true will keep signals used for the measurement for debugging

**Examples**

```
t = 0:0.005:1
freq = 2
y = @. 0.5*(1 + sin(2pi*freq*t) + 1/3*sin(2pi*freq*3t) + 1/5*sin(2pi*freq*5t));
s = PWL(t, y)
meas = falltime(s, 0.8, 0.2)
meas.dy
```

In addition the falltime measure object returned acts as its value when used in a mathematical expression:

`meas/2`

`CedarWaves.find_min_itr`

— Function`find_min_itr(xy_pair_iterator, func=+)`

Returns the `(miny, minx)`

tuple of the mimium of func(y) over the xy pair iterator. `func`

is used to apply a transformation to the y values. For example `func=-`

will find the maximum while `+`

(default) finds the minimum.

Note: this function only iterates over samples (does not do interpolation like `optimize_min_point`

).

**Examples**

```
julia> s = PWL(0:2, [0.5, 1, 0.0]);
julia> CedarWaves.find_min_itr(eachxy(s), +)
(0.0, 2.0)
julia> CedarWaves.find_min_itr(eachxy(s), -)
(1.0, 1.0)
```

See also `optimize_min_point`

.

`CedarWaves.firfilter`

— Functionfirfilter(ftype, span, window=hanning)

A filter design method based on windowed sinc functions.

`ftype`

can be a `Lowpass`

, `Highpass`

, `Bandpass`

, or `Bandstop`

`span`

is the truncated length of the filter `window`

is the windowing function that is applied, defaults to hanning.

To filter a signal, use `convolution(s, flt)`

To see the frequency response of the filter, use `FT(flt; clip=fmin..fmax)`

`CedarWaves.flip`

— Method`flip(signal)`

Flips a signal along the x-axis, so a signal whose domain is `a .. b`

is transformed to return the original signal's values along `b .. a`

.

`CedarWaves.freq2k`

— Method`CedarWaves.frequency`

— Method`frequency(signal, yth; name="frequency", options...)`

Returns the two-point frequency of a signal, measured at the first two crossings by `signal`

of `yth`

.

**Examples**

```
t = 0:0.005:1
freq = 2
y = @. 0.5*(1 + sin(2pi*freq*t) + 1/3*sin(2pi*freq*3t) + 1/5*sin(2pi*freq*5t));
s = PWL(t, y)
yth = 0.5
meas = frequency(s, yth)
meas_rising = frequency(s, rising(yth))
meas.value, meas_rising.value
```

`CedarWaves.gaussian`

— Methodgaussian(σ)

A gaussian windowing function over the domain -0.5..0.5

`CedarWaves.iDFT`

— Method`iDFT(series[; mode=real])`

Returns an inverse Discrete Fourier Transform function of a discrete frequency-domain series, `series`

, according to the formula:

\[\big(\mathrm{iDFT}(S)\big)(x) = s(x) = \sum_{n=0}^{N-1} S(\mathit{freq}) \exp\left(j 2\pi \mathit{freq}\, n \,T_\mathit{step}\right)\]

```
julia> idft = iDFT(signal, 0 .. 1e-9, mode=real);
julia> idft(0) # time zero value
0.5
julia> plot(idft) # plot the result
```

**Arguments**

`mode`

can be one`real`

or`complex`

. The default is`real`

which returns the time domain signal as real numbers.

`CedarWaves.iDTFT`

— Method`iDFT(signal, [mode, integral_options...])`

This is not yet implemented.

Return a `Signal`

which is the Inverse Discrete Time Fourier Transform function of a discrete signal, `signal`

.

`CedarWaves.iFS`

— Method`iFS(series, time_interval[; mode, integral_options...])`

Returns a Inverse Fourier Series function of a discrete frequency-domain series, `series`

, according to the formula:

\[\big(\mathrm{iFS}(S)\big)(x) = s(x) = \sum_{\mathit{freq}=-\infty}^{+\infty} S(\mathit{freq}) \exp\left(j 2\pi \mathit{freq}\, x\right)\]

where `freq`

is a multiple of `k*Fmin`

and `k = ... -2, -1, 0, 1, 2, ...`

.

```
julia> fs = iFS(signal, 0 .. 1e-9);
julia> fs(0) # DC value
0.5 + 0.0im
julia> plot(fs) # plot the result
```

**Arguments**

`mode`

can be one`real`

or`complex`

. The default is`real`

which returns the time domain signal as real numbers.`integral_options`

are options that can be passed to`integral`

.

Inifinite extent signals cannot be computed in finite time so ensure to clip the frequency domain signal to be finite.

`CedarWaves.iFT`

— Method`iFT(signal, [clip, mode, integral_options...])`

Return a `Signal`

which is the Inverse Fourier Transform function of a continuous signal, `signal`

, according to the formula:

\[\big(\mathrm{iFT}(S)\big)(x) = s(x) = \frac{1}{2\pi}\int_{-\infty}^{+\infty} S(\mathit{freq}) \exp(j 2\pi \mathit{freq}\, x) \,\mathrm{d}\mathit{freq}\]

The Inverse Fourier Transform is for aperiodic signals. To get the value of the Inverse Fourier Transform call the transform with the frequency of interest:

```
julia> ift = iFT(signal);
julia> ift(0, mode=real) # at time zero
0.5
julia> plot(ift) # plot the result
```

**Options**

`clip`

is an interval of the Inverse Fourier Transform result. By default it is ±10 times`1/xspan(signal)`

. The Inverse Fourier Transnform itself goes from -Inf..Inf and the time domain can be changed with clipping the result again`clip(FT(signal), 0 .. 0.001)`

(which is equivalent to`iFT(signal, clip=0 .. 0.001)`

). Infinite domains are not returned by default because they cannot be plotted.`mode`

can be one`real`

or`complex`

. The default is`real`

which returns the time domain signal as real numbers.`integral_options`

are options that can be passed to`integral`

.

`CedarWaves.impulse`

— Method`impulse(width)`

Returns a signal representing a finite impulse with a triangle of `PWL([-width, 0, width], [0, 1/width, 0])`

. The intergral of the impulse is `1`

.

**Examples**

```
julia> s = impulse(1e-12);
julia> integral(s)
1.0
```

See also `convolution`

.

`CedarWaves.inspect`

— Function`inspect(x)`

Inspect the object, such as a measurement, to show more information (for debugging).

`CedarWaves.integral`

— Function```
integral(signal, [domain; options...])
integral(function, domain; [options...])
```

Returns the integral (via numerical integration) of a continuous function or signal over its domain, according to the formula:

\[\mathrm{integral}(s)=\int_{\mathrm{xmin}(s)}^{\mathrm{xmax}(s)} s(x)\,\mathrm{d}x\]

\[\mathrm{integral}\big(s, (a,b)\big)=\int_{a}^{b} s(x)\,\mathrm{d}x\]

For signals if no domain is provided then it will use the domain of the signal.

**Options**

The following keyword options are supported:

`rtol`

: relative error tolerance (defaults to`sqrt(eps)`

in the precision of the endpoints.`atol`

: absolute error tolerance (defaults to`1e-12`

). Note that for small currents it's recommended to use`0`

.`maxevals`

: maximum number of function evaluations (defaults to`10^7`

)`order`

: order of the integration rule (defaults to`7`

).`error_value`

: whether to return the estimated upper bound of the absolute error (default to`false`

). If`true`

the value will returned as the number with the error bound like`(3.2, 0.0001)`

.

**Examples**

```
julia> integral(PWL(0:2, [1,0,1]))
1.0
julia> integral(x->exp(-x), 0..Inf)
1.0
julia> integral(sin, 0 .. 1000pi, error_value=true) |> vals -> round.(vals, sigdigits=5)
(-7.2429e-14, 9.7044e-13)
```

See also `sum`

.

`CedarWaves.is_clipped`

— Method`is_clipped(s)`

Returns `true`

if signal has been clipped.

`CedarWaves.iscontinuous`

— Function`iscontinuous(signal)`

Returns true if a signal has a continuous (not discrete) domain.

**Examples**

```
julia> iscontinuous(PWL(0:1, 0:1))
true
julia> iscontinuous(PWC(0:1, 0:1))
true
julia> iscontinuous(Series(0:1, 0:1))
false
```

See also `isdiscrete`

, `signal_kind`

.

`CedarWaves.isdiscrete`

— Function`isdiscrete(signal)`

Returns true if a signal has a discrete (not continuous) domain.

**Examples**

```
julia> isdiscrete(PWL(0:1, 0:1))
false
julia> isdiscrete(PWC(0:1, 0:1))
false
julia> isdiscrete(Series(0:1, 0:1))
true
```

See also `iscontinuous`

, `issampled`

, `signal_kind`

.

`CedarWaves.isperiodic`

— Function`isperiodic(signal)`

Returns true if the signal is periodic.

See also `iscontinuous`

, `isdiscrete`

. `issampled`

.

`CedarWaves.issampled`

— Function`issampled(signal)`

Returns true if the signal is from sampled data (e.g. not a pure function).

**Examples**

```
julia> issampled(PWCubic(0:2, [0,1,0]))
true
julia> issampled(ContinuousFunction(exp))
false
```

See also `iscontinuous`

, `isdiscrete`

.

`CedarWaves.kaiser`

— Methodkaiser(α)

A kaiser windowing function over the domain -0.5..0.5

`CedarWaves.logspace`

— Method`logspace(start, stop; length)`

Returns logarithmically spaced values with `length`

points from `start`

to `stop`

.

**Examples**

```
julia> logspace(0.1, 1000, length=5)
5-element Vector{Float64}:
0.1
1.0
10.0
100.0
1000.0
```

`CedarWaves.new_online`

— Method`new_online(sf::OnlineSignalFactory)`

Create a new online signal from an `OnlineSignalFactory`

. Functions on this signal block until samples are pushed to the factory.

See `OnlineSignalFactory`

for more about online signals. See `postprocess`

for making a non-blocking signal from an `OnlineSignalFactory`

.

`CedarWaves.new_signal`

— Method`new_signal(signal; kwargs...)`

Creates a signal with modifications to signal `signal`

with the fields modified as keyword arguments, `kwargs`

. ```

`CedarWaves.optimize_min_point`

— Function`optimize_min_point(signal, func)`

Finds the global mimimum of `func ∘ signal`

and return `(signal(minx), minx)`

. For continuous signals the mimimum could be between samples and a global optimizer is used with the best sample as the starting point. For periodic signals only the base domain is considered. The optimization method does not guarantee to find the global optimum.

**Examples**

```
julia> s = PWL(0:2, [0.5, 1, 0.0]);
julia> CedarWaves.optimize_min_point(s, +)
(0.0, 2.0)
julia> CedarWaves.optimize_min_point(s, -)
(1.0, 1.0)
```

See also `find_min_itr`

.

`CedarWaves.pairup_conjugates!`

— MethodReorder the vector x of complex numbers so that complex conjugates come after each other, with the one with positive imaginary part first. Returns true if the conjugates can be paired and otherwise false.

`CedarWaves.peak2peak`

— Method`peak2peak(signal)`

Faster version of `ymax(sig) - ymin(sig)`

. See also `extrema`

.

**Examples**

```
julia> peak2peak(PWL(0:3, [0,1,-1,1]))
2.0
```

See also `xmin`

, `xmax`

, `xspan`

, `ymin`

, `ymax`

, `minimum`

, `maximum`

, `extrema`

.

`CedarWaves.phase`

— Method```
phase(real)
phase(complex)
phase(signal)
```

Returns the phase of a complex number or signal in radians. Alias for `angle`

.

Since `pi`

is an approximate number it is better for accuracy to work in degrees, see `phased`

.

**Examples**

```
julia> phase(pi)
0.0
julia> s = phase(PWL(0:1, [1, im]));
julia> s(0.5) ≈ 2pi/8
true
```

See also `abs`

, `real`

, `imag`

, `conj`

, `phased`

, `angle`

, `rad2deg`

, `deg2rad`

.

`CedarWaves.phased`

— Function```
phased(real)
phased(complex)
phased(signal)
```

Returns the phase of a complex number or signal in degrees.

**Examples**

```
julia> phased(1)
0.0
julia> phased(im)
90.0
julia> s = phased(PWL(0:1, [1, im]));
julia> s(0.5)
45.0
```

See also `abs`

, `real`

, `imag`

, `conj`

, `phase`

, `angle`

, `rad2deg`

, `deg2rad`

.

`CedarWaves.postprocess`

— Method`postprocess(sf::OnlineSignalFactory)`

Create a plain old signal from an `OnlineSignalFactory`

. This signal can be used with any function, but only contains the samples currently in the buffer.

See `OnlineSignalFactory`

for more about online signals. See `new_online`

for making an online signal from an `OnlineSignalFactory`

.

`CedarWaves.risetime`

— Method`risetime(signal, yth1, yth2; options...)`

Returns a risetime measurement of a signal, `signal`

, from rising threshold `yth1`

to `yth2`

.

**Options**

`name`

: the name of the measure`sigdigits`

: the number of sigdigits to display (default 5)`trace`

: if true will keep signals used for the measurement for debugging

**Examples**

```
t = 0:0.005:1
freq = 2
y = @. 0.5*(1 + sin(2pi*freq*t) + 1/3*sin(2pi*freq*3t) + 1/5*sin(2pi*freq*5t));
s = PWL(t, y)
meas = risetime(s, 0.2, 0.8)
meas.dy
```

In addition the risetime measure object returned acts as its value when used in a mathematical expression:

`meas/2`

`CedarWaves.rms`

— Method`rms(signal; name="rms", options...)`

Returns `sqrt(mean(signal^2))`

, the root-mean-squared value of a signal. The `mean`

value changes depending on if the signal is discrete or continuous.

**Examples**

```
julia> rms(PWL(0:2, [-1,0,1])) ≈ 1/sqrt(3)
true
julia> rms(Series(0:2, [-1,0,1])) ≈ sqrt(2/3)
true
```

`CedarWaves.signal_kind`

— Method`signal_kind(signal)`

Returns the if the signal is a continuous (`ContinuousKind`

) or discrete (`DiscreteKind`

) kind.

**Examples**

```
julia> signal_kind(PWL(0:1, 0:1))
ContinuousSignal
julia> signal_kind(PWC(0:1, 0:1))
ContinuousSignal
julia> signal_kind(Series(0:1, 0:1))
DiscreteSignal
```

See also `iscontinuous`

, `isdiscrete`

.

`CedarWaves.slewrate`

— Method`slewrate(signal, yth1, yth2, name="slewrate", options...)`

Returns a slewrate measurement of a signal, `signal`

.

**Options**

`name`

: the name of the measure`sigdigits`

: the number of sigdigits to display

**Examples**

```
t = 0:0.005:1
freq = 2
y = @. 0.5*(1 + sin(2pi*freq*t) + 1/3*sin(2pi*freq*3t) + 1/5*sin(2pi*freq*5t));
s = PWL(t, y)
meas = slewrate(s, 0.8, 0.2)
meas.dy/meas.dx
```

In addition the slewrate measure object returned acts as its value when used in a mathematical expression:

`meas/2`

`CedarWaves.toplot`

— Method`toplot(signal[; pixels])`

Returns an x- and y-vector of points that are suitable for plotting. The number of pixels to display can be passed as a keyword argument.

**Examples**

```
using Plots
t = PWL(0 .. 2pi, 0 .. 2pi)
s = sin(t)
x, y = toplot(s)
plot(x, y)
```

`CedarWaves.window`

— Functionwindow(s, w)

Apply window `w`

to signal `s`

.

`CedarWaves.xmax`

— Method`xmax(signal)`

Returns the maximum x-value of a signal.

**Examples**

```
julia> xmax(PWL(0:3, [0,1,0,1]))
3.0
```

See also `xmin`

, `xspan`

, `ymin`

, `ymax`

, `minimum`

, `maximum`

, `extrema`

, `peak2peak`

.

`CedarWaves.xmin`

— Method`xmin(signal)`

Returns the minimum x-value of a signal.

**Examples**

```
julia> xmin(PWC(0:2, rand(3)))
0.0
```

See also `xmax`

, `xspan`

, `ymin`

, `ymax`

, `minimum`

, `maximum`

, `extrema`

, `peak2peak`

.

`CedarWaves.xscale`

— Method`xscale(signal, value)`

Returns a new signal with the x-axis of `signal`

scaled by `value`

. See also `xshift`

.

```
julia> s1 = PWL([0, 1e-9, 2e-9], [1,2,3]);
julia> s1(0.5e-9)
1.5
julia> s2 = xscale(s1, 1e9); # to ns
julia> s2(0.5) # in ns
1.5
```

`CedarWaves.xshift`

— Method`xshift(signal, value)`

Returns a new signal with the x-axis of `signal`

shifted by `value`

. Positive is a right shift while negative shifts left.

```
julia> s1 = xshift(PWL(0:2, [1,2,3]), 3);
julia> s1(3)
1.0
julia> s1(5)
3.0
```

`CedarWaves.xspan`

— Method`xspan(signal)`

Returns the domain of a signal: `xmax(s) - xmin(s)`

.

**Examples**

```
julia> xspan(PWL(0:10, rand(11)))
10.0
julia> xspan(Series(-2:2, rand(5)))
4.0
```

See also `xmin`

, `xmax`

, `ymin`

, `ymax`

, `minimum`

, `maximum`

, `extrema`

, `peak2peak`

, `clip`

.

`CedarWaves.xtype`

— Method`xtype(signal)`

Returns the type of the x-values element type.

**Examples**

```
julia> dig = PWC(0:3, [false, true, true, false]);
julia> xtype(dig)
Float64
```

Note the `xtype`

for a continuous signal is a Float64 (not an Int64).

`CedarWaves.xvals`

— Method`xvals(signal, [dx])`

Returns an vector of the sampled x-values of a signal (continuous or discrete). Or the x values spaces at `dx`

intervals

If the full vector isn't needed in the end it may be faster to iterate over the x-values one-by-one with `eachx`

.

**Examples**

```
julia> s = PWL(1e-9 * [0, 0.05, 0.95, 1.0], [0, 1, 1, 0]);
julia> s2 = xscale(s, 1e9); # convert to ns
julia> xs = xvals(s2)
4-element Vector{Float64}:
0.0
0.05
0.95
1.0
```

`CedarWaves.ymap_signal`

— Method`ymap_signal(func, signal)`

Creates a new signal by applying the function `func`

to each y-value of `signal`

. The `func`

takes a single y-value and returns a modified y-value.

Ensure `func`

does not use `signal.full_transform`

because it is already applied by `ymap_signal`

.

```
julia> double(s::Signal) = ymap_signal(y->2y, s)
double (generic function with 1 method)
julia> s = double(PWL(0:1, 1:2));
julia> s(0.5)
3.0
```

`CedarWaves.ymax`

— Method`ymax(signal)`

Returns the maximum y-value of a signal. Alias of `maximum`

.

See also `ymin`

.

**Examples**

```
julia> ymax(PWL(0:3, [0,1,0,1]))
1.0
```

See also `xmin`

, `xmax`

, `xspan`

, `ymin`

, `minimum`

, `maximum`

, `extrema`

, `peak2peak`

.

`CedarWaves.ymin`

— Method`ymin(signal)`

Returns the minimum y-value of a signal. Alias of `minimum`

.

See also `ymax`

.

**Examples**

```
julia> ymin(PWL(0:3, [0,1,0,1]))
0.0
```

See also `xmin`

, `xmax`

, `xspan`

, `ymax`

, `minimum`

, `maximum`

, `extrema`

, `peak2peak`

.

`CedarWaves.ytype`

— Function`ytype(signal)`

Returns the type of the y-values element type.

**Examples**

```
julia> dig = PWC(0:3, [false, true, true, false]);
julia> ytype(dig)
Bool
```

Note the `xtype`

for a continuous signal is a Float64 (not an Int64).

`CedarWaves.yvals`

— Method`yvals(signal, [dx])`

Returns an vector of the sampled y-values of a signal (continuous or discrete). Or the y values sampled at `dx`

intervals

If the full vector isn't needed in the end it may be faster to iterate over the y-values one-by-one with `eachy`

.

**Examples**

```
julia> s = PWL(1e-9 * [0, 0.05, 0.95, 1.0], [0, 1, 1, 0]);
julia> ys = yvals(s)
4-element Vector{Float64}:
0.0
1.0
1.0
0.0
```

`Statistics.mean`

— Function`mean(signal)`

Calculate the mean value of a signal. For continuous signals the formula is:

\[\mathrm{mean}(s)=\frac{1}{\mathrm{xspan}(s)} \int_{\mathrm{xmin}(s)}^{\mathrm{xmax}(s)} s(x)\,\mathrm{d}x\]

For discrete signals with `N`

elements the formula is:

\[\mathrm{mean}(s) = \frac{1}{N} \sum_{n=\mathrm{xmin}(s)}^{\mathrm{xmax}(s)} s[n]\]

**Examples**

```
julia> mean(PWL(0:2, [0,12,0]))
6.0
julia> mean(Series(0:2, [0,12,0]))
4.0
julia> mean(PWL(0:2, [1,0,1])) ≈ 0.5
true
julia> mean(Series(0:2, [1,0,1])) == 2/3
true
```

`Statistics.std`

— Function`std(signal; <keyword arguments>)`

Returns the standard deviation of a signal. For continuous signals the formula is:

\[\mathrm{std}(s) = \sqrt{\frac{1}{\mathrm{xspan}(s)}\int_{\mathrm{xmin}(s)}^{\mathrm{xmax}(s)} \big(s(x) - \mathrm{mean}(s)\big)^2\,\mathrm{d}x}\]

for discrete signals:

\[\mathrm{std}(s) = \sqrt{\frac{1}{\mathrm{xspan}(s)} \sum_{n=\mathrm{xmin}(s)}^{\mathrm{xmax}(s)} \big(s[n] - \mathrm{mean}(s)\big)^2}\]

**Arguments**

`mean`

: the pre-computed mean of the signal (optional).`corrected`

: if`true`

(default) then it is scaled by`n-1`

, otherwise by`n`

(for discrete signals only).

**Examples**

```
julia> std(Series(0:2, [0, -1, 0])) == std([0, -1, 0])
true
julia> std(Series(0:2, [1, -2, 1]), corrected=false) == rms(Series(0:2, [1, -2, 1])) # std == rms when mean is zero
true
julia> std(PWL(0:1, [-1, 1])) ≈ 1/sqrt(3)
true
```