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

svd算法

发布时间:2022-01-18 07:22:04

❶ 请问matlab中svd的算法是什么 propack中求解svd的命令lansvd的算法是什么 二者的优劣比较傲~~

哈哈,我也在做LJ数值分析大作业。。提示你用help和type命令~

❷ 用MATLAB计算这个矩阵的SVD,怎样操作

以matlab7.1为例,
在command中
>> a=0;

后用数据编辑器打开,把Excel中的数据过来,直接粘贴就行.
再在command中
>> [U V D]= svd( a )

至于U V D:(假设a 为m*n 的矩阵),则
U ,m*m的酉矩阵
D ,n*n的酉矩阵
V ,m*n的矩阵

a = U*V*D 即为奇异值分解..

更详细的说明,请看矩阵分析的相关资料.....

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

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

❹ svd数据点计算完成后如何计算相似度

首先根据Bob=[-0.3775,0.0802],用cosin算法计算出与Bob最相似的用户,假如最后Jorbe与Bob最
相似,Jorbe的评分数据为 [5 4 5 0 4 5],,由Jorbe 的评分数据可以看出,他只有第4项数据没有评
分,而Bob有第3、4、5项数据没有评分,所以就可以根据Jorbe的评分数据来预测Bob的评分数
据,这里就可以预测Bob的第3、5项评分数据为5、4。

❺ 求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;
}


❻ 高维稀疏矩阵都有哪些分解算法,例如svd,nmf

假设有:
这是一个5×5的单位满矩阵和相应的稀疏矩阵.
(a) C = 5*B,结果为:
这是一个稀疏矩阵.
(b) D = A + B,给出的结果为:
这是一个满矩阵.
(c) x = B \ h,结果为:
这是一个满向量.

❼ Matlab 的 svd 是怎么实现的

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

❽ 关于SVD计算问题

...............你发个帖子啊,上网络贴吧发,不一会儿就有很多人回答你了。。。。偶初中,不太懂,你发贴吧上的话如果帖子红了,你就出名了,还能回答出来,你说是不是???告诉你这么好的方法不给分的话你真是没人性了。。。。还有请问这是CSOL的吗???SVD...........狙击枪威力95%。。。。在屏幕中间点个点,冲上去杀人

❾ SVD分解为什么是最好的QR分解和SVD比较LU呢SVD并行算法可行么

鉴于矩阵的奇异值分解SVD在工程领域的广泛应用(如数据压缩、噪声去除、数值分析等等,包括在NLP领域的潜在语义索引LSI核心操作也是SVD),今天就详细介绍一种SVD的实现方法--Jacobi旋转法。跟其它SVD算法相比,Jacobi法精度高,虽然速度慢,但容易并行实现。
基于双边Jacobi旋转的奇异值分解算法

V是A的右奇异向量,也是的特征向量;

U是A的左奇异向量,也是的特征向量。

特别地,当A是对称矩阵的时候,=,即U=V,U的列向量不仅是的特征向量,也是A的特征向量。这一点在主成分分析中会用到。

对于正定的对称矩阵,奇异值等于特征值,奇异向量等于特征向量。

U、V都是正交矩阵,满足矩阵的转置即为矩阵的逆。

双边Jacobi方法本来是用来求解对称矩阵的特征值和特征向量的,由于就是对称矩阵,求出的特征向量就求出了A的右奇异值,的特征值开方后就是A的奇异值。

一个Jacobi旋转矩阵J形如:

它就是在一个单位矩阵的基础上改变p行q行p列q列四个交点上的值,J矩阵是一个标准正交矩阵。

当我们要对H和p列和q列进行正交变换时,就对H施行:

在一次迭代过程当中需要对A的任意两列进行一次正交变换,迭代多次等效于施行

迭代的终止条件是为对角矩阵,即原矩阵H进过多次的双边Jacobi旋转后非对角线元素全部变成了0(实现计算当中不可能真的变为0,只要小于一个很小的数就可以认为是0了)。

每一个J都是标准正交阵,所以也是标准正交阵,记为V,则是,则。从此式也可以看出对称矩阵的左奇异向量和右奇异向量是相等的。V也是H的特征向量。

当特征值是0时,对应的Ui和Vi不用求,我们只需要U和V的前r列就可以恢复矩阵A了(r是非0奇异值的个数),这也正是奇异值分解可以进行数据压缩的原因。

+ View Code
基于单边Jacobi旋转的SVD算法

相对于双边,单边的计算量小,并且容易并行实现。

单边Jacobi方法直接对原矩阵A进行单边正交旋转,A可以是任意矩阵。

同样每一轮的迭代都要使A的任意两列都正交一次,迭代退出的条件是B的任意两列都正交。

单边Jacobi旋转有这么一个性质:旋转前若,则旋转后依然是;反之亦然。

把矩阵B每列的模长提取出来,,把记为V,则。

+ View Code
基于单边Jacobi旋转的SVD并行算法

单边Jacobi之于双边Jacobi的一个不同就是每次旋转只影响到矩阵A的两列,因经很多列对的正交旋转变换是可以并行执行的。

基本思想是将A按列分块,每一块分配到一个计算节点上,块内任意两列之间进行单边Jacobi正交变换,所有的计算节点可以同时进行。问题就是矩阵块内部列与列之间进行正交变换是不够的,我们需要所有矩阵块上的任意两列之间都进行正交变换,这就需要计算节点之间交换矩阵的列。本文采用奇偶序列的方法
由于这次我用的是C版的MPI(MPI也有C++和Fortan版的),所以上面代码用到的C++版的matrix.h就不能用了,需要自己写一个C版的matrix.h。

matrix.h

+ View Code
svd.c

+ View Code

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

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

阅读全文

与svd算法相关的资料

热点内容
工作三年的大专程序员 浏览:728
java毕业设计文献 浏览:143
筹码集中度指标源码 浏览:482
listsortjava 浏览:186
plc闪光电路编程实例 浏览:299
socket编程试题 浏览:206
华为的服务器怎么设置从光驱启动 浏览:871
程序员真的累吗 浏览:328
学信网app为什么刷脸不了 浏览:874
天蝎vs程序员 浏览:996
单片机下载口叫什么 浏览:190
程序员的道 浏览:926
云服务器不实名违法吗 浏览:558
怎样查看文件夹图片是否重复 浏览:995
文件怎么导成pdf文件 浏览:808
打开sql表的命令 浏览:103
安卓手机如何面部支付 浏览:38
天元数学app为什么登录不上去 浏览:825
明日之后为什么有些服务器是四个字 浏览:104
安卓系统l1是什么意思 浏览:26