Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
MorsGames
GitHub Repository: MorsGames/sm64plus
Path: blob/master/tools/sdk-tools/tabledesign/estimate.c
7861 views
1
#include <math.h>
2
#include <stdlib.h>
3
#include "tabledesign.h"
4
5
/**
6
* Computes the autocorrelation of a vector. More precisely, it computes the
7
* dot products of vec[i:] and vec[:-i] for i in [0, k). Unused.
8
*
9
* See https://en.wikipedia.org/wiki/Autocorrelation.
10
*/
11
void acf(double *vec, int n, double *out, int k)
12
{
13
int i, j;
14
double sum;
15
for (i = 0; i < k; i++)
16
{
17
sum = 0.0;
18
for (j = 0; j < n - i; j++)
19
{
20
sum += vec[j + i] * vec[j];
21
}
22
out[i] = sum;
23
}
24
}
25
26
// https://en.wikipedia.org/wiki/Durbin%E2%80%93Watson_statistic ?
27
// "detects the presence of autocorrelation at lag 1 in the residuals (prediction errors)"
28
int durbin(double *arg0, int n, double *arg2, double *arg3, double *outSomething)
29
{
30
int i, j;
31
double sum, div;
32
int ret;
33
34
arg3[0] = 1.0;
35
div = arg0[0];
36
ret = 0;
37
38
for (i = 1; i <= n; i++)
39
{
40
sum = 0.0;
41
for (j = 1; j <= i-1; j++)
42
{
43
sum += arg3[j] * arg0[i - j];
44
}
45
46
arg3[i] = (div > 0.0 ? -(arg0[i] + sum) / div : 0.0);
47
arg2[i] = arg3[i];
48
49
if (fabs(arg2[i]) > 1.0)
50
{
51
ret++;
52
}
53
54
for (j = 1; j < i; j++)
55
{
56
arg3[j] += arg3[i - j] * arg3[i];
57
}
58
59
div *= 1.0 - arg3[i] * arg3[i];
60
}
61
*outSomething = div;
62
return ret;
63
}
64
65
void afromk(double *in, double *out, int n)
66
{
67
int i, j;
68
out[0] = 1.0;
69
for (i = 1; i <= n; i++)
70
{
71
out[i] = in[i];
72
for (j = 1; j <= i - 1; j++)
73
{
74
out[j] += out[i - j] * out[i];
75
}
76
}
77
}
78
79
int kfroma(double *in, double *out, int n)
80
{
81
int i, j;
82
double div;
83
double temp;
84
double *next;
85
int ret;
86
87
ret = 0;
88
next = malloc((n + 1) * sizeof(double));
89
90
out[n] = in[n];
91
for (i = n - 1; i >= 1; i--)
92
{
93
for (j = 0; j <= i; j++)
94
{
95
temp = out[i + 1];
96
div = 1.0 - (temp * temp);
97
if (div == 0.0)
98
{
99
free(next);
100
return 1;
101
}
102
next[j] = (in[j] - in[i + 1 - j] * temp) / div;
103
}
104
105
for (j = 0; j <= i; j++)
106
{
107
in[j] = next[j];
108
}
109
110
out[i] = next[i];
111
if (fabs(out[i]) > 1.0)
112
{
113
ret++;
114
}
115
}
116
117
free(next);
118
return ret;
119
}
120
121
void rfroma(double *arg0, int n, double *arg2)
122
{
123
int i, j;
124
double **mat;
125
double div;
126
127
mat = malloc((n + 1) * sizeof(double*));
128
mat[n] = malloc((n + 1) * sizeof(double));
129
mat[n][0] = 1.0;
130
for (i = 1; i <= n; i++)
131
{
132
mat[n][i] = -arg0[i];
133
}
134
135
for (i = n; i >= 1; i--)
136
{
137
mat[i - 1] = malloc(i * sizeof(double));
138
div = 1.0 - mat[i][i] * mat[i][i];
139
for (j = 1; j <= i - 1; j++)
140
{
141
mat[i - 1][j] = (mat[i][i - j] * mat[i][i] + mat[i][j]) / div;
142
}
143
}
144
145
arg2[0] = 1.0;
146
for (i = 1; i <= n; i++)
147
{
148
arg2[i] = 0.0;
149
for (j = 1; j <= i; j++)
150
{
151
arg2[i] += mat[i][j] * arg2[i - j];
152
}
153
}
154
155
free(mat[n]);
156
for (i = n; i > 0; i--)
157
{
158
free(mat[i - 1]);
159
}
160
free(mat);
161
}
162
163
double model_dist(double *arg0, double *arg1, int n)
164
{
165
double *sp3C;
166
double *sp38;
167
double ret;
168
int i, j;
169
170
sp3C = malloc((n + 1) * sizeof(double));
171
sp38 = malloc((n + 1) * sizeof(double));
172
rfroma(arg1, n, sp3C);
173
174
for (i = 0; i <= n; i++)
175
{
176
sp38[i] = 0.0;
177
for (j = 0; j <= n - i; j++)
178
{
179
sp38[i] += arg0[j] * arg0[i + j];
180
}
181
}
182
183
ret = sp38[0] * sp3C[0];
184
for (i = 1; i <= n; i++)
185
{
186
ret += 2 * sp3C[i] * sp38[i];
187
}
188
189
free(sp3C);
190
free(sp38);
191
return ret;
192
}
193
194
// compute autocorrelation matrix?
195
void acmat(short *in, int n, int m, double **out)
196
{
197
int i, j, k;
198
for (i = 1; i <= n; i++)
199
{
200
for (j = 1; j <= n; j++)
201
{
202
out[i][j] = 0.0;
203
for (k = 0; k < m; k++)
204
{
205
out[i][j] += in[k - i] * in[k - j];
206
}
207
}
208
}
209
}
210
211
// compute autocorrelation vector?
212
void acvect(short *in, int n, int m, double *out)
213
{
214
int i, j;
215
for (i = 0; i <= n; i++)
216
{
217
out[i] = 0.0;
218
for (j = 0; j < m; j++)
219
{
220
out[i] -= in[j - i] * in[j];
221
}
222
}
223
}
224
225
/**
226
* Replaces a real n-by-n matrix "a" with the LU decomposition of a row-wise
227
* permutation of itself.
228
*
229
* Input parameters:
230
* a: The matrix which is operated on. 1-indexed; it should be of size
231
* (n+1) x (n+1), and row/column index 0 is not used.
232
* n: The size of the matrix.
233
*
234
* Output parameters:
235
* indx: The row permutation performed. 1-indexed; it should be of size n+1,
236
* and index 0 is not used.
237
* d: the determinant of the permutation matrix.
238
*
239
* Returns 1 to indicate failure if the matrix is singular or has zeroes on the
240
* diagonal, 0 on success.
241
*
242
* Derived from ludcmp in "Numerical Recipes in C: The Art of Scientific Computing",
243
* with modified error handling.
244
*/
245
int lud(double **a, int n, int *indx, int *d)
246
{
247
int i,imax,j,k;
248
double big,dum,sum,temp;
249
double min,max;
250
double *vv;
251
252
vv = malloc((n + 1) * sizeof(double));
253
*d=1;
254
for (i=1;i<=n;i++) {
255
big=0.0;
256
for (j=1;j<=n;j++)
257
if ((temp=fabs(a[i][j])) > big) big=temp;
258
if (big == 0.0) return 1;
259
vv[i]=1.0/big;
260
}
261
for (j=1;j<=n;j++) {
262
for (i=1;i<j;i++) {
263
sum=a[i][j];
264
for (k=1;k<i;k++) sum -= a[i][k]*a[k][j];
265
a[i][j]=sum;
266
}
267
big=0.0;
268
for (i=j;i<=n;i++) {
269
sum=a[i][j];
270
for (k=1;k<j;k++)
271
sum -= a[i][k]*a[k][j];
272
a[i][j]=sum;
273
if ( (dum=vv[i]*fabs(sum)) >= big) {
274
big=dum;
275
imax=i;
276
}
277
}
278
if (j != imax) {
279
for (k=1;k<=n;k++) {
280
dum=a[imax][k];
281
a[imax][k]=a[j][k];
282
a[j][k]=dum;
283
}
284
*d = -(*d);
285
vv[imax]=vv[j];
286
}
287
indx[j]=imax;
288
if (a[j][j] == 0.0) return 1;
289
if (j != n) {
290
dum=1.0/(a[j][j]);
291
for (i=j+1;i<=n;i++) a[i][j] *= dum;
292
}
293
}
294
free(vv);
295
296
min = 1e10;
297
max = 0.0;
298
for (i = 1; i <= n; i++)
299
{
300
temp = fabs(a[i][i]);
301
if (temp < min) min = temp;
302
if (temp > max) max = temp;
303
}
304
return min / max < 1e-10 ? 1 : 0;
305
}
306
307
/**
308
* Solves the set of n linear equations Ax = b, using LU decomposition
309
* back-substitution.
310
*
311
* Input parameters:
312
* a: The LU decomposition of a matrix, created by "lud".
313
* n: The size of the matrix.
314
* indx: Row permutation vector, created by "lud".
315
* b: The vector b in the equation. 1-indexed; is should be of size n+1, and
316
* index 0 is not used.
317
*
318
* Output parameters:
319
* b: The output vector x. 1-indexed.
320
*
321
* From "Numerical Recipes in C: The Art of Scientific Computing".
322
*/
323
void lubksb(double **a, int n, int *indx, double *b)
324
{
325
int i,ii=0,ip,j;
326
double sum;
327
328
for (i=1;i<=n;i++) {
329
ip=indx[i];
330
sum=b[ip];
331
b[ip]=b[i];
332
if (ii)
333
for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j];
334
else if (sum) ii=i;
335
b[i]=sum;
336
}
337
for (i=n;i>=1;i--) {
338
sum=b[i];
339
for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j];
340
b[i]=sum/a[i][i];
341
}
342
}
343
344