# interpolate

```Vector
```

## SYNTAX

`obj = ysrcdest.interpolate(xdest, xsrc)`
`obj = ydest.interpolate(xdest, xsrc, ysrc)`

## DESCRIPTION

Linearly interpolate points from (xsrc,ysrc) to (xdest,ydest) In the second form, xsrc and ysrc remain unchanged. Destination points outside the domain of xsrc are set to ysrc or ysrc[ysrc.size-1]

## EXAMPLES

execute following example
```//...
objref xs, ys, xd, yd
xs = new Vector(10)
xs.indgen()
ys = xs.c.mul(xs)
ys.line(g, xs, 1, 0) // black reference line

xd = new Vector()

xd.indgen(-.5, 10.5, .1)
yd = ys.c.interpolate(xd, xs)
yd.line(g, xd, 3, 0) // blue more points than reference

xd.indgen(-.5, 13, 3)
yd = ys.c.interpolate(xd, xs)
yd.line(g, xd, 2, 0) // red fewer points than reference
```

# deriv

```Vector
```

## SYNTAX

`obj = vdest.deriv(vsrc)`
`obj = vdest.deriv(vsrc, dx)`
`obj = vdest.deriv(vsrc, dx, method)`
`obj = vsrcdest.deriv()`
`obj = vsrcdest.deriv(dx)`
`obj = vsrcdest.deriv(dx, method)`

## DESCRIPTION

The numerical Euler derivative or the central difference derivative of `vec` is placed in `vdest`. The variable `dx` gives the increment of the independent variable between successive elements of `vec`.
`method` = 1 = Euler derivative:
`vec1[i] = (vec[i+1] - vec[i])/dx`
Each time this method is used, the first element of `vec` is lost since i cannot equal -1. Therefore, since the `integral` function performs an Euler integration, the integral of `vec1` will reproduce `vec` minus the first element.
`method` = 2 = Central difference derivative:
`vec1[i] = ((vec[i+1]-vec[i-1])/2)/dx`
This method produces an Euler derivative for the first and last elements of `vec1`. The central difference method maintains the same number of elements in `vec1` as were in `vec` and is a more accurate method than the Euler method. A vector differentiated by this method cannot, however, be integrated to reproduce the original `vec`.

## EXAMPLES

```objref vec, vec1
vec = new Vector()
vec1 = new Vector()
vec.indgen(0, 5, 1)
func sq(){
return \$1*\$1
}
vec.apply("sq")
vec1.deriv(vec, 0.1)
```
creates `vec1` with elements:
```10	20
40	60
80	90
```
Since `dx`=0.1, and there are eleven elements including 0, the entire function exists between the values of 0 and 1, and the derivative values are large compared to the function values. With `dx`=1,the vector `vec1` would consist of the following elements:
```1	2
4	6
8	9
```

The Euler method vs. the Central difference method:
Beginning with the vector `vec`:

```0	1
4	9
16	25
```
`vec1.deriv(vec, 1, 1)` (Euler) would go about producing `vec1` by the following method:
```1-0   = 1	4-1  = 3
9-4   = 5	16-9 = 7
25-16 = 9
```
whereas `vec1.deriv(vec, 1, 2)` (Central difference) would go about producing `vec1` as such:
```1-0      = 1		(4-0)/2  = 2
(9-1)/2  = 4		(16-4)/2 = 6
(25-9)/2 = 8		25-16    = 9
```

# integral

```Vector
```

## SYNTAX

`obj = vdest.integral(vsrc)`
`obj = vdest.integral(vsrc, dx)`
`obj = vsrcdest.integral()`
`obj = vsrcdest.integral(dx)`

## DESCRIPTION

Places a numerical Euler integral of the vsrc elements in vdest. `dx` sets the size of the discretization.

`vdest[i+1] = vdest[i] + vsrc[i+1]` and the first element of `vdest` is always equal to the first element of `vsrc`.

## EXAMPLES

