1 /*
2 * principal component analysis (PCA)
3 * Copyright (c) 2004 Michael Niedermayer <michaelni@gmx.at>
4 *
5 * This file is part of FFmpeg.
6 *
7 * FFmpeg is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU Lesser General Public
9 * License as published by the Free Software Foundation; either
10 * version 2.1 of the License, or (at your option) any later version.
11 *
12 * FFmpeg is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public
18 * License along with FFmpeg; if not, write to the Free Software
19 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
20 */
21
22 /**
23 * @file
24 * principal component analysis (PCA)
25 */
26
29
37
40 if(n<=0)
42
44 if (!pca)
46
52
56 }
57
58 return pca;
59 }
60
66 }
67
71
76 }
78 }
79
80 int ff_pca(
PCA *pca,
double *eigenvector,
double *eigenvalue){
82 int k=0;
85
86 memset(eigenvector, 0, sizeof(double)*n*n);
87
88 for(j=0; j<n; j++){
90 eigenvector[j + j*n] = 1.0;
95 }
97 z[j]= 0;
98 }
99
101 double sum=0;
102
106
107 if(sum == 0){
109 double maxvalue= -1;
111 if(eigenvalue[j] > maxvalue){
112 maxvalue= eigenvalue[j];
113 k= j;
114 }
115 }
116 eigenvalue[k]= eigenvalue[
i];
117 eigenvalue[
i]= maxvalue;
118 for(j=0; j<n; j++){
119 double tmp= eigenvector[k + j*n];
120 eigenvector[k + j*n]= eigenvector[
i + j*n];
121 eigenvector[
i + j*n]=
tmp;
122 }
123 }
125 }
126
128 for(j=
i+1; j<n; j++){
130 double t,
c,
s,tau,theta,
h;
131
132 if(
pass < 3 &&
fabs(covar) < sum / (5*n*n))
//FIXME why pass < 3
133 continue;
134 if(
fabs(covar) == 0.0)
//FIXME should not be needed
135 continue;
136 if(
pass >=3 &&
fabs((eigenvalue[j]+z[j])/covar) > (1LL<<32) &&
fabs((eigenvalue[
i]+z[
i])/covar) > (1LL<<32)){
138 continue;
139 }
140
141 h= (eigenvalue[j]+z[j]) - (eigenvalue[
i]+z[
i]);
143 t=1.0/(
fabs(theta)+sqrt(1.0+theta*theta));
144 if(theta < 0.0) t = -t;
145
150 z[j] += t*covar;
151
152 #define ROTATE(a,i,j,k,l) {\
153 double g=a[j + i*n];\
154 double h=a[l + k*n];\
155 a[j + i*n]=g-s*(h+g*tau);\
156 a[l + k*n]=h+s*(g-h*tau); }
157 for(k=0; k<n; k++) {
160 }
162 }
164 }
165 }
166 for (
i=0;
i<n;
i++) {
167 eigenvalue[
i] += z[
i];
169 }
170 }
171
172 return -1;
173 }