2 * linear least squares model
4 * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
6 * This file is part of Libav.
8 * Libav is free software; you can redistribute it and/or
9 * modify it under the terms of the GNU Lesser General Public
10 * License as published by the Free Software Foundation; either
11 * version 2.1 of the License, or (at your option) any later version.
13 * Libav is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with Libav; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
25 * linear least squares model
33 void av_init_lls(LLSModel
*m
, int indep_count
)
35 memset(m
, 0, sizeof(LLSModel
));
36 m
->indep_count
= indep_count
;
39 void av_update_lls(LLSModel
*m
, double *var
, double decay
)
43 for (i
= 0; i
<= m
->indep_count
; i
++) {
44 for (j
= i
; j
<= m
->indep_count
; j
++) {
45 m
->covariance
[i
][j
] *= decay
;
46 m
->covariance
[i
][j
] += var
[i
] * var
[j
];
51 void av_solve_lls(LLSModel
*m
, double threshold
, int min_order
)
54 double (*factor
)[MAX_VARS
+ 1] = (void *) &m
->covariance
[1][0];
55 double (*covar
) [MAX_VARS
+ 1] = (void *) &m
->covariance
[1][1];
56 double *covar_y
= m
->covariance
[0];
57 int count
= m
->indep_count
;
59 for (i
= 0; i
< count
; i
++) {
60 for (j
= i
; j
< count
; j
++) {
61 double sum
= covar
[i
][j
];
63 for (k
= i
- 1; k
>= 0; k
--)
64 sum
-= factor
[i
][k
] * factor
[j
][k
];
69 factor
[i
][i
] = sqrt(sum
);
71 factor
[j
][i
] = sum
/ factor
[i
][i
];
76 for (i
= 0; i
< count
; i
++) {
77 double sum
= covar_y
[i
+ 1];
79 for (k
= i
- 1; k
>= 0; k
--)
80 sum
-= factor
[i
][k
] * m
->coeff
[0][k
];
82 m
->coeff
[0][i
] = sum
/ factor
[i
][i
];
85 for (j
= count
- 1; j
>= min_order
; j
--) {
86 for (i
= j
; i
>= 0; i
--) {
87 double sum
= m
->coeff
[0][i
];
89 for (k
= i
+ 1; k
<= j
; k
++)
90 sum
-= factor
[k
][i
] * m
->coeff
[j
][k
];
92 m
->coeff
[j
][i
] = sum
/ factor
[i
][i
];
95 m
->variance
[j
] = covar_y
[0];
97 for (i
= 0; i
<= j
; i
++) {
98 double sum
= m
->coeff
[j
][i
] * covar
[i
][i
] - 2 * covar_y
[i
+ 1];
100 for (k
= 0; k
< i
; k
++)
101 sum
+= 2 * m
->coeff
[j
][k
] * covar
[k
][i
];
103 m
->variance
[j
] += m
->coeff
[j
][i
] * sum
;
108 double av_evaluate_lls(LLSModel
*m
, double *param
, int order
)
113 for (i
= 0; i
<= order
; i
++)
114 out
+= param
[i
] * m
->coeff
[order
][i
];
131 for (i
= 0; i
< 100; i
++) {
135 var
[0] = (rand() / (double) RAND_MAX
- 0.5) * 2;
136 var
[1] = var
[0] + rand() / (double) RAND_MAX
- 0.5;
137 var
[2] = var
[1] + rand() / (double) RAND_MAX
- 0.5;
138 var
[3] = var
[2] + rand() / (double) RAND_MAX
- 0.5;
139 av_update_lls(&m
, var
, 0.99);
140 av_solve_lls(&m
, 0.001, 0);
141 for (order
= 0; order
< 3; order
++) {
142 eval
= av_evaluate_lls(&m
, var
+ 1, order
);
143 printf("real:%9f order:%d pred:%9f var:%f coeffs:%f %9f %9f\n",
144 var
[0], order
, eval
, sqrt(m
.variance
[order
] / (i
+ 1)),
145 m
.coeff
[order
][0], m
.coeff
[order
][1],