Investment Studio > Expressions > Functions > DSP > RESONATE

Short form: float array[*][data_columns] resonate(float array[1][4] filter_parameters, float amplification, float array[*][data_columns] data)

Returns the data array, with all columns passed through the resonant filter specified by the filter_parameters and multiplied by the amplification factor. Each data column is filtered separately.

Long form: (float array[1][4] filter_parameters, float amplification, float array[*][data_columns] data, integer first_column, integer last_column = first_column)

Returns the data array, with columns first_column through last_column passed through the resonant filter specified by the filter_parameters and multiplied by the amplification factor. Each data column is filtered separately.

If last_column is omitted, it defaults to first_column (i.e. only first_column is convolved).

All arguments (including all array elements) are converted to float. If conversion fails, the default value 0.0 is used.

The filter_parameters describe a second order IIR (Infinite Impulse Response) filter implementing the difference equation

y[n] = b0 * x[n] + a1 * y[n - 1] + a2 * y[n - 2]

where x[n] is the input sequence and y[n] is the filter's output. The filter coefficients are listed in the order {b0, b1, a1, a2}. They can be specified manually or created with make_resonator (recommended).

Tip: The frequency response of any linear, time-invariant filter is just the Fourier transform of the filter's impulse response (the filter's output when the input sequence is a unit impulse, i.e. a single 1 surrounded by zeros, effectively all the way both to positive and to negative infinity) so to visualize the filter's frequency response, all you have to do is pass a unit impulse through the filter, apply fftp to the output and plot the result. See make_resonator for examples.

Example

The 100-point column vector

_data = mop("sin()", makevector(100, 0, 4 * PI / 100)) + 0.1 * mop("sin()", makevector(100, 0, 20 * PI / 100))

contains a sine wave with period 50 (normalized frequency 0.5) and unit amplitude, mixed with a much weaker sine wave with period 10 (normalized frequency 0.1) and amplitude 0.1. Plugged into a graph source, the above expression looks like this:

In order to emphasize the weaker wave, we can use a resonant filter centered on its frequency (0.1) and with a peak gain of 10:

=resonate(make_resonator(0.1, 1, 10), 1, array(_data))

Ideally, this should yield the same result as an equal mix of the two input waves:

=mop("sin()", makevector(100, 0, 4 * PI / 100)) + mop("sin()", makevector(100, 0, 20 * PI / 100))

A plot of the resonator output (in blue) and the remixed input waves (in gray) over the actual input (still in black) looks like this:

Once it settles down, the resonator tracks the remixed input waves closely, with a small phase delay (see the example in make_resonator for a phase response plot).

See also hipass, lopass, make_ema, make_notch, make_resonator.