本文主要是介绍SVM-SMO算法C++实现,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
SMO程序
#include <iostream>
#include <stdlib.h>
#include <string>
#include <math.h>
#include "matrix.h"
#include <fstream>
#include <sstream>
#include <stack>
using namespace std;
#define MAX_SIZE_OF_TRAINING_SET 100
#define MAX_NUMIT 100
#define MAX 1000000
#define MIN -100000
//SMO参数结构体
struct OS
{Matrix x;Matrix y;double C;double soft;int m;Matrix alphas;double b;Matrix eCache;Matrix kernel;bool k;
};
//核函数的结构体
struct kTup
{int type;//0,1double arg;
};
class SMOP
{//非常值得注意的是svm中训练样本按列排列,即每一列是一个样本,所以导致w是行向量
public:OS os;
public:/**根据参数,来生成不同的核函数*/Matrix kernelTran(Matrix x,Matrix xOneCol,kTup ktup){Matrix K;K.initMatrix(&K,x.col,1);Matrix xOneColT;xOneColT.initMatrix(&xOneColT,xOneCol.row,xOneCol.col);xOneColT.transposematrix(xOneCol,&xOneColT);if(ktup.type==1){K.multsmatrix(&K,x,xOneColT);}if(ktup.type==2){//高斯核}return K;}/**结构体OS的初始化,用于保存所以SMO算法中需要用到的参数*/int initOs(Matrix x,Matrix y,double C,double soft,kTup ktup){os.x.initMatrix(&os.x,x.col,x.row);os.x.copy(x,&os.x);os.y.initMatrix(&os.y,y.col,y.row);os.y.copy(y,&os.y);os.eCache.initMatrix(&os.eCache,x.col,2);os.alphas.initMatrix(&os.alphas,x.col,1);os.b=0;os.C=C;os.m=x.col;os.kernel.initMatrix(&os.kernel,os.m,os.m);os.soft=soft;if(ktup.type!=0){int i=0,j=0;Matrix xOneCol;xOneCol.initMatrix(&xOneCol,1,os.x.row);Matrix kOneRow;kOneRow.initMatrix(&kOneRow,os.m,1);cout<<"-----------"<<endl;for(i=0; i<os.m; i++){xOneCol=xOneCol.getOneCol(x,i);kOneRow=kernelTran(x,xOneCol,ktup);for(j=0; j<os.m; j++)os.kernel.mat[j][i]=kOneRow.mat[j][0];}os.k=true;return 0;}os.k=false;return 0;}/**上下限剪辑函数*/double clipAlpha(double alpha,double L,double H){if(alpha>H)return H;if(alpha<L)return L;return alpha;}/**误差值的计算也是根据数学表达式来实现的**/double calcEk(int k){Matrix ay;ay.initMatrix(&ay,os.x.col,1);int i;for(i=0; i<os.m; i++){ay.mat[i][0]=os.alphas.mat[i][0]*os.y.mat[i][0];}Matrix ayT;ayT.initMatrix(&ayT,ay.row,ay.col);ayT.transposematrix(ay,&ayT);Matrix f;f.initMatrix(&f,1,1);if(!os.k){Matrix ayTx;ayTx.initMatrix(&ayTx,ayT.col,os.x.row);ayTx.multsmatrix(&ayTx,ayT,os.x);Matrix xOneCol;xOneCol.initMatrix(&xOneCol,1,os.x.row);xOneCol=xOneCol.getOneCol(os.x,k);Matrix xOneColT;xOneColT.initMatrix(&xOneColT,xOneCol.row,xOneCol.col);xOneColT.transposematrix(xOneCol,&xOneColT);f.multsmatrix(&f,ayTx,xOneColT);//值得商榷}else{Matrix kOneRow;kOneRow.initMatrix(&kOneRow,os.m,1);kOneRow=kOneRow.getOneRow(os.kernel,k);f.multsmatrix(&f,ayT,kOneRow);//值得商榷}double fXK=f.mat[0][0]+os.b-os.y.mat[k][0];return fXK;}///更新误差矩阵void updataEk(int k){double Ek;Ek=calcEk(k);//计算误差值os.eCache.mat[k][0]=1;os.eCache.mat[k][1]=Ek;}/**对于第二个alpha的选择采用Ei-Ej的大小进行衡量,同时这里引用一个矩阵来保存不变的E,减少计算量选择出合适第二个alpha2,对于第一次进来,保存误差值E的矩阵必然没有一个有效的,所以采用随机策略随机选择策略其实可以任意选择,具体没有实现,而是采用等价方式实现,但需要注意数据越界问题**/int selectJ(int i,double Ei){int maxK=-1;double Ek;double Ej;double deltaE;double maxDeltaE=0;int k;for(k=0; k<os.alphas.col; k++){if(os.eCache.mat[k][0]==1&&k!=i){Ek=calcEk(k);deltaE=abs(Ei-Ek);if(deltaE>maxDeltaE){maxK=k;maxDeltaE=deltaE;Ej=Ek;}}//随机选择一个j, 理论上只有第一次时所有的ek都没计算过,所以任选一个即可if(maxK==-1){maxK=(i*2+1)%100;Ej=calcEk(maxK);}}return maxK;}/**内层循环实现两个alpha的优化,由外层循环函数提供alpha1的可选集合(所有样本或者是支持向量),遍历集合上的每一个alpha,对其进行判断是否违反KKT条件,如果违反则选为第一个alpha1,同样调用selctJ函数来启发式选择使得alpha1改变最大的alpha2,选择出合适ij之后,还得根据当前alpha1和alpha2来确定优化的上下限。然后通过迭代公式,来计算alpha1和alpha2,计算的时候判断是否采用核方法。并对计算结果进行上下限剪辑,最终确定优化后的alpha1和alpha2,同时对当前优化后结果对b也进行修改考虑到每一次选择第二个alpha2时,都需要比较一个误差值,而这个误差值在每次优化过程中都只有对应修改alpha的误差值有变化而其他的是不变的,所以用一个矩阵来保存有效的误差值。*/int innerL(int i){double Ei;double Ej;int j;double alphaIOld;double alphaJOld;double L;double H;double eta;int n;double temp[3];//ii,jj,ijdouble b1,b2;if(os.y.mat[i][0]*(Ei-os.y.mat[i][0]*os.soft)<0&&os.alphas.mat[i][0]<os.C||os.y.mat[i][0]*(Ei-os.y.mat[i][0]*os.soft)>0&&os.alphas.mat[i][0]>0){Ei=calcEk(i);j=selectJ(i,Ei);Ej=calcEk(j);alphaIOld=os.alphas.mat[i][0];alphaJOld=os.alphas.mat[j][0];if(os.y.mat[i][0]!=os.y.mat[j][0]){L=max(0.0,os.alphas.mat[j][0]-os.alphas.mat[i][0]);H=min(os.C,os.alphas.mat[j][0]-os.alphas.mat[i][0]+os.C);}else{L=max(0.0,os.alphas.mat[j][0]+os.alphas.mat[i][0]-os.C);H=min(os.C,os.alphas.mat[j][0]+os.alphas.mat[i][0]);}if(L==H){cout<<"l=h------------------"<<endl;return 0;}if(!os.k){temp[0]=0;temp[1]=0;temp[2]=0;for(n=0; n<os.x.row; n++){temp[0]+=pow(os.x.mat[i][n],2);temp[1]+=pow(os.x.mat[j][n],2);temp[2]+=os.x.mat[i][n]*os.x.mat[j][n];}}else{temp[0]=os.kernel.mat[i][i];temp[1]=os.kernel.mat[j][j];temp[2]=os.kernel.mat[i][j];eta=temp[0]+temp[1]-2*temp[2];}eta=temp[0]+temp[1]-2*temp[2];if(eta<0){cout<<"eta<0-----------------"<<endl;return 0;}os.alphas.mat[j][0]+=os.y.mat[j][0]*(Ei-Ej)/eta;os.alphas.mat[j][0]=clipAlpha(os.alphas.mat[j][0],L,H);//对alpha进行剪辑updataEk(j);//更新误差值if(fabs(os.alphas.mat[j][0]-alphaJOld)<0.000001){cout<<"j not moving enough---------------"<<endl;return 0;}os.alphas.mat[i][0]+=os.y.mat[i][0]*os.y.mat[j][0]*(alphaJOld-os.alphas.mat[j][0]);updataEk(i);//更新误差值b1=os.b-Ei-os.y.mat[i][0]*(os.alphas.mat[i][0]-alphaIOld)*temp[0]-os.alphas.mat[j][0]*(os.alphas.mat[j][0]-alphaJOld)*temp[2];b2=os.b-Ej-os.y.mat[i][0]*(os.alphas.mat[i][0]-alphaIOld)*temp[2]-os.alphas.mat[j][0]*(os.alphas.mat[j][0]-alphaJOld)*temp[1];if(0<os.alphas.mat[i][0]&&os.C>os.alphas.mat[i][0])os.b=b1;else if(0<os.alphas.mat[j][0]&&os.C>os.alphas.mat[j][0])os.b=b2;elseos.b=(b1+b2)/2;return 1;}cout<<"kkt--------------------------"<<endl;return 0;}/**SMO算法的入口函数,其主要功能是初始化SMO所有的参数到结构体OS确定迭代结束标志,并在所有样本和支持向量上循环的选择合适alpha1,调用inner确定alpha1,外层循环每一次是迭代优化一对alpha,内层循环才是正真实现迭代优化一对alpha最后,对smo算法的实现进行检查,通过alpha求解出w,b,并在训练样本上比较其预测值与实际值的差异。该办法只能检查SMO算法实现的正确性,不能检查SVM的性能。*/int smoP(Matrix x,Matrix y,double C,double soft,int maxIter,kTup ktup){int iter=0;int i,j;initOs(x,y,C,soft,ktup);///初始化OS结构体,OS结构体中定义了SMOP算法需要的大部分参数bool entireSet=true;//标志用于判断当前迭代是针对所有alpha,还是针对0-C之间的部分alpha,这里其实第一个alpha的启发式选择,即选择落在支持向量上的点int alphaPairsChanged=0;//该参数判断在确定第一个参数之后,是否能选择出符合要求的第二alpha,返回值为1表示能,0为不能for(iter=0; iter<maxIter&&(alphaPairsChanged>0||entireSet); iter++){//循环结束标志为迭代次数已到预设值,或者是不能再继续优化(对于所有的支持向量上的点都找不到第二个alpha对第一个alpha进行优化后,重新再遍历所有的点寻找可优化的参数对)//还是找不到则再次遍历支持向量上的点,这次必然也是找不到,才结束迭代alphaPairsChanged=0;if(entireSet){for(i=0; i<os.m; i++){alphaPairsChanged+=innerL(i);cout<<"iter="<<iter<<" i="<<i<<" alphachanged="<<alphaPairsChanged<<endl;}iter++;}else{for(i=0; i<os.m; i++){if(os.alphas.mat[i][0]>0&&os.alphas.mat[i][0]<os.C)//只选择支持向量上的点continue;alphaPairsChanged+=innerL(i);cout<<"iter="<<iter<<" i="<<i<<" alphachanged="<<alphaPairsChanged<<endl;}iter++;}if(entireSet)entireSet=false;else if(alphaPairsChanged==0)entireSet=true;}///对SMO算法实现的正确性进行验证,输出预测值与实际值的差别,全为0表示在训练样本上预测全对Matrix ay;ay.initMatrix(&ay,os.x.col,1);for(i=0; i<os.m; i++){ay.mat[i][0]=os.alphas.mat[i][0]*os.y.mat[i][0];}Matrix xT;xT.initMatrix(&xT,os.x.row,os.x.col);xT.transposematrix(x,&xT);Matrix w;w.initMatrix(&w,os.x.row,1);w.multsmatrix(&w,xT,ay);Matrix label;label.initMatrix(&label,os.x.col,1);label.multsmatrix(&label,os.x,w);cout<<os.b<<" ";for(i=0; i<os.x.row; i++){cout<<w.mat[i][0]<<" ";}cout<<endl;///验证训练样本数据,验证SVM实现的正确性for(i=0; i<os.m; i++){if((label.mat[i][0]+os.b)>0)cout<<1-os.y.mat[i][0]<<endl;elsecout<<-1-os.y.mat[i][0]<<endl;}return 0;}};
int main()
{///加载数据文件保存到对象dtm的矩阵元素中dataToMatrix dtm;char file[20]="data\\svm.txt";dtm.loadData(&dtm,file);///通过矩阵对象中的load函数初始化样本的特征和类别矩阵x,yMatrix x;x.loadMatrix(&x,dtm);Matrix y;y.initMatrix(&y,x.col,1);y=y.getOneRow(x,x.row);x.deleteOneRow(&x,x.row);///调用SMO函数求解SVM模型cout<<"SVM"<<endl;SMOP smop;kTup ktup;//核函数的定义,其中type元素为0表示不适用核函数,非0分别对应不同的核函数ktup.type=1;ktup.arg=1.0;smop.smoP(x,y,0.6,0.001,40,ktup);//return 0;
}
loadData程序
#include <iostream>
#include <stdlib.h>
#include <string>
#include <math.h>
#include <fstream>
#include <sstream>
#include <stack>
#include <string>
using namespace std;
#define MAX_SIZE_OF_TRAINING_SET 100
#define MAX_NUMIT 100
#define ATTR_NUM 3
#define MAX 1000000
#define MIN -100000
#define MAX_MATRIX_COL 1000
#define MAX_MATRIX_ROW 100
struct Data
{int id;double attr_double[ATTR_NUM];//用于数值型属性string attr_string[ATTR_NUM];//用于数值型属性double weight;Data *next;
};
class dataToMatrix
{
public:Data *dataSet;int col;int row;
public:int loadData(dataToMatrix *dtm,char *file){int i=0,j=0;ifstream infile;string tmpstrline;Data *p;dtm->dataSet=new Data;dtm->dataSet->next=NULL;p=dtm->dataSet;Data *datatmp;dtm->col=0;cout<<file<<endl;infile.open(file,ios::in);while(!infile.eof()&&i<MAX_SIZE_OF_TRAINING_SET){getline(infile,tmpstrline,'\n');//读取文件中一行的数据,保存为string类型stringstream input(tmpstrline);if(tmpstrline!="\0")由于读取文件结束符同样会继续该操作{datatmp=new Data;datatmp->id=i;datatmp->next=NULL;j=0;while(input>>datatmp->attr_double[j])j++;p->next=datatmp;p=p->next;dtm->col++;}}dtm->row=j;return 0;}int print(dataToMatrix dtm){//检测数据加载是否正确int i,j;Data *p=dtm.dataSet->next;for(i=0;i<dtm.col&&p!=NULL; i++){for(j=0; j<dtm.row; j++){cout<<p->attr_double[j]<<" ";}p=p->next;cout<<endl;}return i;}
};
Matrix程序
#include <iostream>
#include <stdlib.h>
#include <string>
#include <math.h>
#include "loadData.h"
#include <fstream>
#include <sstream>
#include <stack>
using namespace std;
#define MAX_SIZE_OF_TRAINING_SET 100
#define MAX_NUMIT 100
#define ATTR_NUM 3
#define MAX 1000000
#define MIN -100000
#define MAX_MATRIX_COL 1000
#define MAX_MATRIX_ROW 100
class Matrix
{
public:double **mat;int col,row;
public:int loadMatrix(Matrix *matrix,dataToMatrix dtm){int i,j;Data *p;p=dtm.dataSet->next;matrix->mat=(double **)malloc(sizeof(double*)*dtm.col);if(!matrix->mat){cout<<"loadMatrix fail"<<endl;exit(-1);}for(i=0; i<dtm.col&&p!=NULL; i++){matrix->mat[i]=(double *)malloc(sizeof(double)*dtm.row);if(!matrix->mat[i]){cout<<"loadmatrix fail"<<endl;exit(-1);}for(j=0; j<dtm.row; j++){matrix->mat[i][j]=p->attr_double[j];}p=p->next;}matrix->row=dtm.row;matrix->col=dtm.col;return 0;}int initMatrix(Matrix *matrix,int col,int row){initMatrix(matrix,col,row,0);}int initMatrix(Matrix *matrix,int col,int row,double lam){if(col==0||row==0){cout<<"matrix row or col no can 0"<<endl;exit(-1);}matrix->col=col;matrix->row=row;matrix->mat=(double **)malloc(sizeof(double*)*col);if(!matrix->mat){cout<<"initMatrix fail"<<endl;exit(-1);}int i=0,j=0;for(i=0; i<col; i++){matrix->mat[i]=(double *)malloc(sizeof(double)*row);if(!matrix->mat[i]){cout<<"initMatrix fail"<<endl;exit(-1);}for(j=0; j<row; j++){matrix->mat[i][j]=0;if(i==j)matrix->mat[i][j]=lam;}}return 0;}int print(Matrix matrix){int i,j;for(i=0; i<matrix.col; i++){for(j=0; j<matrix.row; j++){cout<<matrix.mat[i][j]<<" ";}cout<<endl;}}int copy(Matrix matrixA,Matrix *matrixB){if(!matrixB)//还应该考虑a{cout<<"matrixB is null"<<endl;exit(-1);}if(matrixB->col!=matrixA.col||matrixB->row!=matrixA.row){cout<<"matrixA matrixB is no "<<endl;exit(-1);}int i,j;for(i=0; i<matrixA.col; i++){for(j=0; j<matrixA.row; j++){matrixB->mat[i][j]=matrixA.mat[i][j];}}return 0;}Matrix getOneRow(Matrix matrix,int iRow){Matrix oneRow;oneRow.col=matrix.col;oneRow.row=1;initMatrix(&oneRow,oneRow.col,oneRow.row);int i=0;for(i=0; i<oneRow.col; i++){oneRow.mat[i][0]=matrix.mat[i][iRow-1];}return oneRow;}Matrix getOneCol(Matrix matrix,int iCol){Matrix oneCol;oneCol.row=matrix.row;oneCol.col=1;initMatrix(&oneCol,oneCol.col,oneCol.row);int i=0;for(i=0; i<oneCol.row; i++){oneCol.mat[0][i]=matrix.mat[iCol][i];}return oneCol;}int deleteOneRow(Matrix *matrix,int iRow){if(matrix->row==1){cout<<"matrix is vec"<<endl;exit(-1);}int i,j;for(i=iRow; i<matrix->row; i++){for(j=0;j<matrix->col;j++){matrix->mat[j][i]=matrix->mat[j][i+1];}}matrix->row--;return 0;}void transposematrix(Matrix matrix,Matrix *matrixT)//矩阵形式的转置{if(matrixT->col!=matrix.row||matrixT->row!=matrix.col){cout<<"matrix matrixT is no "<<endl;exit(-1);}int i=0,j=0;for(i=0; i<matrixT->col; i++){for(j=0; j<matrixT->row; j++){matrixT->mat[i][j]=matrix.mat[j][i];}}}int addmatrix(Matrix *addMatrix,Matrix matrix1,Matrix matrix2){if(matrix1.col!=matrix2.col||matrix1.row!=matrix2.row||addMatrix->col!=matrix1.col||addMatrix->row!=matrix1.row){cout<<"addMatrix matrix1 matrix2 is no"<<endl;exit(-1);}int i,j;for(i=0; i<matrix1.col; i++){for(j=0; j<matrix1.row; j++){addMatrix->mat[i][j]=matrix1.mat[i][j]+matrix2.mat[i][j];}}return 0;}int submatrix(Matrix *subMatrix,Matrix matrix1,Matrix matrix2){if(matrix1.col!=matrix2.col||matrix1.row!=matrix2.row||subMatrix->col!=matrix1.col||subMatrix->row!=matrix1.row){cout<<"subMatrix matrix1 matrix2 is no"<<endl;exit(-1);}int i,j;subMatrix->col=matrix1.col;subMatrix->row=matrix1.row;for(i=0; i<matrix1.col; i++){for(j=0; j<matrix1.row; j++){subMatrix->mat[i][j]=matrix1.mat[i][j]-matrix2.mat[i][j];}}return 0;}int multsmatrix(Matrix *multsMatrix,Matrix matrix1,Matrix matrix2)//矩阵形式的相乘{if(matrix1.row!=matrix2.col||multsMatrix->col!=matrix1.col||multsMatrix->row!=matrix2.row){cout<<"multsmatrix error"<<endl;exit(-1);}int i,j,k,l;for(i=0; i<matrix1.col; i++){for(j=0; j<matrix2.row; j++){multsMatrix->mat[i][j]=0;}}for(i=0; i<matrix1.col; i++){for(j=0; j<matrix2.row; j++){for(k=0; k<matrix1.row; k++){multsMatrix->mat[i][j]+=matrix1.mat[i][k]*matrix2.mat[k][j];}}}return 0;}//行列式double detmatrix(Matrix matrix){if(matrix.col!=matrix.row){cout<<"matrix det is no"<<endl;exit(-1);}Matrix matrixCopy;matrixCopy.initMatrix(&matrixCopy,matrix.col,matrix.row);matrixCopy.copy(matrix,&matrixCopy);double det=1;int i=0,j,k;double max=MIN;int swap=-1;double temp;double aij[MAX_MATRIX_COL][MAX_MATRIX_ROW];for(k=0; k<matrixCopy.row-1; k++)//k表示第k次消元,一共需要n-1次{for(i=0; i<matrixCopy.col; i++){if(matrixCopy.mat[i][k]>max)//每一次消元都是比较第k列的元素,选出第k列中最大的一行{swap=i;}}//找到第k次列主元消去的最大行的下标if(swap==-1||matrixCopy.mat[swap][k]==0)return -1;//最大主元为0for(j=0; j<matrixCopy.row; j++){temp=matrixCopy.mat[k][j];matrixCopy.mat[k][j]=matrixCopy.mat[swap][j];matrixCopy.mat[swap][j]=temp;}//第k次消元,选出最大的一行是swap行,与第k行交换for(i=k+1; i<matrixCopy.col; i++){aij[i][k]=matrixCopy.mat[i][k]/matrixCopy.mat[k][k];// 第k次消元,主元素为第k行第k列,把第k行以下的行都进行消元for(j=k; j<matrixCopy.row; j++)//对于k行以下的每一行的每一列元素都减去主行与消元因子的乘积{matrixCopy.mat[i][j]-=aij[i][k]*matrixCopy.mat[k][j];}}}for(i=0; i<matrixCopy.col; i++){det*=matrixCopy.mat[i][i];}cout<<"det="<<det<<endl;return det;}//高斯消元矩阵求逆,特别注意,LU分解不能进行行列式变换int nimatrix(Matrix *niMatrix,Matrix matrix){if(matrix.col!=matrix.row){cout<<"matrix ni is no "<<endl;exit(-1);}if(detmatrix(matrix)==0)//这里调用求行列式进行了列主元消去改变了参数矩阵,如何传递不改变是一个问题{cout<<"matrix det is no so ni is no "<<endl;exit(-1);}int i=0,j,k;double temp;Matrix cpMatrix;Matrix uMatrix;Matrix lMatrix;Matrix uniMatrix;Matrix lniMatrix;initMatrix(&uniMatrix,matrix.col,matrix.row);initMatrix(&lniMatrix,matrix.col,matrix.row);initMatrix(&cpMatrix,matrix.col,matrix.row);initMatrix(&uMatrix,matrix.col,matrix.row);initMatrix(&lMatrix,uMatrix.col,uMatrix.row);copy(matrix,&cpMatrix);double aij[MAX_MATRIX_COL][MAX_MATRIX_ROW];for(k=0; k<matrix.row-1; k++)//k表示第k次消元,一共需要n-1次{for(i=k+1; i<matrix.col; i++){aij[i][k]=matrix.mat[i][k]/matrix.mat[k][k];// 第k次消元,主元素为第k行第k列,把第k行以下的行都进行消元for(j=k; j<matrix.row; j++)//对于k行以下的每一行的每一列元素都减去主行与消元因子的乘积{matrix.mat[i][j]-=aij[i][k]*matrix.mat[k][j];}}}copy(matrix,&uMatrix);cout<<"uMatrix"<<endl;print(uMatrix);for(j=0; j<matrix.row; j++){for(i=j+1; i<matrix.col; i++){temp=0;for(k=0; k<j; k++){temp=lMatrix.mat[i][k]*uMatrix.mat[k][j];}lMatrix.mat[i][j]=1/uMatrix.mat[j][j]*(cpMatrix.mat[i][j]-temp);}}for(i=0; i<lMatrix.col; i++){for(j=0; j<lMatrix.row; j++){if(i==j)lMatrix.mat[i][j]=1;if(j>i)lMatrix.mat[i][j]=0;}}cout<<"lMatrix"<<endl;print(lMatrix);Matrix multsMatrix;multsMatrix.initMatrix(&multsMatrix,lMatrix.col,uMatrix.row);matrix.multsmatrix(&multsMatrix,lMatrix,uMatrix);cout<<"lu"<<endl;print(multsMatrix);//计算u逆for(j=0; j<uMatrix.row; j++){for(i=j; i>=0; i--){if(i==j)uniMatrix.mat[i][j]=1/uMatrix.mat[i][j];else{temp=0;for(k=j; k>i; k--){temp+=uMatrix.mat[i][k]*uniMatrix.mat[k][j];}uniMatrix.mat[i][j]=-1/uMatrix.mat[i][i]*temp;}}}cout<<"uniMatrix"<<endl;print(uniMatrix);//计算l逆for(j=0; j<lMatrix.row; j++){for(i=0; i<lMatrix.col; i++){if(j==i)lniMatrix.mat[i][j]=1;else{temp=0;for(k=j; k<i; k++){temp+=(lMatrix.mat[i][k]*lniMatrix.mat[k][j]);}lniMatrix.mat[i][j]=-temp;}}}cout<<"lniMatrix"<<endl;print(lniMatrix);multsmatrix(&multsMatrix,uniMatrix,lniMatrix);cout<<"luni"<<endl;print(multsMatrix);copy(multsMatrix,niMatrix);multsmatrix(&multsMatrix,cpMatrix,*niMatrix);cout<<"luluni"<<endl;print(multsMatrix);copy(cpMatrix,&matrix);}int LDL(Matrix x)//矩阵的LDL分解,不知道怎样用于矩阵特征值,特征向量求解{Matrix l;l.initMatrix(&l,x.col,x.row);Matrix d;d.initMatrix(&d,x.col,x.row);int i,j,k;Matrix temp;temp.initMatrix(&temp,x.col,x.row);for(i=0;i<x.col;i++){l.mat[i][i]=1;for(j=0;j<i;j++){for(k=0;k<j;k++){temp.mat[i][k]=l.mat[i][k]*d.mat[k][k];temp.mat[i][j]-=temp.mat[i][k]*l.mat[j][k];}temp.mat[i][j]=temp.mat[i][j]+x.mat[i][j];l.mat[i][j]=temp.mat[i][j]/d.mat[j][j];}d.mat[i][i]=x.mat[i][i];for(k=0;k<i;k++){d.mat[i][i]-=temp.mat[i][k]*l.mat[i][k];}}for(i=0;i<x.col;i++){for(j=0;j<x.row;j++){cout<<l.mat[i][j]<<" ";}cout<<endl;}for(i=0;i<x.col;i++){for(j=0;j<x.row;j++){cout<<d.mat[i][j]<<" ";}cout<<endl;}}
};
这篇关于SVM-SMO算法C++实现的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!