Mercurial > hg > ltpda
comparison 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 |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:f0afece42f48 |
---|---|
1 (* | |
2 | |
3 /home/ghh/math/polyreg/polyregz.m 17.01.2008 Gerhard Heinzel AEI | |
4 | |
5 This is version 1.1 | |
6 | |
7 history: | |
8 version 1.0 17.1.08 initial release | |
9 version 1.1 18.1.08 fixed two typos in comment | |
10 | |
11 Mathematica code to produce C code for efficient polynomial detrending | |
12 | |
13 The polynomials are defined in terms of z = 2i/(n-1)-1, i=0...n | |
14 such that the range 0...n-1 is mapped to -1...+1 | |
15 | |
16 Thereby the high dynamic range of i^n is reduced to -1..1, | |
17 and furthermore every second entry in the matrix of | |
18 the normal equations and its inverse vanishes due to symmetry. | |
19 | |
20 The regression is done via explicit solution of the normal equations. | |
21 | |
22 These are of dimension (p+1) for degree p: | |
23 | |
24 ( s_0 s_1 s_2 .. s_p ) ( a_0 ) = ( b_0 ) | |
25 ( s_1 s_2 s_3 .. s_p+1 ) ( a_1 ) ( b_1 ) | |
26 ( ... ) ( ... ) ( ... ) | |
27 ( s_p s_p+1 .. s_2p ) ( a_p ) ( b_p ) | |
28 | |
29 with | |
30 s_k = Sum(i=0...n-1) z^k, | |
31 b_k = Sum(i=0...n-1) x_i z^k, | |
32 a_k = The unknown coefficient of z^k in the best-fit regression. | |
33 | |
34 The Matrix with s depends only on p and n, not on the data. | |
35 | |
36 The Mathematica code below finds exact explicit expressions for | |
37 the Matrix and its Inverse and writes the corresponding C code. | |
38 | |
39 If any modifications of the C code are desired apart from "indent"ing, | |
40 this file below should be altered but not the C code. | |
41 | |
42 *) | |
43 | |
44 <<clear.m | |
45 | |
46 (* | |
47 <<polyregz.m | |
48 *) | |
49 | |
50 z[i_,n_] := 2 i /(n-1) -1; | |
51 | |
52 s[k_,n_] := Sum[z[i,n]^k,{i,0,n-1}]; | |
53 | |
54 m[n_,p_] := Table[s[i+j,n],{i,0,p},{j,0,p}]; | |
55 | |
56 sol[p_] := sol[p] = Simplify[Inverse[m[n, p]]]; | |
57 | |
58 cln[x_] := CoefficientList[Numerator[x],n]; | |
59 cld[x_] := CoefficientList[Denominator[x],n]; | |
60 | |
61 max[x_] := Max[cln[x],cld[x]]; | |
62 | |
63 pn[x_] := "0" /; x== 0; | |
64 pn[x_] := ToString[CForm[x]] <> "L"; | |
65 | |
66 ncln[x_] := Map[pn, N[cln[x] / max[x], 22]]; | |
67 ncld[x_] := Map[pn, N[cld[x] / max[x], 22]]; | |
68 | |
69 polyprint[p_, x_] := p[[1]] /; Length[p]==1; | |
70 polyprint[p_, x_] := "(" <> polyprint[Drop[p,1], x] <> " * " <> x <> " + " <> p[[1]] <> ")" /; Length[p]>1 ; | |
71 | |
72 cform[x_] := "0" /; FreeQ[x,n]; | |
73 cform[x_] := polyprint[ncln[x], "n"] <> " / " <> polyprint[ncld[x], "n"]; | |
74 | |
75 wlist[sbeg_, list_, sep_, send_] := | |
76 Write[fp, sbeg <> Apply[StringJoin, Riffle[list, sep]] <> send]; | |
77 | |
78 out[p_] := Module[ {fn, s, i, j, s1, list}, | |
79 fn="polyreg"<>ToString[p] <> ".c"; | |
80 fp=OpenWrite[fn,FormatType->OutputForm, PageWidth->1024]; | |
81 Write[fp,"void"]; | |
82 Write[fp,"polyreg",p," (double *x, int nn, double *y, double *a)"]; | |
83 Write[fp,"{"]; | |
84 Write[fp,""]; | |
85 Write[fp,"/*"]; | |
86 Write[fp,"polynominal detrending of a time series, order ",p]; | |
87 Write[fp,"machine-generated file, do not edit!"]; | |
88 Write[fp,"made by polyregz.m (Mathematica )"]; | |
89 Write[fp,"Gerhard Heinzel AEI 17.01.2008"]; | |
90 Write[fp,""]; | |
91 Write[fp,"x[]: input, read-only: time series to be detrended"]; | |
92 Write[fp,"nn: input, read-only: length of x[]"]; | |
93 Write[fp,"y[]: output: time series with trend subtracted"]; | |
94 Write[fp,"a[]: fitting coefficients in for z^0, z^1, z^2,... with"]; | |
95 Write[fp," z = 2*i/(nn-1)-1 ; i=0,...,nn-1"]; | |
96 Write[fp,"*/"]; | |
97 Write[fp,""]; | |
98 Write[fp," long double n = nn, n1 = 2.L / (n - 1), z;"]; | |
99 For[i=0, i<=p, i++, | |
100 Write[fp," long double a",i,", temp",i,", sum",i," = 0;"]; | |
101 ]; | |
102 Write[fp," int i;"]; | |
103 Write[fp," for (i = 0; i < nn; i++)"]; | |
104 Write[fp," {"]; | |
105 Write[fp," z = n1 * i - 1.L;"]; | |
106 list={"x[i]"}; | |
107 For[i=0, i<=p, i++, | |
108 s1=" sum" <> ToString[i] <> " += "; | |
109 wlist[s1, list, " * ", ";"]; | |
110 list=Append[list,"z"]; | |
111 ]; | |
112 Write[fp,"/* the above code is efficiently optimized by GCC4 */"]; | |
113 Write[fp,""]; | |
114 Write[fp," }"]; | |
115 | |
116 s=sol[p]; | |
117 For[i=0, i<=p, i++, | |
118 list={}; | |
119 For[j=0, j<=p, j++, | |
120 If[!FreeQ[s[[i+1,j+1]],n], | |
121 Write[fp, "temp", j, " = ", cform[s[[i+1,j+1]]], ";"]; | |
122 list=Append[list,"temp" <> ToString[j] <> " * sum" <> ToString[j]]; | |
123 ] | |
124 ]; | |
125 s1 = "a" <> ToString[i] <> " = "; | |
126 wlist[s1, list, " + ", ";"]; | |
127 ]; | |
128 Write[fp," for (i = 0; i < nn; i++)"]; | |
129 Write[fp," {"]; | |
130 Write[fp," z = n1 * i - 1.L;"]; | |
131 list={}; | |
132 For[i=0, i<=p, i++, | |
133 list=Append[list, "a" <> ToString[i]]; | |
134 ]; | |
135 | |
136 Write[fp," y[i] = x[i] - ", polyprint[list, "z"], ";"]; | |
137 Write[fp," }"]; | |
138 For[i=0, i<=p, i++, | |
139 Write[fp," a[",i,"] = a",i,";"]; | |
140 ]; | |
141 Write[fp,"}"]; | |
142 Close[fp]; | |
143 ]; | |
144 | |
145 For[i=0, i<=10, i++, | |
146 out[i]; | |
147 Print["degree ",i," done."]; | |
148 ] | |
149 |