求解协方差矩阵算法 转载地址:http://www.16kan.com/post/231601.html




covHead.h

#include <iostream>
  
class COV {
public :
     COV( void );
     void clear( void );
public :
     void rdOrMatrix( int _sapNum, int _dim); 
     //_sapNum为样本个数, _dimt为维数; 创建样本集矩阵并存入数组 orAry(_sapNum行, _dimt列)
     void meanVal( void ); //计算各维度的均值, 并存入数组 meanValAry(一维数组, 维数为_dimt)
     void meanMatrix( void ); //计算各维减去各维均值后的新矩阵并存入数组 orAry(_sapNum行, _dimt列)
     void meanMatrixTrs( void ); //计算新矩阵的转置矩阵并存入数组 meanAryTrs(_dimt行,_sapNum列)
     void covMatrix( void ); //计算协方差矩阵并存入数组 covAry(_dimt * _dimt方阵)
  
     void showOrMatrix( void ); //输出初始样本集矩阵
     void showMeanVal( void ); //输出各维度的均值
     void showMeanMatrix( void ); //输出减去均值后的样本矩阵
     void showMeanMatrixTrs( void ); //输出减去均值后的样本矩阵的转置矩阵
     void showCovMatrix( void ); //输出协方差矩阵
private :
     int sapNum_, dim_; //样本个数;维数;降维后维数
     double **orAry; //初始样本集矩阵(减去均值后的新样本矩阵)
     double *meanValAry, **meanAryTrs; //各维度的均值;减去均值后的矩阵的转置矩阵
     double **covAry; //协方差方阵
};
 

 covFile.h

#include <iostream>
#include "covHead.h"
#include <malloc.h>
#include <math.h>
  
//
COV::COV() {
     sapNum_ = 0;    dim_ = 0;
     orAry = NULL;
     meanValAry = NULL;  meanAryTrs = NULL;
     covAry = NULL;
}
  
//
void COV::clear() {
      
}
  
/
void COV::rdOrMatrix( int _sapNum, int _dim) { //读取初始样本集矩阵
     sapNum_ = _sapNum;  dim_ = _dim;
     std::cout << "维数为: " << dim_ << "样本个数为: " << sapNum_ << '\n' ;
     orAry = ( double **) malloc (sapNum_* sizeof ( double ));
     for ( int i=0; i<sapNum_; i++)
         *(orAry+i) = ( double *) malloc (dim_* sizeof ( double )); //每一行存放一个样本向量,列数为维数,行数位总样本向量个数
  
     std::cout << "read the original vectors" << '\n' ;
     FILE *fp;
     char ch;
     if ((fp= fopen ( "covariance.txt" , "rt" ))==NULL) { //covariance文件中每一行代表一个样本向量,列数为维数                            
         printf ( "Cannot open file strike any key exit!" );
         exit (0);
     }
  
     ch= fgetc (fp);
     std::string str= "" ; //这里str是类string的一个对象
     int k=0;
     while (k<sapNum_) {
         for ( int i=0; i<dim_; i++) {
             while (ch== ' ' || ch== 'v' || ch== '\n' )
                 ch= fgetc (fp);
             while (ch!= ' ' && ch!= '\n' && ch!= 'v' ) {
                 str+=ch;
                 ch= fgetc (fp);
             }
             double aa= atof (str.c_str()); //将字符串转换成double型
             *(*(orAry+k)+i) = aa; //文本中的一行为矩阵valAry中的一行
             str= "" ;
         }
         ch= fgetc (fp);
         k++;
     }
}
  
void COV::showOrMatrix() {
     std::cout << "============================================================" << '\n' ;
     std::cout << "初始样本矩阵 :" << '\n' ;
     for ( int i=0; i<sapNum_; i++) {
         for ( int j=0; j<dim_; j++)
             std::cout << *(*(orAry+i)+j) << "    " ;
         std::cout << '\n' ;
     }           
}
  
  
/
void COV::meanVal() { //各维的均值
     meanValAry = ( double *) malloc (dim_* sizeof ( double ));
  
     double sum=0.0;
     for ( int i=0; i<dim_; i++) {
         sum = 0.0;
         for ( int j=0; j<sapNum_; j++)
             sum += *(*(orAry+j)+i);
         *(meanValAry+i) = sum/sapNum_;
     }
}
  
