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