/** C++ function for SVD
站在用戶的角度思考問題,與客戶深入溝通,找到如皋網(wǎng)站設(shè)計與如皋網(wǎng)站推廣的解決方案,憑借多年的經(jīng)驗,讓設(shè)計與互聯(lián)網(wǎng)技術(shù)結(jié)合,創(chuàng)造個性化、用戶體驗好的作品,建站類型包括:成都網(wǎng)站建設(shè)、網(wǎng)站制作、企業(yè)官網(wǎng)、英文網(wǎng)站、手機端網(wǎng)站、網(wǎng)站推廣、空間域名、虛擬主機、企業(yè)郵箱。業(yè)務(wù)覆蓋如皋地區(qū)。
函數(shù)原型:
bool svd(vectorvectordouble A, int K, std::vectorstd::vectordouble U, std::vectordouble S, std::vectorstd::vectordouble V);
其中
A是輸入矩陣,假設(shè)A的維數(shù)是m*n,那么本函數(shù)將A分解為U diag(S) V'
其中U是m*K的列正交的矩陣. V是n*K的列正交矩陣,S是K維向量。K由第二個參數(shù)指定。
U的第i列是A的第i大奇異值對應(yīng)的左歧義向量,S[i]=A的第 i大奇異值,V的第i列是A的第i大奇異值對應(yīng)的右歧義響亮.
K是需要分解的rank,0K=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;in;i++)
r+=x[i]*x[i];
return sqrt(r);
}
double normalize(double *x, int n){
double r=get_norm(x,n);
if(reps)
return 0;
for(int i=0;in;i++)
x[i]/=r;
return r;
}
inline double product(double*a, double *b,int n){
double r=0;
for(int i=0;in;i++)
r+=a[i]*b[i];
return r;
}
void orth(double *a, double *b, int n){//|a|=1
double r=product(a,b,n);
for(int i=0;in;i++)
b[i]-=r*a[i];
}
bool svd(vectorvectordouble A, int K, std::vectorstd::vectordouble U, std::vectordouble S, std::vectorstd::vectordouble 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;iK;i++)
U[i].resize(M,0);
V.resize(K);
for(int i=0;iK;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;iM;i++)
?left_vector[i]= (float)rand() / RAND_MAX;
if(normalize(left_vector, M)eps)
?break;
}
int col=0;
for(int col=0;colK;col++){
double diff=1;
double r=-1;
for(int iter=0;diff=eps iterMAX_ITER;iter++){
?memset(next_left_vector,0,sizeof(double)*M);
?memset(next_right_vector,0,sizeof(double)*N);
?for(int i=0;iM;i++)
??? ?for(int j=0;jN;j++)
??? ??? ?next_right_vector[j]+=left_vector[i]*A[i][j];
?r=normalize(next_right_vector,N);
?if(reps) break;
?for(int i=0;icol;i++)
??? ?orth(V[i][0],next_right_vector,N);
?normalize(next_right_vector,N);
?for(int i=0;iM;i++)
??? ?for(int j=0;jN;j++)
??? ??? ?next_left_vector[i]+=next_right_vector[j]*A[i][j];
?r=normalize(next_left_vector,M);
?if(reps) break;
?for(int i=0;icol;i++)
??? ?orth(U[i][0],next_left_vector,M);
?normalize(next_left_vector,M);
?diff=0;
?for(int i=0;iM;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(vectorvectordouble A){
for(int i=0;iA.size();i++){
for(int j=0;jA[i].size();j++){
?coutsetprecision(3)A[i][j]' ';
}
coutendl;
}
}
int main(){
int m=10;
int n=5;
srand(time(0));
vectorvectordouble A;
A.resize(m);
for(int i=0;im;i++){
A[i].resize(n);
for(int j=0;jn;j++)
?A[i][j]=(float)rand()/RAND_MAX;
}
print(A);
coutendl;
vectorvectordouble U;
vectordouble S;
vectorvectordouble V;
svd(A,2,U,S,V);
cout"U="endl;
print(U);
coutendl;
cout"S="endl;
for(int i=0;iS.size();i++){
coutS[i]' ';
}
coutendl;
cout"V="endl;
print(V);
return 0;
}
數(shù)據(jù)挖掘比賽算法
examples/src/main/java/org/apache/mahout/cf/taste/example/kddcup/track1/svd
推薦系統(tǒng)中利用SVD實現(xiàn)降維
core/src/main/java/org/apache/mahout/cf/taste/impl/recommender/svd
String?getStr(String?str)?{
if?(str.length()?=?2)?{
return?str;
}
return?str.substring(0,?2)?+?"#"?+?getStr(str.substring(2));
}
不要太簡單
SVD相當于:
C為mxn階矩陣,U為mxm階酉矩陣,E為mxn階實數(shù)對角矩陣,V為nxn階酉矩陣。
E矩陣對角線上的元素等于C的奇異值。
在OpenCV中可以用
solve(InputArray?src1, InputArray?src2, OutputArray?dst, intflags=DECOMP_SVD)
你是不是要用SVD求解最小二乘問題?
線性方程組Cx=b,求其最小二乘解。
你可以先求出C的偽逆C+。
C+=V(E+)(UT)
(E+)是E的偽逆,將E主對角線上每個非零元素都求倒數(shù)之后再轉(zhuǎn)置得到.
(UT)是U的轉(zhuǎn)置。
最后計算出最小二乘解為:(C+)b
名稱欄目:svdjava代碼 SVD代碼
本文地址:http://m.newbst.com/article16/hpdodg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站改版、域名注冊、品牌網(wǎng)站建設(shè)、微信公眾號、靜態(tài)網(wǎng)站、服務(wù)器托管
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)