void COV::showMeanVal() {
     std::cout << "====================================" << '\n' ;
     std::cout << "各维的均值 :" << '\n' ;
     for ( int i=0; i<dim_; i++)
         std::cout << *(meanValAry+i) << "   " ;
     std::cout << '\n' ;
}
  
  
/
void COV::meanMatrix() { //减去均值后的样本集矩阵
     for ( int j=0; j<dim_; j++)
         for ( int i=0; i<sapNum_; i++)
             *(*(orAry+i)+j) = *(*(orAry+i)+j)- *(meanValAry+j);
}
  
void COV::showMeanMatrix() {
     std::cout << "============================================================" << '\n' ;
     std::cout << "减去均值后的样本矩阵 :" << '\n' ;
     for ( int i=0; i<sapNum_; i++) {
         for ( int j=0; j<dim_; j++)
             std::cout << *(*(orAry+i)+j) << "    " ;
         std::cout << '\n' ;
     }           
}
  
  
///
void COV::meanMatrixTrs() { //减去均值后的样本集矩阵的转置矩阵
     meanAryTrs = ( double **) malloc (dim_* sizeof ( double ));
     for ( int i=0; i<dim_; i++)
         *(meanAryTrs+i) = ( double *) malloc (sapNum_* sizeof ( double ));
      
     for (i=0; i<dim_; i++)
         for ( int j=0; j<sapNum_; j++)
             *(*(meanAryTrs+i)+j) = *(*(orAry+j)+i);
}
  
void COV::showMeanMatrixTrs() {
     std::cout << "============================================================" << '\n' ;
     std::cout << "减去均值后的样本矩阵的转置矩阵 :" << '\n' ;
     for ( int i=0; i<dim_; i++) {
         for ( int j=0; j<sapNum_; j++)
             std::cout << *(*(meanAryTrs+i)+j) << "    " ;
         std::cout << '\n' ;
     }           
}
  
  
///
void COV::covMatrix() { //协方差矩阵
     covAry = ( double **) malloc (dim_* sizeof ( double ));
         for ( int i=0; i<dim_; i++)
             *(covAry+i) = ( double *) malloc (dim_* sizeof ( double ));
  
     //计算协方差矩阵代码:减去均值的样本矩阵的转置矩阵 * 减去均值的样本矩阵本身
     for (i=0; i<dim_; i++) {
         for ( int j=0; j<dim_; j++) {
             double data = 0.0;
             for ( int k=0; k<sapNum_; k++)
                 data +=  (*(*(meanAryTrs+i)+k))* (*(*(orAry+k)+j));
             data /= sapNum_-1;
             *(*(covAry+i)+j) = data;
         }
     }
}
  
void COV::showCovMatrix() {
     std::cout << "============================================================" << '\n' ;
     std::cout << "初始样本集矩阵的协方差矩阵 :" << '\n' ;
     for ( int i=0; i<dim_; i++) {
         for ( int j=0; j<dim_; j++)
             std::cout << *(*(covAry+i)+j) << "    " ;
         std::cout << '\n' ;
     }           
}

 

covariance.cpp

#include <iostream>
#include "covFile.h"
  
int main() {
     COV cov;
     //pca.PCA();
     cov.rdOrMatrix(10,3); //初始样本集矩阵
     cov.showOrMatrix();
     cov.meanVal(); //均值数组
     cov.showMeanVal();
     cov.meanMatrix(); //减去均值后的样本集矩阵
     cov.showMeanMatrix();
     cov.meanMatrixTrs(); //减去均值后的样本矩阵的转置矩阵
     cov.showMeanMatrixTrs();
     cov.covMatrix(); //协方差矩阵
     cov.showCovMatrix();
      
     return 0;
}

 


 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值