```objref vec, vec1
vec = new Vector()
vec1 = new Vector()
vec.indgen(0, 5, 1)	//vec will have 6 values from 0 to 5, with increment=1
vec.apply("sq")		//sq() squares an element
//and is defined in the example for .deriv
vec1.integral(vec, 1)	//Euler integral of vec elements approximating
//an x-squared function, dx = 0.1
vec1.printf()
```
will print the following elements in `vec1` to the screen:
```0	1	5
14	30	55
```
In order to make the integral values more accurate, it is necessary to increase the size of the vector and to decrease the size of dx.
```objref vec2
vec2 = new Vector(6)
vec.indgen(0, 5.1, 0.1)	//vec will have 51 values from 0 to 5, with increment=0.1
vec.apply("sq")		//sq() squares an element
//and is defined in the example for .deriv
vec1.integral(vec, 0.1)	//Euler integral of vec elements approximating
//an x-squared function, dx = 0.1
for i=0,5{vec2.x[i] = vec1.x[i*10]}  //put the value of every 10th index in vec2
vec2.printf()
```
will print the following elements in `vec2` (which are the elements of `vec1` corresponding to the integers 0-5) to the screen:
```0	0.385	2.87
9.455	22.14	42.925
```
The integration naturally becomes more accurate as dx is reduced and the size of the vector is increased. If the vector is taken to 501 elements from 0-5 and dx is made to equal 0.01, the integrals of the integers 0-5 yield the following (compared to their continuous values on their right).
```0.00000 -- 0.00000	0.33835 --  0.33333	2.6867  --  2.6666
9.04505 -- 9.00000	21.4134 -- 21.3333	41.7917 -- 41.6666
```

# median

```Vector
```

## SYNTAX

`median = vsrc.median()`

## DESCRIPTION

Find the median value of `vec`.

# medfltr

```Vector
```

## SYNTAX

`obj = vdest.medfltr(vsrc)`
`obj = vdest.medfltr(vsrc, points)`
`obj = vsrcdest.medfltr()`
`obj = vsrcdest.medfltr( points)`

## DESCRIPTION

Apply a median filter to vsrc, producing a smoothed version in vdest. Each point is replaced with the median value of the points on either side. This is typically used for eliminating spikes from data.

# sort

```Vector
```

## SYNTAX

`obj = vsrcdest.sort()`

## DESCRIPTION

Sort the elements of `vec1` in place, putting them in numerical order.

# sortindex

```Vector
```

## SYNTAX

`vdest = vsrc.sortindex()`
`vdest = vsrc.sortindex(vdest)`

## DESCRIPTION

Return a new vector of indices which sort the vsrc elements in numerical order. That is vsrc.index(vsrc.sortindex) is equivalent to vsrc.sort(). If vdest is present, use that as the destination vector for the indices. This, if it is large enough, avoids the destruct/construct of vdest.

## EXAMPLES

execute following example
```objref a, r, si
r = new Random()
r.uniform(0,100)
a = new Vector(10)
a.setrand(r)
a.printf

si = a.sortindex
si.printf
a.index(si).printf
```

# reverse

```Vector
```

## SYNTAX

`obj = vsrcdest.reverse()`

## DESCRIPTION

Reverses the elements of `vec` in place.

# rotate

```Vector
```

## SYNTAX

`obj = vsrcdest.rotate(value)`
`obj = vsrcdest.rotate(value, 0)`

## DESCRIPTION

A negative value will move elements to the left. A positive argument will move elements to the right. In both cases, the elements shifted off one end of the vector will reappear at the other end. If a 2nd arg is present, 0 values get shifted in and elements shifted off one end are lost.

## EXAMPLES

```vec.indgen(1, 10, 1)
vec.rotate(3)
```
orders the elements of `vec` as follows:
```8  9  10  1  2  3  4  5  6  7
```
whereas,
```vec.indgen(1, 10, 1)
vec.rotate(-3)
```
orders the elements of `vec` as follows:
```4  5  6  7  8  9  10  1  2  3
```
execute following example
```objref vec
vec = new Vector()
vec.indgen(1,5,1)
vec.printf
vec.c.rotate(2).printf
vec.c.rotate(2, 0).printf
vec.c.rotate(-2).printf
vec.c.rotate(-2, 0).printf
```

# rebin

```Vector
```

## SYNTAX

`obj = vdest.rebin(vsrc,factor)`
`obj = vsrcdest.rebin(factor)`

## DESCRIPTION

Compresses length of vector `vsrc` by an integer factor. The sum of elements is conserved, unless the factor produces a remainder, in which case the remainder values are truncated from `vdest`.

## EXAMPLES

```vec.indgen(1, 10, 1)
vec1.rebin(vec, 2)
```
produces `vec1`:
```3  7  11  15  19
```
where each pair of `vec ` elements is added together into one element.

But,

```vec.indgen(1, 10, 1)
vec1.rebin(vec, 3)
```
adds trios `vec` elements and gets rid of the value 10, producing `vec1`:
```6  15  24
```

# pow

```Vector
```

## SYNTAX

`obj = vdest.pow(vsrc, power)`
`obj = vsrcdest.pow(power)`

## DESCRIPTION

