00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00028 #include <math.h>
00029 #include <string.h>
00030
00031 #include "lls.h"
00032
00033 void av_init_lls(LLSModel *m, int indep_count)
00034 {
00035 memset(m, 0, sizeof(LLSModel));
00036 m->indep_count = indep_count;
00037 }
00038
00039 void av_update_lls(LLSModel *m, double *var, double decay)
00040 {
00041 int i, j;
00042
00043 for (i = 0; i <= m->indep_count; i++) {
00044 for (j = i; j <= m->indep_count; j++) {
00045 m->covariance[i][j] *= decay;
00046 m->covariance[i][j] += var[i] * var[j];
00047 }
00048 }
00049 }
00050
00051 void av_solve_lls(LLSModel *m, double threshold, int min_order)
00052 {
00053 int i, j, k;
00054 double (*factor)[MAX_VARS + 1] = (void *) &m->covariance[1][0];
00055 double (*covar) [MAX_VARS + 1] = (void *) &m->covariance[1][1];
00056 double *covar_y = m->covariance[0];
00057 int count = m->indep_count;
00058
00059 for (i = 0; i < count; i++) {
00060 for (j = i; j < count; j++) {
00061 double sum = covar[i][j];
00062
00063 for (k = i - 1; k >= 0; k--)
00064 sum -= factor[i][k] * factor[j][k];
00065
00066 if (i == j) {
00067 if (sum < threshold)
00068 sum = 1.0;
00069 factor[i][i] = sqrt(sum);
00070 } else {
00071 factor[j][i] = sum / factor[i][i];
00072 }
00073 }
00074 }
00075
00076 for (i = 0; i < count; i++) {
00077 double sum = covar_y[i + 1];
00078
00079 for (k = i - 1; k >= 0; k--)
00080 sum -= factor[i][k] * m->coeff[0][k];
00081
00082 m->coeff[0][i] = sum / factor[i][i];
00083 }
00084
00085 for (j = count - 1; j >= min_order; j--) {
00086 for (i = j; i >= 0; i--) {
00087 double sum = m->coeff[0][i];
00088
00089 for (k = i + 1; k <= j; k++)
00090 sum -= factor[k][i] * m->coeff[j][k];
00091
00092 m->coeff[j][i] = sum / factor[i][i];
00093 }
00094
00095 m->variance[j] = covar_y[0];
00096
00097 for (i = 0; i <= j; i++) {
00098 double sum = m->coeff[j][i] * covar[i][i] - 2 * covar_y[i + 1];
00099
00100 for (k = 0; k < i; k++)
00101 sum += 2 * m->coeff[j][k] * covar[k][i];
00102
00103 m->variance[j] += m->coeff[j][i] * sum;
00104 }
00105 }
00106 }
00107
00108 double av_evaluate_lls(LLSModel *m, double *param, int order)
00109 {
00110 int i;
00111 double out = 0;
00112
00113 for (i = 0; i <= order; i++)
00114 out += param[i] * m->coeff[order][i];
00115
00116 return out;
00117 }
00118
00119 #ifdef TEST
00120
00121 #include <stdio.h>
00122 #include <limits.h>
00123 #include "lfg.h"
00124
00125 int main(void)
00126 {
00127 LLSModel m;
00128 int i, order;
00129 AVLFG lfg;
00130
00131 av_lfg_init(&lfg, 1);
00132 av_init_lls(&m, 3);
00133
00134 for (i = 0; i < 100; i++) {
00135 double var[4];
00136 double eval;
00137
00138 var[0] = (av_lfg_get(&lfg) / (double) UINT_MAX - 0.5) * 2;
00139 var[1] = var[0] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
00140 var[2] = var[1] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
00141 var[3] = var[2] + av_lfg_get(&lfg) / (double) UINT_MAX - 0.5;
00142 av_update_lls(&m, var, 0.99);
00143 av_solve_lls(&m, 0.001, 0);
00144 for (order = 0; order < 3; order++) {
00145 eval = av_evaluate_lls(&m, var + 1, order);
00146 printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n",
00147 var[0], order, eval, sqrt(m.variance[order] / (i + 1)),
00148 m.coeff[order][0], m.coeff[order][1],
00149 m.coeff[order][2]);
00150 }
00151 }
00152 return 0;
00153 }
00154
00155 #endif