implementación del lenguaje c de descomposición svd
/*
Este programa está compilado bajo linux g
bool svd(vectorlt; vectorlt; doublet; gt; A, int K, vectorlt; vectorlt; doublegt; gt; vectorlt; doublegt; amp; vectorlt; doublegt; K: Entrada, tome los primeros K valores singulares grandes y vectores singulares
U[0], U[1],..., U[K-1]: correspondientes a los primeros K grandes valores singulares Vector singular izquierdo
S[0], S[1],..., S[K-1]: los primeros K valores singulares grandes S[0]gt;=S[ 1]gt; =... gt; =S[K-1]
V[0], V[1],..., V[K-1]: corresponde a la primera K valores singulares grandes El vector singular derecho de
*/
#include lt;cmathgt;
#include lt;iostreamgt;
#include lt; iomanipgt;
#include lt;iomanipgt;
# include lt;cstdlibgt;
#include lt;cstringgt;
#include lt;fstreamgt;
#include lt;vectorgt;
usando el espacio de nombres std;
const int MAX_ITER=100000;
const doble eps=0.0000001;
doble get_norm(doble *x, int n){
doble r=0; 0; ilt; n; i) ?r =x[i]*x[i];
retorno sqrt(r);
}
doble normalizar(doble * x, int n){
doble r= get_norm(x, n);
if(rlt;eps) ?return 0;
for(int i=0; ilt; n; i ) ?x[i]/=r;
Retornar
}
inline double producto(doble* a, doble *b, int n){
doble r=0;
for(int i=0; ilt; n; i) ?r =a [i]* b[i];
return r;
}
void orth(doble *a, doble *b, int n){/ /||a |=1
double r=producto(a, b, n);
for(int i=0; ilt; n; i) ?b[i ]-=r *a[i];
}
bool svd(vectorlt; vectorlt; doblete; gt; A, int
K, vectorlt; vectorlt; gt; , 0);
U.resize(K);
for(int i=0; ilt; K; i ) ?U[i].resize(M, 0) ;
V.resize(K);
for(int i=0;i lt;K;i) ?V[i].resize(N, 0);
srand(time(0));
doble *left_vector=nuevo doble[M]
doble *next_left_vector =nuevo; doble[M];
doble *right_vector=nuevo doble[N];
doble *next_right_vector=nuevo doble[N];
int col=0 ;
for(int col=0; collt; K; col ){ ?double diff=1; ?double r=-1; while(1){ ?for(int i=0; ilt; ;M;i) ?left_vector[i]= (float)rand() / RAND_MAX; ?if(normalize(left_vector, M)gt;eps) ?break; amp; amp; iterlt; MAX_ITER; iter ){ ?memset(next_left_vector, 0, tamaño de (doble)*M); ?memset(next_right_vector, 0, tamaño de (doble)*N); ;M;i) ?for(int j=0;jlt;N;j) ?next_right_vector[j] =left_vector [i]*A[i][j]; ?r=normalize(next_right_vector,N); (rlt;eps) romper; ?for(int i=0;ilt;col;i) ?orth(amp;V[i][0],next_right_vector,N); int i=0;ilt;M;i) ?for(int j=0;jlt;N;j) ?next_left_vector[i] =next_right_vector[j]*A[i][j]; , M); ?if(rlt; eps) break; ?for(int i=0; ilt; col; i) ?orth( amp; U[i][0], next_left_vector, M); M); ?diff=0; ?para(int i=0; ilt; M; i ){ ?
double d=next_left_vector[i]-left_vector[i]; ?diff =d*d; ?} ?memcpy(siguiente_vector_izquierdo, sizeof(double)*M); ); ((char *)amp; V[col][0], vector_derecho, tamañode(doble)*N ?}
}
eliminar [] next_left_vector;
eliminar [] next_right_vector;
eliminar [] left_vector
eliminar [] right_vector;
devuelve verdadero;
}
void print(vectorlt; vectorlt; doublet; gt; amp; A){
}
int main(){
int m=10;
int n=8
int k=5; >
/Descomponga una matriz A de 10*8 y encuentre sus primeros 5 valores singulares y vectores singulares
srand(time(0));
vectorlt; vectorlt; doblete; gt;
A.resize(m); m;i ){ ?A[i].resize(n); ?for(int j=0;jlt;n;j ) ?A[i][j]=(float)rand()/RAND_MAX- 0.5;
}
coutlt;lt; "A="lt;lt;endl;
for(int i=0 ; ilt;A.size();i ){ ?for(int j=0;jlt;A[i].size();j ){ ?coutlt;lt;setw(12)lt;lt;A[i ] [j]lt;lt;' '; ?} ?coutlt;lt;endl;
}
coutlt;lt;endl;
vectorlt; vectorlt; gt;
vectorlt;
vectorlt; , U, S, V);
coutlt;lt; "U="lt;lt;endl;
for(int i=0;ilt;U[0] . tamaño(); i ){ ?para(int j=0; jlt; U.size(); j ){ ?coutlt;
lt;setw(12)lt;lt;U[j][i]lt;lt;' ?} ?coutlt;lt;endl;
}
coutlt ;lt;endl;
coutlt;lt;lt;lt;endl;
coutlt;lt;lt;endl;
for(int i=0 ;ilt;S.size();i ){ ?coutlt;lt;setw(7)lt;lt;S[i]lt;lt;';
}
coutlt;lt;endl;
coutlt;lt;lt; "V="lt;lt;endl;
for(int i=0.ilt;V[0] .size();i ){ ?for(int j=0;jlt;V.size();j ){ ?coutlt;lt;setw(12)lt;lt;V[j][i]lt;lt ;lt;''; ?} ??coutlt;lt;endl;
}
Devuelve 0;
} ?