Path: blob/master/tools/sdk-tools/tabledesign/estimate.c
7861 views
#include <math.h>1#include <stdlib.h>2#include "tabledesign.h"34/**5* Computes the autocorrelation of a vector. More precisely, it computes the6* dot products of vec[i:] and vec[:-i] for i in [0, k). Unused.7*8* See https://en.wikipedia.org/wiki/Autocorrelation.9*/10void acf(double *vec, int n, double *out, int k)11{12int i, j;13double sum;14for (i = 0; i < k; i++)15{16sum = 0.0;17for (j = 0; j < n - i; j++)18{19sum += vec[j + i] * vec[j];20}21out[i] = sum;22}23}2425// https://en.wikipedia.org/wiki/Durbin%E2%80%93Watson_statistic ?26// "detects the presence of autocorrelation at lag 1 in the residuals (prediction errors)"27int durbin(double *arg0, int n, double *arg2, double *arg3, double *outSomething)28{29int i, j;30double sum, div;31int ret;3233arg3[0] = 1.0;34div = arg0[0];35ret = 0;3637for (i = 1; i <= n; i++)38{39sum = 0.0;40for (j = 1; j <= i-1; j++)41{42sum += arg3[j] * arg0[i - j];43}4445arg3[i] = (div > 0.0 ? -(arg0[i] + sum) / div : 0.0);46arg2[i] = arg3[i];4748if (fabs(arg2[i]) > 1.0)49{50ret++;51}5253for (j = 1; j < i; j++)54{55arg3[j] += arg3[i - j] * arg3[i];56}5758div *= 1.0 - arg3[i] * arg3[i];59}60*outSomething = div;61return ret;62}6364void afromk(double *in, double *out, int n)65{66int i, j;67out[0] = 1.0;68for (i = 1; i <= n; i++)69{70out[i] = in[i];71for (j = 1; j <= i - 1; j++)72{73out[j] += out[i - j] * out[i];74}75}76}7778int kfroma(double *in, double *out, int n)79{80int i, j;81double div;82double temp;83double *next;84int ret;8586ret = 0;87next = malloc((n + 1) * sizeof(double));8889out[n] = in[n];90for (i = n - 1; i >= 1; i--)91{92for (j = 0; j <= i; j++)93{94temp = out[i + 1];95div = 1.0 - (temp * temp);96if (div == 0.0)97{98free(next);99return 1;100}101next[j] = (in[j] - in[i + 1 - j] * temp) / div;102}103104for (j = 0; j <= i; j++)105{106in[j] = next[j];107}108109out[i] = next[i];110if (fabs(out[i]) > 1.0)111{112ret++;113}114}115116free(next);117return ret;118}119120void rfroma(double *arg0, int n, double *arg2)121{122int i, j;123double **mat;124double div;125126mat = malloc((n + 1) * sizeof(double*));127mat[n] = malloc((n + 1) * sizeof(double));128mat[n][0] = 1.0;129for (i = 1; i <= n; i++)130{131mat[n][i] = -arg0[i];132}133134for (i = n; i >= 1; i--)135{136mat[i - 1] = malloc(i * sizeof(double));137div = 1.0 - mat[i][i] * mat[i][i];138for (j = 1; j <= i - 1; j++)139{140mat[i - 1][j] = (mat[i][i - j] * mat[i][i] + mat[i][j]) / div;141}142}143144arg2[0] = 1.0;145for (i = 1; i <= n; i++)146{147arg2[i] = 0.0;148for (j = 1; j <= i; j++)149{150arg2[i] += mat[i][j] * arg2[i - j];151}152}153154free(mat[n]);155for (i = n; i > 0; i--)156{157free(mat[i - 1]);158}159free(mat);160}161162double model_dist(double *arg0, double *arg1, int n)163{164double *sp3C;165double *sp38;166double ret;167int i, j;168169sp3C = malloc((n + 1) * sizeof(double));170sp38 = malloc((n + 1) * sizeof(double));171rfroma(arg1, n, sp3C);172173for (i = 0; i <= n; i++)174{175sp38[i] = 0.0;176for (j = 0; j <= n - i; j++)177{178sp38[i] += arg0[j] * arg0[i + j];179}180}181182ret = sp38[0] * sp3C[0];183for (i = 1; i <= n; i++)184{185ret += 2 * sp3C[i] * sp38[i];186}187188free(sp3C);189free(sp38);190return ret;191}192193// compute autocorrelation matrix?194void acmat(short *in, int n, int m, double **out)195{196int i, j, k;197for (i = 1; i <= n; i++)198{199for (j = 1; j <= n; j++)200{201out[i][j] = 0.0;202for (k = 0; k < m; k++)203{204out[i][j] += in[k - i] * in[k - j];205}206}207}208}209210// compute autocorrelation vector?211void acvect(short *in, int n, int m, double *out)212{213int i, j;214for (i = 0; i <= n; i++)215{216out[i] = 0.0;217for (j = 0; j < m; j++)218{219out[i] -= in[j - i] * in[j];220}221}222}223224/**225* Replaces a real n-by-n matrix "a" with the LU decomposition of a row-wise226* permutation of itself.227*228* Input parameters:229* a: The matrix which is operated on. 1-indexed; it should be of size230* (n+1) x (n+1), and row/column index 0 is not used.231* n: The size of the matrix.232*233* Output parameters:234* indx: The row permutation performed. 1-indexed; it should be of size n+1,235* and index 0 is not used.236* d: the determinant of the permutation matrix.237*238* Returns 1 to indicate failure if the matrix is singular or has zeroes on the239* diagonal, 0 on success.240*241* Derived from ludcmp in "Numerical Recipes in C: The Art of Scientific Computing",242* with modified error handling.243*/244int lud(double **a, int n, int *indx, int *d)245{246int i,imax,j,k;247double big,dum,sum,temp;248double min,max;249double *vv;250251vv = malloc((n + 1) * sizeof(double));252*d=1;253for (i=1;i<=n;i++) {254big=0.0;255for (j=1;j<=n;j++)256if ((temp=fabs(a[i][j])) > big) big=temp;257if (big == 0.0) return 1;258vv[i]=1.0/big;259}260for (j=1;j<=n;j++) {261for (i=1;i<j;i++) {262sum=a[i][j];263for (k=1;k<i;k++) sum -= a[i][k]*a[k][j];264a[i][j]=sum;265}266big=0.0;267for (i=j;i<=n;i++) {268sum=a[i][j];269for (k=1;k<j;k++)270sum -= a[i][k]*a[k][j];271a[i][j]=sum;272if ( (dum=vv[i]*fabs(sum)) >= big) {273big=dum;274imax=i;275}276}277if (j != imax) {278for (k=1;k<=n;k++) {279dum=a[imax][k];280a[imax][k]=a[j][k];281a[j][k]=dum;282}283*d = -(*d);284vv[imax]=vv[j];285}286indx[j]=imax;287if (a[j][j] == 0.0) return 1;288if (j != n) {289dum=1.0/(a[j][j]);290for (i=j+1;i<=n;i++) a[i][j] *= dum;291}292}293free(vv);294295min = 1e10;296max = 0.0;297for (i = 1; i <= n; i++)298{299temp = fabs(a[i][i]);300if (temp < min) min = temp;301if (temp > max) max = temp;302}303return min / max < 1e-10 ? 1 : 0;304}305306/**307* Solves the set of n linear equations Ax = b, using LU decomposition308* back-substitution.309*310* Input parameters:311* a: The LU decomposition of a matrix, created by "lud".312* n: The size of the matrix.313* indx: Row permutation vector, created by "lud".314* b: The vector b in the equation. 1-indexed; is should be of size n+1, and315* index 0 is not used.316*317* Output parameters:318* b: The output vector x. 1-indexed.319*320* From "Numerical Recipes in C: The Art of Scientific Computing".321*/322void lubksb(double **a, int n, int *indx, double *b)323{324int i,ii=0,ip,j;325double sum;326327for (i=1;i<=n;i++) {328ip=indx[i];329sum=b[ip];330b[ip]=b[i];331if (ii)332for (j=ii;j<=i-1;j++) sum -= a[i][j]*b[j];333else if (sum) ii=i;334b[i]=sum;335}336for (i=n;i>=1;i--) {337sum=b[i];338for (j=i+1;j<=n;j++) sum -= a[i][j]*b[j];339b[i]=sum/a[i][i];340}341}342343344