2 * linear least squares model
4 * Copyright (c) 2006 Michael Niedermayer <michaelni@gmx.at>
6 * This file is part of FFmpeg.
8 * FFmpeg 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 * FFmpeg 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 FFmpeg; 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
32 #include "attributes.h"
33 #include "float_dsp.h"
36 static void update_lls(LLSModel
*m
, const double *var
)
40 for (i
= 0; i
<= m
->indep_count
; i
++) {
41 for (j
= i
; j
<= m
->indep_count
; j
++) {
42 m
->covariance
[i
][j
] += var
[i
] * var
[j
];
47 void avpriv_solve_lls(LLSModel
*m
, double threshold
, unsigned short min_order
)
50 double (*factor
)[MAX_VARS_ALIGN
] = (void *) &m
->covariance
[1][0];
51 double (*covar
) [MAX_VARS_ALIGN
] = (void *) &m
->covariance
[1][1];
52 double *covar_y
= m
->covariance
[0];
53 int count
= m
->indep_count
;
55 for (i
= 0; i
< count
; i
++) {
56 for (j
= i
; j
< count
; j
++) {
57 double sum
= covar
[i
][j
];
59 for (k
= 0; k
<= i
-1; k
++)
60 sum
-= factor
[i
][k
] * factor
[j
][k
];
65 factor
[i
][i
] = sqrt(sum
);
67 factor
[j
][i
] = sum
/ factor
[i
][i
];
72 for (i
= 0; i
< count
; i
++) {
73 double sum
= covar_y
[i
+ 1];
75 for (k
= 0; k
<= i
-1; k
++)
76 sum
-= factor
[i
][k
] * m
->coeff
[0][k
];
78 m
->coeff
[0][i
] = sum
/ factor
[i
][i
];
81 for (j
= count
- 1; j
>= min_order
; j
--) {
82 for (i
= j
; i
>= 0; i
--) {
83 double sum
= m
->coeff
[0][i
];
85 for (k
= i
+ 1; k
<= j
; k
++)
86 sum
-= factor
[k
][i
] * m
->coeff
[j
][k
];
88 m
->coeff
[j
][i
] = sum
/ factor
[i
][i
];
91 m
->variance
[j
] = covar_y
[0];
93 for (i
= 0; i
<= j
; i
++) {
94 double sum
= m
->coeff
[j
][i
] * covar
[i
][i
] - 2 * covar_y
[i
+ 1];
96 for (k
= 0; k
< i
; k
++)
97 sum
+= 2 * m
->coeff
[j
][k
] * covar
[k
][i
];
99 m
->variance
[j
] += m
->coeff
[j
][i
] * sum
;
104 static double evaluate_lls(LLSModel
*m
, const double *param
, int order
)
106 return ff_scalarproduct_double_c(m
->coeff
[order
], param
, order
+ 1);
109 av_cold
void avpriv_init_lls(LLSModel
*m
, int indep_count
)
111 memset(m
, 0, sizeof(LLSModel
));
112 m
->indep_count
= indep_count
;
113 m
->update_lls
= update_lls
;
114 m
->evaluate_lls
= evaluate_lls
;
116 ff_init_lls_riscv(m
);