Raise each element to some power. A power of -1, 0, .5, 1, or 2 are efficient.

# sqrt

```Vector
```

## SYNTAX

`obj = vdest.sqrt(vsrc)`
`obj = vsrcdest.sqrt()`

## DESCRIPTION

Take the square root of each element. No domain checking.

# log

```Vector
```

## SYNTAX

`obj = vdest.log(vsrc)`
`obj = vsrcdest.log()`

## DESCRIPTION

Take the natural log of each element. No domain checking.

# log10

```Vector
```

## SYNTAX

`obj = vdest.log10(vsrc)`
`obj = vsrcdest.log10()`

## DESCRIPTION

Take the logarithm to the base 10 of each element. No domain checking.

# tanh

```Vector
```

## SYNTAX

`obj = vdest.tanh(vsrc)`
`obj = vsrcdest.tanh()`

## DESCRIPTION

Take the hyperbolic tangent of each element.

# abs

```Vector
```

## SYNTAX

`obj = vdest.abs(vsrc)`
`obj = vsrcdest.abs()`

## DESCRIPTION

Take the absolute value of each element.

## EXAMPLES

```objref v1
v1 = new Vector()
v1.indgen(-.5, .5, .1)
v1.printf()
v1.abs.printf()
```

math

# index

```Vector
```

## SYNTAX

`obj = vdest.index(vsrc, indices)`

## DESCRIPTION

The values of the vector `vsrc` indexed by the vector indices are collected into `vdest`.

## EXAMPLES

```objref vec, vec1, vec2, vec3
vec = new Vector()
vec1 = new Vector()
vec2 = new Vector()
vec3 = new Vector(6)
vec.indgen(0, 5.1, 0.1)	//vec will have 51 values from 0 to 5, with increment=0.1
vec1.integral(vec, 0.1)	//Euler integral of vec elements approximating
//an x-squared function, dx = 0.1
vec2.indgen(0, 50,10)
vec3.index(vec1, vec2)  //put the value of every 10th index in vec2
```
makes `vec3` with six elements corresponding to the integrated integers from `vec`.

# min

```Vector
```

## SYNTAX

`x = vec.min()`
`x = vec.min(start, end)`

## DESCRIPTION

Return the minimum value.

# min_ind

```Vector
```

## SYNTAX

`i = vec.min_ind()`
`i = vec.min_ind(start, end)`

## DESCRIPTION

Return the index of the minimum value.

# max

```Vector
```

## SYNTAX

`x = vec.max()`
`x = vec.max(start, end)`

## DESCRIPTION

Return the maximum value.

# max_ind

```Vector
```

## SYNTAX

`i = vec.max_ind()`
`i = vec.max_ind(start, end)`

## DESCRIPTION

Return the index of the maximum value.

# sum

```Vector
```

## SYNTAX

`x = vec.sum()`
`x = vec.sum(start, end)`

## DESCRIPTION

Return the sum of element values.

# sumsq

```Vector
```

## SYNTAX

`x = vec.sumsq()`
`x = vec.sumsq(start, end)`

## DESCRIPTION

Return the sum of squared element values.

# mean

```Vector
```

## SYNTAX

`x = vec.mean()`
`x = vec.mean(start, end)`

## DESCRIPTION

Return the mean of element values.

# var

```Vector
```

## SYNTAX

`x = vec.var()`
`x = vec.var(start, end)`

## DESCRIPTION

Return the variance of element values.

# stdev

```Vector
```

## SYNTAX

`vec.stdev()`
`vec.stdev(start,end)`

## DESCRIPTION

Return the standard deviation of the element values.

# stderr

```Vector
```

## SYNTAX

`x = vec.stderr()`
`x = vec.stderr(start, end)`

## DESCRIPTION

Return the standard error of the mean (SEM) of the element values.

# dot

```Vector
```

## SYNTAX

`x = vec.dot(vec1)`

## DESCRIPTION

Return the dot (inner) product of `vec` and vec1.

# mag

```Vector
```

## SYNTAX

`x = vec.mag()`

## DESCRIPTION

Return the vector length or magnitude.

```Vector
```

## SYNTAX

`obj = vsrcdest.add(scalar)`
`obj = vsrcdest.add(vec1)`

## DESCRIPTION

Add either a scalar to each element of the vector or add the corresponding elements of vec1 to the elements of `vsrcdest`. `vsrcdest` and vec1 must have the same size.

# sub

```Vector
```

## SYNTAX

`obj = vsrcdest.sub(scalar)`
`obj = vsrcdest.sub(vec1)`

## DESCRIPTION

