导航:首页 > 源码编译 > svd算法实现

svd算法实现

发布时间:2022-06-02 19:23:08

A. 怎么在推荐系统中使用svd算法

SVD算法 SVD算法可用来求解大多数的线性最小二乘法问题. SVD 算法基于如下分解定理:对任 意的矩阵 Am ×n ,当其行数 m 大于等于列数 n 时,可以分解为正交矩阵 Um ×n , 非负对角矩阵 Wn×n以及正交矩阵Vn×n的转置的乘积,即 Am×n = Um×n ·[diag(

B. 关于MATLAB中稀疏表示的K-SVD算法的疑问,跪求各位大神指点,感激不尽,详细内容见问题补充

字典都是小数是因为里面每个列都经过了normalization,L2 norm都是1
如果要得到稀疏系数,试试OMPerr

C. Matlab中求解矩阵(不一定是方阵)的算法有哪些

iug uhg hkj;

D. Matlab 的 svd 是怎么实现的

在MATLAB里打开svd的源码可以看到只有一堆注释,最后写的是该函数为built-in function。事实上,MATLAB的矩阵计算使用的是Intel的MKL库,这个库基本是现有BLAS/LAPACK实现中最快的了。svd是LAPACK中的标准运算,因此MATLAB实际是使用的MKL库来做svd。
MKL作为一个商业库,其算法细节和代码是不公开的,而且业界对于这种基本算法必然会有非常独到的优化,涉及到大量细节(算法本身的细节,以及代码层次的细节)。svd的经典算法有Golub-Kahan算法、分治法、Jacobi法几种,我推测MKL具体实现的是分治法。

E. 求SVD算法的C++实现代码

/** C++ function for SVD
函数原型:
bool svd(vector<vector<double> > A, int K, std::vector<std::vector<double> > &U, std::vector<double> &S, std::vector<std::vector<double> > &V);
其中
A是输入矩阵,假设A的维数是m*n,那么本函数将A分解为U diag(S) V'
其中U是m*K的列正交的矩阵. V是n*K的列正交矩阵,S是K维向量。K由第二个参数指定。
U的第i列是A的第i大奇异值对应的左歧义向量,S[i]=A的第 i大奇异值,V的第i列是A的第i大奇异值对应的右歧义响亮.
K是需要分解的rank,0<K<=min(m,n)

本程序采用的是最基本幂迭代算法,在linux g++下编译通过
**/


#include <cmath>
#include <iostream>
#include <iomanip>
#include <cstdlib>
#include <cstring>
#include <fstream>
#include <vector>
using namespace std;
const int MAX_ITER=100000;
const double eps=0.0000001;

double get_norm(double *x, int n){
double r=0;
for(int i=0;i<n;i++)
r+=x[i]*x[i];
return sqrt(r);
}
double normalize(double *x, int n){
double r=get_norm(x,n);
if(r<eps)
return 0;
for(int i=0;i<n;i++)
x[i]/=r;
return r;
}

inline double proct(double*a, double *b,int n){
double r=0;
for(int i=0;i<n;i++)
r+=a[i]*b[i];
return r;
}
void orth(double *a, double *b, int n){//|a|=1
double r=proct(a,b,n);
for(int i=0;i<n;i++)
b[i]-=r*a[i];

}


bool svd(vector<vector<double> > A, int K, std::vector<std::vector<double> > &U, std::vector<double> &S, std::vector<std::vector<double> > &V){
int M=A.size();
int N=A[0].size();
U.clear();
V.clear();
S.clear();
S.resize(K,0);
U.resize(K);
for(int i=0;i<K;i++)
U[i].resize(M,0);
V.resize(K);
for(int i=0;i<K;i++)
V[i].resize(N,0);


srand(time(0));
double *left_vector=new double[M];
double *next_left_vector=new double[M];
double *right_vector=new double[N];
double *next_right_vector=new double[N];
while(1){
for(int i=0;i<M;i++)
left_vector[i]= (float)rand() / RAND_MAX;
if(normalize(left_vector, M)>eps)
break;
}
int col=0;
for(int col=0;col<K;col++){
double diff=1;
double r=-1;
for(int iter=0;diff>=eps && iter<MAX_ITER;iter++){
memset(next_left_vector,0,sizeof(double)*M);
memset(next_right_vector,0,sizeof(double)*N);
for(int i=0;i<M;i++)
for(int j=0;j<N;j++)
next_right_vector[j]+=left_vector[i]*A[i][j];

r=normalize(next_right_vector,N);
if(r<eps) break;
for(int i=0;i<col;i++)
orth(&V[i][0],next_right_vector,N);
normalize(next_right_vector,N);

for(int i=0;i<M;i++)
for(int j=0;j<N;j++)
next_left_vector[i]+=next_right_vector[j]*A[i][j];
r=normalize(next_left_vector,M);
if(r<eps) break;
for(int i=0;i<col;i++)
orth(&U[i][0],next_left_vector,M);
normalize(next_left_vector,M);
diff=0;
for(int i=0;i<M;i++){
double d=next_left_vector[i]-left_vector[i];
diff+=d*d;
}

memcpy(left_vector,next_left_vector,sizeof(double)*M);
memcpy(right_vector,next_right_vector,sizeof(double)*N);
}
if(r>=eps){
S[col]=r;
memcpy((char *)&U[col][0],left_vector,sizeof(double)*M);
memcpy((char *)&V[col][0],right_vector,sizeof(double)*N);
}else
break;
}
delete [] next_left_vector;
delete [] next_right_vector;
delete [] left_vector;
delete [] right_vector;

return true;
}

void print(vector<vector<double> > &A){
for(int i=0;i<A.size();i++){
for(int j=0;j<A[i].size();j++){
cout<<setprecision(3)<<A[i][j]<<' ';
}
cout<<endl;
}
}
int main(){
int m=10;
int n=5;
srand(time(0));
vector<vector<double> > A;
A.resize(m);

for(int i=0;i<m;i++){
A[i].resize(n);
for(int j=0;j<n;j++)
A[i][j]=(float)rand()/RAND_MAX;
}
print(A);
cout<<endl;

vector<vector<double> > U;
vector<double> S;
vector<vector<double> > V;
svd(A,2,U,S,V);
cout<<"U="<<endl;
print(U);
cout<<endl;
cout<<"S="<<endl;
for(int i=0;i<S.size();i++){
cout<<S[i]<<' ';
}
cout<<endl;
cout<<"V="<<endl;
print(V);
return 0;
}


F. 怎么样用matlab的svd算法处理一个稀疏矩阵

确实有点大的 两个指定顶点之间的最短路径 问题如下:给出了一个连接若干个城镇的铁路网络,在这个网络的两个指定城镇间,找一条最短铁路线。 以各城镇为图G的顶点,两城镇间的直通铁路为图G相应两顶点间的边,得图G。对 G的每一边e...

阅读全文

与svd算法实现相关的资料

热点内容
floyd最短路径算法c 浏览:382
新湖app在哪里下载 浏览:703
计算机图形学涉及的算法 浏览:369
阿里云linux一键web 浏览:25
弹性云服务器注册 浏览:169
垃圾程序员写出垃圾代码 浏览:760
帝国时代java下载 浏览:51
数据结构的经典算法题 浏览:194
逍遥安卓多开管理器是干什么的 浏览:914
程序员收玉米一天多少钱 浏览:355
程序员很可爱根据哪本小说改编的 浏览:984
游戏旧版安卓怎么玩 浏览:263
冗余单片机 浏览:849
cad抽壳命令怎么用 浏览:29
服务器第一地址怎么改 浏览:498
单片机最小系统电路设计流程图 浏览:669
steam源码 浏览:35
关于对数的运算法则及公式 浏览:781
明星谈如何缓解压力 浏览:147
androidlistview隐藏列 浏览:402