这次我要来分析另外一个头文件mdarray.h
第一步、粘代码
第一步条件编译指令
#ifndef __MDARRAY_H__
#define __MDARRAY_H__
一大堆头文件
#include <iostream>
#include <fstream>
#include <algorithm>
#include <numeric>
#include <cassert>
前面已经分析过了的头文件
#include "util.h"
#define USE_DOUBLE //定义的一个变量
#ifdef USE_DOUBLE //这里是给USE_DOUBLE给定类型
typedef double REAL;
#else
typedef float REAL;
#endif
template<class T> class Array2dC; //这句话在我看来后面重复了,没什么用
template<class T> //定义一个矩阵模板类
class Array2d
{
private:
void IncreaseCapacity(const int newrow); //私有中增加容量的函数
void DecreaseCapacity(const int newrow); //私有中减少容量的函数
public:
int nrow; //行
int ncol; //列
T** p; //设置一个二维数组的指针
public:
Array2d():nrow(0),ncol(0),p(NULL) { } //构造函数把0,0,NULL给出
Array2d(const int nrow,const int ncol):nrow(0),ncol(0),p(NULL) { Create(nrow,ncol); } //复制构造函数
Array2d(const Array2d<T>& source); //又是一个拷贝构造函数,应用了引用
virtual ~Array2d() { Clear(); } //虚析构函数
Array2d<T>& operator=(const Array2d<T>& source); //重载运算符“=”
void Create(const int _nrow,const int _ncol); //
void Swap(Array2d<T>& array2); //交换函数
void Clear(); //清空函数
void Zero(const T t = 0);
void AdjustCapacity(const int newrow); //调整容量函数
};
template<class T> //定义了一个类模板
class Array2dC
{
public:
int nrow; //行
int ncol; //列
T** p; //二维数组指针
T* buf; //缓冲带指针
public:
Array2dC():nrow(0),ncol(0),p(NULL),buf(NULL) {} //构造函数
Array2dC(const int nrow,const int ncol):nrow(0),ncol(0),p(NULL),buf(NULL) { Create(nrow,ncol); } //拷贝构造函数
Array2dC(const Array2dC<T>& source); //拷贝构造函数
virtual ~Array2dC() { Clear(); } //虚析构函数
Array2dC<T>& operator=(const Array2dC<T>& source); //重载运算符"="
void Create(const int _nrow,const int _ncol);
void Swap(Array2dC<T>& array2); //交换函数
void Zero(const T t = 0);
void Clear();//清零函数
};
//
double MatrixInversion(double** a,const int n,const double diagonal_increment); //矩阵求逆
bool Inv3x3(double a[3][3],double b[3][3],const double thresh = 1E-200); //倒置3*3矩阵
void SVD(Array2d<double>& a,double* w,Array2d<double>& v); //奇异值分解<a target=_blank href="http://http://blog.csdn.net/wangran51/article/details/7408414">点击打开链接</a>
void Normalize_L1(double* p,const int size); //标准化L1
void Normalize_L2(double* p,const int size); //标准化L2
void Normalize_01(double* p,const int size); //标准化01
void ComputeMeanAndVariance(Array2d<double>& data,Array2dC<double>& avg,Array2d<double>& cov,const bool subtractMean); //计算均值和方差
template<class T>
void Array2d<T>::IncreaseCapacity(const int newrow) //模板函数增加容量函数
{
assert(newrow>nrow); //假如新的行值大于类中的行值
T** newp = new T*[newrow]; assert(newp!=NULL); //新分配一个行的空间地址给二维矩阵指针
std::copy(p,p+nrow,newp); //调用copy函数,从Array2d类中的矩阵p到p的行结束,拷贝到newp中
for(int i=nrow;i<newrow;i++)
{
newp[i] = new T[ncol]; 新开辟一个ncol大小的数组给后面复制
assert(newp[i]!=NULL);
}
delete[] p; //
p = NULL;
p = newp;
newp = NULL;
nrow = newrow; //把原参数置换
}
//
template<class T>
void Array2d<T>::DecreaseCapacity(const int newrow) //和上面一个道理,我就不解释了
{
assert(newrow<nrow);
T** newp = new T*[newrow]; assert(newp!=NULL);
std::copy(p,p+newrow,newp);
for(int i=newrow;i<nrow;i++)
{
delete[] p[i];
p[i] = NULL;
}
delete[] p;
p = NULL;
p = newp;
newp = NULL;
nrow = newrow;
}
template<class T>
Array2d<T>::Array2d(const Array2d<T>& source):nrow(0),ncol(0),p(NULL) //拷贝构造函数
{
if(source.p!=NULL) //类中数组不为空
{
Create(source.nrow,source.ncol); //从创建一个数组
for(int i=0;i<nrow;i++)
std::copy(source.p[i],source.p[i]+ncol,p[i]);
}
}
template<class T>
Array2d<T>& Array2d<T>::operator=(const Array2d<T>& source) //重载运算符函数
{
if(source.p!=NULL) //类中数组不为空
{
Create(source.nrow,source.ncol); //创建一个新的矩阵
for(int i=0;i<nrow;i++)
std::copy(source.p[i],source.p[i]+ncol,p[i]);
}
else
Clear();
return *this; //返回当前状态指针
}
template<class T>
void Array2d<T>::Create(const int _nrow,const int _ncol) //创建函数
{
assert(_nrow>0 && _ncol>0); 输入的函数值都大于零
if(ncol==_ncol) return AdjustCapacity(_nrow);//假如类中的列值等于输入的列值,返回调整输入的行值得大小
Clear(); //把类中的数据清零
nrow = _nrow; ncol = _ncol; //把输入的行,列值分别给类
p = new T*[nrow]; assert(p!=NULL);//开辟一个新的行地址给类中的二维数组
for(int i=0;i<nrow;i++)
{
p[i] = new T[ncol]; assert(p[i]!=NULL);//再定义列数组
}
}
template<class T>
void Array2d<T>::Swap(Array2d<T>& array2) //交换函数
{
std::swap(nrow,array2.nrow); //把输入的行交换
std::swap(ncol,array2.ncol); //把输入的列交换
std::swap(p,array2.p); //把矩阵交换
}
template<class T>
void Array2d<T>::Zero(const T t)
{
if(nrow>0)
{
for(int i=0;i<nrow;i++) std::fill(p[i],p[i]+ncol,t); //指定p[i]到后面的值都为t
}
}
template<class T>
void Array2d<T>::Clear() //清零函数
{
for(int i=0;i<nrow;i++) { delete[] p[i]; p[i] = NULL; }
delete[] p; p = NULL;
nrow = ncol = 0;
}
template<class T>
void Array2d<T>::AdjustCapacity(const int newrow) //调整容量函数
{
assert(newrow>0); //断言,新行大于0
if(newrow == nrow) //一样就往回走
return;
else if(newrow>nrow) //假如大于调用增加容量函数
IncreaseCapacity(newrow);
else // newrow < nrow
DecreaseCapacity(newrow);
}
template<class T>
Array2dC<T>::Array2dC(const Array2dC<T>& source):nrow(0),ncol(0),p(NULL),buf(NULL) //C的构造函数
{
if(source.buf!=NULL) //调用的对象中的buf不为空
{
Create(source.nrow,source.ncol); //创建一个矩阵
std::copy(source.buf,source.buf+nrow*ncol,buf); //拷贝缓冲区域
}
}
template<class T>
Array2dC<T>& Array2dC<T>::operator=(const Array2dC<T>& source) //运算符重载函数
{
if(source.buf!=NULL)
{
Create(source.nrow,source.ncol);
std::copy(source.buf,source.buf+nrow*ncol,buf);
}
else
Clear();
return *this; //返回当前指针
}
template<class T>
void Array2dC<T>::Create(const int _nrow,const int _ncol) //
{
assert(_nrow>0 && _ncol>0);
if(nrow==_nrow && ncol==_ncol) return;
Clear();
nrow = _nrow; ncol = _ncol;
buf = new T[nrow*ncol]; assert(buf!=NULL); //多了一个buf空间
p = new T*[nrow]; assert(p!=NULL);
for(int i=0;i<nrow;i++) p[i] = buf + i * ncol; //这句话是干嘛的有点看不懂
}
template<class T>
void Array2dC<T>::Swap(Array2dC<T>& array2) //交换函数
{
std::swap(nrow,array2.nrow);
std::swap(ncol,array2.ncol);
std::swap(p,array2.p);
std::swap(buf,array2.buf);
}
template<class T>
void Array2dC<T>::Zero(const T t) //填充函数
{
if(nrow>0) std::fill(buf,buf+nrow*ncol,t);
}
template<class T>
void Array2dC<T>::Clear() //清零函数
{
delete[] buf; buf = NULL;
delete[] p; p = NULL;
nrow = ncol = 0;
}
#endif // __MDARRAY_H__