Revision 1 as of 2006-01-02 22:14:31

Clear message

<pre>

""" sinc(x) = sin(\pi x) / (\pi x), if x != 0

""" def sinc(x):

""" cbrt(x) = x^{1/3}, if x >= 0

""" def cbrt(x):

""" Convert from polar (r,w) to rectangular (x,y)

""" def rect(r, w, deg=0): # radian if deg=0; degree if deg=1

""" Convert from rectangular (x,y) to polar (r,w)

""" def polar(x, y, deg=0): # radian if deg=0; degree if deg=1

""" p(x) = polyeval(a, x)

""" def polyeval(a, x):

""" p'(x) = polyderiv(a)

where

""" def polyderiv(a):

""" Given x = r is a root of n'th degree polynomial p(x) = (x-r)q(x), divide p(x) by linear factor (x-r) using the same algorithm as polynomial evaluation. Then, return the (n-1)'th degree quotient q(x) = polyreduce(a, r)

""" def polyreduce(a, root):

""" x2 + ax + b = 0 (or ax2 + bx + c = 0) By substituting x = y-t and t = a/2, the equation reduces to

which has easy solution

""" def quadratic(a, b, c=None):

""" x3 + ax2 + bx + c = 0 (or ax3 + bx2 + cx + d = 0) With substitution x = y-t and t = a/3, the cubic equation reduces to

where p = b-3t2 and q = c-bt+2t3. Then, one real root y1 = u+v can be determined by solving

where w = u3, v3. From Vieta's theorem,

the other two (real or complex) roots can be obtained by solving

""" def cubic(a, b, c, d=None):

""" Ubiquitous Newton-Raphson algorithm for solving

where a root is repeatedly estimated by

until |dx|/(1+|x|) < TOL is achieved. This termination condition is a compromise between

""" def newton(func, funcd, x, TOL=1e-6): # f(x)=func(x), f'(x)=funcd(x)

""" Similar to Newton's method, but the derivative is estimated by divided difference using only function calls. A root is estimated by

where oldx = x[i-1] and x = x[i]. """ def secant(func, oldx, x, TOL=1e-6): # f(x)=func(x)

""" Closed Simpson's rule for

Divide [a,b] iteratively into h, h/2, h/4, h/8, ... step sizes; and, for each step size, evaluate f(x) at a+h, a+3h, a+5h, a+7h, ..., b-3h, b-h, noting that other points have already been sampled.

At each iteration step, data are sampled only where necessary so that the total data is represented by adding sampled points from all previous steps:


b


^


b

So, for step size of h/n, there are n intervals, and the data are sampled at the boundaries including the 2 end points.

If old = Trapezoid formula for an old step size 2h, then Trapezoid formula for the new step size h is obtained by

Also, Simpson formula for the new step size h is given by

""" def closedpoints(func, a, b, TOL=1e-6): # f(x)=func(x)

""" Open Simpson's rule (excluding end points) for

Divide [a,b] iteratively into h, h/3, h/9, h/27, ... step sizes; and, for each step size, evaluate f(x) at a+h/2, a+2h+h/2, a+3h+h/2, a+5h+h/2, a+6h+h/2, ... , b-3h-h/2, b-2h-h/2, b-h/2, noting that other points have already been sampled.

At each iteration step, data are sampled only where necessary so that the total data is represented by adding sampled points from all previous steps:


^


b


-----------------------


b

So, for step size of h/n, there are n intervals, and the data are sampled at the midpoints.

If old = Trapezoid formula for an old step size 3h, then Trapezoid formula for the new step size h is obtained by

Also, Simpson formula for the new step size h is given by

""" def openpoints(func, a, b, TOL=1e-6): # f(x)=func(x)

""" Find 2^n that is equal to or greater than. """ def nextpow2(i):

""" Return bit-reversed list, whose length is assumed to be 2^n: eg. 0111 <--> 1110 for N=2^4. """ def bitrev(x):

""" FFT using Cooley-Tukey algorithm where N = 2^n. The choice of e{-j2\pi/N} or e{j2\pi/N} is made by 'sign=-1' or 'sign=1' respectively. Since I prefer Engineering convention, I chose 'sign=-1' as the default.

FFT is performed as follows: 1. bit-reverse the array. 2. partition the data into group of m = 2, 4, 8, ..., N data points. 3. for each group with m data points,

  1. divide into upper half (section A) and lower half (section B),
    • each containing m/2 data points.
  2. divide unit circle by m.
  3. apply "butterfly" operation
    • |a| = |1 w||a| or a, b = a+w*b, a-w*b |b| |1 -w||b|

    • where a and b are data points of section A and B starting from the top of each section, and w is data points along the unit circle starting from z = 1+0j.

FFT ends after applying "butterfly" operation on the entire data array as whole, when m = N. """ def fft(x, sign=-1):

""" Inverse FFT with normalization by N, so that x == ifft(fft(x)) within round-off errors. """ def ifft(X):

""" DFT using discrete summation

where N need not be power of 2. The choice of e^{-j2\pi/N} or e^{j2\pi/N} is made by "sign=-1" or "sign=1" respectively. """ def dft(x, sign=-1):

""" Inverse DFT with normalization by N, so that x == idft(dft(x)) within round-off errors. """ def idft(X):

""" Convolution of 2 casual signals, x(t<0) = y(t<0) = 0, using discrete summation.

where the size of x[], y[], x*y[] are P, Q, N=P+Q-1 respectively. """ def conv(x, y):

""" Correlation of 2 casual signals, x(t<0) = y(t<0) = 0, using discrete summation.

where the size of x[], y[], Rxy[] are P, Q, N=P+Q-1 respectively.

The Rxy[i] data is not shifted, so relationship with the continuous Rxy(t) is preserved. For example, Rxy(0) = Rxy[0], Rxy(t) = Rxy[i], and Rxy(-t) = Rxy[-i]. The data are ordered as follows:

""" def corr(x, y):

""" FFT convolution using relation

where x[] and y[] have been zero-padded to length N, such that N >= P+Q-1 and N = 2^n. """ def fftconv(x, y):

""" FFT correlation using relation

where x[] and y[] have been zero-padded to length N, such that N >= P+Q-1 and N = 2^n. """ def fftcorr(x, y):

""" vdot(x, y) = <x|y> = \sum_i x_i y_i """ def vdot(x, y):

""" Various vector norms of x[]:

""" def vnorm(x, normtype=2):

""" Calculate mean and standard deviation of data x[]:

""" def meanstdv(x):

""" Read 1 number/line using eval() from <stdin> or 'file' if specified. If the first non-whitespace is not valid number characters '(+-.0123456789', then the line will be skipped. """ def getv(s=):

""" Read 2 numbers/line using eval() from <stdin> or 'file' if specified. If the first non-whitespace is not valid number characters '(+-.0123456789', then the line will be skipped. """ def getv2(s=):

""" Write 1 number/line to <stdout> or 'file' if specified. """ def printv(x, s=):

""" Returns coefficients to the regression line "y=ax+b" from x[] and y[]. Basically, it solves

where Sxy = \sum_i x_i y_i, Sx = \sum_i x_i, and Sy = \sum_i y_i. The solution is

where det = Sxx N - Sx^2. In addition,

It also prints to <stdout> few other data,

which are useful in assessing the confidence of estimation. """ def linreg(X, Y):

</pre>

Unable to edit the page? See the FrontPage for instructions.