Mercurial > hg > ltpda
diff src/ltpda_dft/polyregz.m @ 0:f0afece42f48
Import.
author | Daniele Nicolodi <nicolodi@science.unitn.it> |
---|---|
date | Wed, 23 Nov 2011 19:22:13 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/ltpda_dft/polyregz.m Wed Nov 23 19:22:13 2011 +0100 @@ -0,0 +1,149 @@ +(* + +/home/ghh/math/polyreg/polyregz.m 17.01.2008 Gerhard Heinzel AEI + +This is version 1.1 + +history: + version 1.0 17.1.08 initial release + version 1.1 18.1.08 fixed two typos in comment + +Mathematica code to produce C code for efficient polynomial detrending + +The polynomials are defined in terms of z = 2i/(n-1)-1, i=0...n +such that the range 0...n-1 is mapped to -1...+1 + +Thereby the high dynamic range of i^n is reduced to -1..1, +and furthermore every second entry in the matrix of +the normal equations and its inverse vanishes due to symmetry. + +The regression is done via explicit solution of the normal equations. + +These are of dimension (p+1) for degree p: + +( s_0 s_1 s_2 .. s_p ) ( a_0 ) = ( b_0 ) +( s_1 s_2 s_3 .. s_p+1 ) ( a_1 ) ( b_1 ) +( ... ) ( ... ) ( ... ) +( s_p s_p+1 .. s_2p ) ( a_p ) ( b_p ) + +with +s_k = Sum(i=0...n-1) z^k, +b_k = Sum(i=0...n-1) x_i z^k, +a_k = The unknown coefficient of z^k in the best-fit regression. + +The Matrix with s depends only on p and n, not on the data. + +The Mathematica code below finds exact explicit expressions for +the Matrix and its Inverse and writes the corresponding C code. + +If any modifications of the C code are desired apart from "indent"ing, +this file below should be altered but not the C code. + +*) + +<<clear.m + +(* +<<polyregz.m +*) + +z[i_,n_] := 2 i /(n-1) -1; + +s[k_,n_] := Sum[z[i,n]^k,{i,0,n-1}]; + +m[n_,p_] := Table[s[i+j,n],{i,0,p},{j,0,p}]; + +sol[p_] := sol[p] = Simplify[Inverse[m[n, p]]]; + +cln[x_] := CoefficientList[Numerator[x],n]; +cld[x_] := CoefficientList[Denominator[x],n]; + +max[x_] := Max[cln[x],cld[x]]; + +pn[x_] := "0" /; x== 0; +pn[x_] := ToString[CForm[x]] <> "L"; + +ncln[x_] := Map[pn, N[cln[x] / max[x], 22]]; +ncld[x_] := Map[pn, N[cld[x] / max[x], 22]]; + +polyprint[p_, x_] := p[[1]] /; Length[p]==1; +polyprint[p_, x_] := "(" <> polyprint[Drop[p,1], x] <> " * " <> x <> " + " <> p[[1]] <> ")" /; Length[p]>1 ; + +cform[x_] := "0" /; FreeQ[x,n]; +cform[x_] := polyprint[ncln[x], "n"] <> " / " <> polyprint[ncld[x], "n"]; + +wlist[sbeg_, list_, sep_, send_] := + Write[fp, sbeg <> Apply[StringJoin, Riffle[list, sep]] <> send]; + +out[p_] := Module[ {fn, s, i, j, s1, list}, + fn="polyreg"<>ToString[p] <> ".c"; + fp=OpenWrite[fn,FormatType->OutputForm, PageWidth->1024]; + Write[fp,"void"]; + Write[fp,"polyreg",p," (double *x, int nn, double *y, double *a)"]; + Write[fp,"{"]; + Write[fp,""]; + Write[fp,"/*"]; + Write[fp,"polynominal detrending of a time series, order ",p]; + Write[fp,"machine-generated file, do not edit!"]; + Write[fp,"made by polyregz.m (Mathematica )"]; + Write[fp,"Gerhard Heinzel AEI 17.01.2008"]; + Write[fp,""]; + Write[fp,"x[]: input, read-only: time series to be detrended"]; + Write[fp,"nn: input, read-only: length of x[]"]; + Write[fp,"y[]: output: time series with trend subtracted"]; + Write[fp,"a[]: fitting coefficients in for z^0, z^1, z^2,... with"]; + Write[fp," z = 2*i/(nn-1)-1 ; i=0,...,nn-1"]; + Write[fp,"*/"]; + Write[fp,""]; + Write[fp," long double n = nn, n1 = 2.L / (n - 1), z;"]; + For[i=0, i<=p, i++, + Write[fp," long double a",i,", temp",i,", sum",i," = 0;"]; + ]; + Write[fp," int i;"]; + Write[fp," for (i = 0; i < nn; i++)"]; + Write[fp," {"]; + Write[fp," z = n1 * i - 1.L;"]; + list={"x[i]"}; + For[i=0, i<=p, i++, + s1=" sum" <> ToString[i] <> " += "; + wlist[s1, list, " * ", ";"]; + list=Append[list,"z"]; + ]; + Write[fp,"/* the above code is efficiently optimized by GCC4 */"]; + Write[fp,""]; + Write[fp," }"]; + + s=sol[p]; + For[i=0, i<=p, i++, + list={}; + For[j=0, j<=p, j++, + If[!FreeQ[s[[i+1,j+1]],n], + Write[fp, "temp", j, " = ", cform[s[[i+1,j+1]]], ";"]; + list=Append[list,"temp" <> ToString[j] <> " * sum" <> ToString[j]]; + ] + ]; + s1 = "a" <> ToString[i] <> " = "; + wlist[s1, list, " + ", ";"]; + ]; + Write[fp," for (i = 0; i < nn; i++)"]; + Write[fp," {"]; + Write[fp," z = n1 * i - 1.L;"]; + list={}; + For[i=0, i<=p, i++, + list=Append[list, "a" <> ToString[i]]; + ]; + + Write[fp," y[i] = x[i] - ", polyprint[list, "z"], ";"]; + Write[fp," }"]; + For[i=0, i<=p, i++, + Write[fp," a[",i,"] = a",i,";"]; + ]; + Write[fp,"}"]; + Close[fp]; +]; + +For[i=0, i<=10, i++, + out[i]; + Print["degree ",i," done."]; +] +