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[0] 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()

SEE ALSO

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.


add

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[5] = v1.x[6] = 1
v2.x[3] = v2.x[4] = 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[0] is the amplitude of the 0 frequency cosine (constant) and vec.x[1] 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.

execute following example

...	//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[0] 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[0] /= 2	// makes the spectrum appear discontinuous
                $o3.x[1] /= 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[0]           //highest cos started in o3.x[1
                $o4.x[0] = $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[1] = $o3.x[n-1]
                $o2.copy($o4, 3, 1, n-2, 2, 1)
                $o2.x[0] *= 2
                $o2.x[1] *= 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()

SEE ALSO

fft spctrm


neuron/general/classes/vector/vect2.hel : Dec 6 07:13