sm64

A Super Mario 64 decompilation
Log | Files | Refs | README | LICENSE

estimate.c (7497B)


      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 }