Subtract either a scalar from each element of the vector or subtract the corresponding elements of vec1 from the elements of `vsrcdest`. `vsrcdest` and vec1 must have the same size.

# mul

```Vector
```

## SYNTAX

`obj = vsrcdest.mul(scalar)`
`obj = vsrcdest.mul(vec1)`

## DESCRIPTION

Multiply each element of `vsrcdest` either by either a scalar or the corresponding elements of vec1. `vsrcdest` and vec1 must have the same size.

# div

```Vector
```

## SYNTAX

`obj = vsrcdest.div(scalar)`
`obj = vsrcdest.div(vec1)`

## DESCRIPTION

Divide each element of `vsrcdest` either by a scalar or by the corresponding elements of vec1. `vsrcdest` and vec1 must have the same size.

# scale

```Vector
```

## SYNTAX

`scale = vsrcdest.scale(low, high)`

## DESCRIPTION

Scale values of the elements of a vector to lie within the given range. Return the scale factor used.

# eq

```Vector
```

## SYNTAX

`boolean = vec.eq(vec1)`

## DESCRIPTION

Test equality of vectors. Returns 1 if all elements of vec == corresponding elements of vec1 (to within float_epsilon ). Otherwise it returns 0.

# meansqerr

```Vector
```

## SYNTAX

`x = vec.meansqerr(vec1)`
`x = vec.meansqerr(vec1, weight_vec)`

## DESCRIPTION

Return the mean squared error between values of the elements of `vec` and the corresponding elements of vec1. `vec` and vec1 must have the same size.

If the second vector arg is present, it also must have the same size and the return value is sum of w[i]*(v1[i] - v2[i])^2 / size

# Fourier

```Vector
convlv         fft            spctrm
correl         filter
```
The following routines are based on the fast fourier transform (FFT) and are implemented using code from Numerical Recipes in C (2nd ed.) Refer to this source for further information.

# correl

```Fourier
```

## SYNTAX

`obj = vdest.correl(src)`
`obj = vdest.correl(src, vec2)`

## DESCRIPTION

Compute the cross-correlation function of src and vec2 (or the autocorrelation of src if vec2 is not present).

# convlv

```Fourier
```

## SYNTAX

`obj = vdest.convlv(src,filter)`
`obj = vdest.convlv(src,filter, sign)`

## DESCRIPTION

Compute the convolution of src with filter. If sign = -1 then compute the deconvolution. Assumes filter is given in "wrap-around" order, with countup `t=0..t=n/2` followed by countdown `t=n..t=n/2`. The size of filter should be an odd <= the size of v1>.

## EXAMPLES

execute following example
```objref v1, v2, v3
v1 = new Vector(16)
v2 = new Vector(16)
v3 = new Vector()
v1.x = v1.x = 1
v2.x = v2.x = 3
v3.convlv(v1, v2)
v1.printf()
v2.printf()
v3.printf()
```

# spctrm

```Fourier
```

## SYNTAX

`obj = vdest.spctrm(vsrc)`

## DESCRIPTION

Return the power spectral density function of vsrc.

# filter

```Fourier
```

## SYNTAX

`obj = vdest.filter(src,filter)`
`obj = vsrcdest.filter(filter)`

## DESCRIPTION

Digital filter implemented by taking the inverse fft of filter and convolving it with vec1. vec and vec1 are in the time domain and filter is in the frequency domain.

# fft

```Fourier
```

## SYNTAX

`obj = vdest.fft(vsrc, sign)`
`obj = vsrcdest.fft(sign)`

## DESCRIPTION

Compute the fast fourier transform of the source data vector. If sign=-1 then compute the inverse fft.

If vsrc.size() is not an integral power of 2, it is padded with 0's to the next power of 2 size.

