❶ 請問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(