The complex frequency domain is represented in the vector as pairs of numbers --- except for the first two numbers. vec.x is the amplitude of the 0 frequency cosine (constant) and vec.x is the amplitude of the highest (N/2) frequency cosine (ie. alternating 1,-1's in the time domain) vec.x[2, 3] is the amplitude of the cos(2*PI*i/n), sin(2*PI*i/n) components (ie. one whole wave in the time domain) vec.x[n-2, n-1] is the amplitude of the cos(PI*(n-1)*i/n), sin(PI*(n-1)*i/n) components. The following example of a pure time domain sine wave sampled at 16 points should be played with to see where the specified frequency appears in the frequency domain vector (note that if the frequency is greater than 8, aliasing will occur, ie sampling makes it appear as a lower frequency) Also note that the forward transform does not produce the amplitudes of the frequency components that goes up to make the time domain function but instead each element is the integral of the product of the time domain function and a specific pure frequency. Thus the 0 and highest frequency cosine are N times the amplitudes and all others are N/2 times the amplitudes.

```...	//define a gui for this example

N=16	// should be power of 2
c=1	// 0 -> sin   1 -> cos
f=1	// waves per domain, max is N/2
setup_gui() // construct the gui for this example

proc p() {
v1 = new Vector(N)
v1.sin(f, c*PI/2, 1000/N)
v1.plot(g1)

v2 = new Vector()
v2.fft(v1, 1)		// forward
v2.plot(g2)

v3 = new Vector()
v3.fft(v2, -1)		// inverse
v3.plot(g3)		// amplitude N/2 times the original
}

p()
```

The inverse fft is mathematically almost identical to the forward transform but often has a different operational interpretation. In this case the result is a time domain function which is merely the sum of all the pure sinusoids weighted by the (complex) frequency function (although, remember, points 0 and 1 in the frequency domain are special, being the constant and the highest alternating cosine, respectively). The example below shows the index of a particular frequency and phase as well as the time domain pattern. Note that index 1 is for the higest frequency cosine instead of the 0 frequency sin.

Because the frequency domain representation is something only a programmer could love, and because one might wish to plot the real and imaginary frequency spectra, one might wish to encapsulate the fft in a function which uses a more convenient representation.

Below is an alternative FFT function where the frequency values are spectrum amplitudes (no need to divide anything by N) and the real and complex frequency components are stored in separate vectors (of length N/2 + 1).

Consider the functions

## SYNTAX

`FFT(1, vt_src, vfr_dest, vfi_dest)`
`FFT(-1, vt_dest, vfr_src, vfi_src)`

## DESCRIPTION

The forward transform (first arg = 1) requires a time domain source vector with a length of N = 2^n where n is some positive integer. The resultant real (cosine amplitudes) and imaginary (sine amplitudes) frequency components are stored in the N/2 + 1 locations of the vfr_dest and vfi_dest vectors respectively (Note: vfi_dest.x and vfi_dest.x[N/2] are always set to 0. The index i in the frequency domain is the number of full pure sinusoid waves in the time domain. ie. if the time domain has length T then the frequency of the i'th component is i/T.

The inverse transform (first arg = -1) requires two freqency domain source vectors for the cosine and sine amplitudes. The size of these vectors must be N/2+1 where N is a power of 2. The resultant time domain vector will have a size of N.

If the source vectors are not a power of 2, then the vectors are padded with 0's til vtsrc is 2^n or vfr_src is 2^n + 1. The destination vectors are resized if necessary.

This function has the property that the sequence

```FFT(1, vt, vfr, vfi)
FFT(-1, vt, vfr, vfi)
```
leaves vt unchanged. Reversal of the order would leave vfr and vfi unchanged.

The implementation is:
execute following example

```proc FFT() {local n, x
if (\$1 == 1) { // forward
\$o3.fft(\$o2, 1)
n = \$o3.size()
\$o3.div(n/2)
\$o3.x /= 2	// makes the spectrum appear discontinuous
\$o3.x /= 2	// but the amplitudes are intuitive

\$o4.copy(\$o3, 0, 1, -1, 1, 2)   // odd elements
\$o3.copy(\$o3, 0, 0, -1, 1, 2)   // even elements
\$o3.resize(n/2+1)
\$o4.resize(n/2+1)
\$o3.x[n/2] = \$o4.x           //highest cos started in o3.x[1
\$o4.x = \$o4.x[n/2] = 0       // weights for sin(0*i)and sin(PI*i)
}else{ // inverse
// shuffle o3 and o4 into o2
n = \$o3.size()
\$o2.copy(\$o3, 0, 0, n-2, 2, 1)
\$o2.x = \$o3.x[n-1]
\$o2.copy(\$o4, 3, 1, n-2, 2, 1)
\$o2.x *= 2
\$o2.x *= 2
\$o2.fft(\$o2, -1)
}
}
```
If you load the previous example so that FFT is defined, the following example shows the cosine and sine spectra of a pulse.
execute following example
```...
N=128
delay = 0
duration = N/2
setup_gui()
proc p() {
v1 = new Vector(N)
v1.fill(1, delay, delay+duration-1)
v1.plot(g1)

v2 = new Vector()
v3 = new Vector()
FFT(1, v1, v2, v3)
v2.plot(g2)
v3.plot(g3)

v4 = new Vector()
FFT(-1, v4, v2, v3)
v4.plot(g4)
}
p()

```