📄 matlabfun.cpp
字号:
// MatlabFun.cpp: implementation of the CMatlabFun class.
//
//////////////////////////////////////////////////////////////////////
#include "stdafx.h"
#ifdef USE_MATLAB
//#include "eds.h"
#include "MatlabFun.h"
#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif
//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////
CMatlabFun::CMatlabFun()
{
#ifdef USE_MATLAB
if (!(ep = engOpen(NULL))) {
MessageBox ((HWND)NULL, (LPSTR)"Can't start MATLAB engine",
(LPSTR) "Engwindemo.c", MB_OK);
exit(-1);
}
#endif
}
CMatlabFun::~CMatlabFun()
{
}
// ==================================================================
//
// FUNCTION : CMatlabFun::Cluster()
//
// * Description :层次聚类分析(默认为Euliadan距离,类间距为最短距离,可考虑进行修改)
//
//
// * Author : [Wenyu Ye], Created : [2002-9-21 9:53:05]
//
// * Returns : [bool] -
//
// * Function parameters :
// [*pSData] -原始数据
// [nVecLen] -单个向量常
// [nVecNum] -向量个数
// [nClass] -待划分类别个数
// [*pRe] -结果指针
// [nReNum] -结果个数(=向量个数)
//
// ==================================================================
bool CMatlabFun::HCluster(double *pSData, int nVecLen, int nVecNum, int nClass, int *pRe, int nReNum)
{
ASSERT(nReNum==nVecNum);
TRACE0( " CMatlabFun::Cluster() entered\n" );
mxArray *T=NULL,*R=NULL;
T = mxCreateDoubleMatrix(nVecLen,nVecNum,mxREAL);
memcpy((void *) mxGetPr(T),(void*)pSData,nVecLen*nVecNum*sizeof(double));
// mxSetName(T, "T");
// engPutArray(ep, T);
engPutVariable(ep,"T",T);
engEvalString(ep, "T=T'");//因存储顺序问题聚类时以行为对象
//==此处用的是分级聚类方法;该方法为分为指定的类
CString strT,str="Y=pdist(T);Z=linkage(Y);R=cluster(Z,";
strT.Format("%d);",nClass);
str=str+strT;
engEvalString(ep,str);
// R=engGetArray(ep,"R");
R=engGetVariable(ep,"R");
//==debug
int row=mxGetM(R);
//--debug
double *pT= new double[nVecNum];
memcpy((void*)pT,(void*)mxGetPr(R),nVecNum*sizeof(double));
for(int i=0;i<nVecNum;i++)
pRe[i]=int(pT[i]);
delete pT;
mxDestroyArray(T);
return true;
}
// ==================================================================
//
// FUNCTION : CMatlabFun::PutToMatlab()
//
// * Description :放指定数据到matlab中
//
//
// * Author : [Wenyu Ye], Created : [2002-9-22 11:19:31]
//
// * Returns : [void] -
//
// * Function parameters :
// [*pSData] -
// [nRow] -
// [nCol] -
// [strName] -
//
// ==================================================================
void CMatlabFun::PutToMatlab(double *pSData, int nRow, int nCol, CString strName)
{
// TRACE0( " CMatlabFun::PutToMatlab() entered\n" );
mxArray *T=NULL,*R=NULL;
T = mxCreateDoubleMatrix(nRow,nCol,mxREAL);
memcpy((void *) mxGetPr(T),(void*)pSData,nRow*nCol*sizeof(double));
// mxSetName(T, strName);
// engPutArray(ep, T);
engPutVariable(ep,strName,T);
/*
engEvalString(ep, "T=T'");//因存储顺序问题
CString strT,str="Y=pdist(T);Z=linkage(Y);R=cluster(Z,";
strT.Format("%d);",nClass);
str=str+strT;
engEvalString(ep,str);
R=engGetArray(ep,"R");
//==debug
int row=mxGetM(R);
//--debug
double *pT= new double[nVecNum];
memcpy((void*)pT,(void*)mxGetPr(R),nVecNum*sizeof(double));
for(int i=0;i<nVecNum;i++)
pRe[i]=int(pT[i]);
delete pT;
*/ mxDestroyArray(T);
return ;
}
void CMatlabFun::PutToMatlab(int *pSData, int nRow, int nCol, CString strName)
{
double *p=new double[nRow*nCol];
for(int i=0;i<nRow*nCol;i++)
p[i]=pSData[i];
PutToMatlab(p,nRow,nCol,strName);
delete [] p;
return;
}
void CMatlabFun::ExecuteFun(CString str)
{
engEvalString(ep, str);//因存储顺序问题
}
void CMatlabFun::CloseMatlab()
{
engClose(ep);
}
// ==================================================================
//
// FUNCTION : CMatlabFun::PolyFit()
//
// * Description :曲线拟和函数
//
//
// * Author : [Wenyu Ye], Created : [2002-10-8 13:34:52]
//
// * Returns : [void] -
//
// * Function parameters :
// [*pData] -原始数据
// [nS] -拟和起始点
// [nE] -拟和终止点
// [Order] -多项式阶次
// [*pcofRe] -返回的结果系数a[0]*x^order+...a[order-1]*x+a[order];
// [nReLen] -结果系数长度(=order+1);
// [&var] -拟和方差;
//
// ==================================================================
void CMatlabFun::PolyFit(int *pData, int nS, int nE, int Order, float *pcofRe, int nReLen, float &var)
{
TRACE0( " CPubFun::PolyFit() entered\n" );
CString str;
str.Format ("X=%d:%d;order=%;",nS,nE,Order);
ExecuteFun(str);
PutToMatlab(&pData[nS],1,nE-nS+1,"Y");
ExecuteFun("p=polyfit(Y,X,order);YY=polyval(p,X);VAR=sum((YY-Y)^2)");
GetFromMatlab(pcofRe,1,nReLen,"p");
GetFromMatlab(&var,1,1,"VAR");
}
// ==================================================================
//
// FUNCTION : CMatlabFun::GetFromMatlab()
//
// * Description :
//
//
// * Author : [Wenyu Ye], Created : [2002-10-8 14:10:43]
//
// * Returns : [bool] -
//
// * Function parameters :
// [*pSData] -
// [nRow] -
// [nCol] -
// [strName] -matlab 中变量名
//
// ==================================================================
bool CMatlabFun::GetFromMatlab(double *pSData, int nRow, int nCol, CString strName)
{
// TRACE0( " CMatlabFun::GetFromMatlab() entered\n" );
mxArray *d;
// d=engGetArray(ep,strName);
d=engGetVariable(ep,strName);
if(d==NULL)
return false;
else
{
int M,N;
double *Dreal=mxGetPr(d);
M=mxGetM(d),N=mxGetN(d);
ASSERT(M*N==nRow*nCol);
//if()
memcpy((void*)pSData,(void*)Dreal,sizeof(double)*M*N);
return true;
}
}
bool CMatlabFun::GetFromMatlab(int *pSData, int nRow, int nCol, CString strName)
{
double *pT=new double[nRow*nCol];
if(GetFromMatlab(pT, nRow, nCol, strName))
{
for(int i=0;i<nRow*nCol;i++)
pSData[i]=(int)pT[i];
if(pT!=NULL)
delete [] pT;
return true;
}
else
{
if(pT!=NULL)
delete [] pT;
return false;
}
}
bool CMatlabFun::GetFromMatlab(__int16 *pSData, int nRow, int nCol, CString strName)
{
double *pT=new double[nRow*nCol];
if(GetFromMatlab(pT, nRow, nCol, strName))
{
for(int i=0;i<nRow*nCol;i++)
pSData[i]=(__int16)pT[i];
if(pT!=NULL)
delete [] pT;
return true;
}
else
{
if(pT!=NULL)
delete [] pT;
return false;
}
}
bool CMatlabFun::GetFromMatlab(float *pSData, int nRow, int nCol, CString strName)
{
double *pT=new double[nRow*nCol];
if(GetFromMatlab(pT, nRow, nCol, strName))
{
for(int i=0;i<nRow*nCol;i++)
pSData[i]=(float)pT[i];
if(pT!=NULL)
delete [] pT;
return true;
}
else
{
if(pT!=NULL)
delete [] pT;
return false;
}
}
void CMatlabFun::PutToMatlab(float *pSData, int nRow, int nCol, CString strName)
{
double *p=new double[nRow*nCol];
for(int i=0;i<nRow*nCol;i++)
p[i]=pSData[i];
PutToMatlab(p,nRow,nCol,strName);
delete [] p;
return;
}
// ==================================================================
//
// FUNCTION : CMatlabFun::AutoHCluster()
//
// * Description :层次聚类分析(默认为Euliadan距离,类间距为最短距离,可考虑进行修改)
//
//
// * Author : [Wenyu Ye], Created : [2002-9-21 9:53:05]
//
// * Returns : [bool] -
//
// * Function parameters :
// [*pSData] -原始数据
// [nVecLen] -单个向量常
// [nVecNum] -向量个数
// [dThreshold] -分类阈值0~1间
// [*pRe] -结果指针
// [nReNum] -结果个数(=向量个数)
//
// ==================================================================
void CMatlabFun::AutoHCluster(double *pSData, int nVecLen, int nVecNum, float dThreshold, int *pRe, int &nReNum)
{
/*T = clusterdata(X, cutoff)
T = clusterdata(X,'param1',val1,'param2',val2,...)
可选参数:(有关具体定义见,原online文档)
'distance':'euclidean'(default),'seuclidean','mahalanobis','cityblock','minkowski',
'cosine','correlation','hamming','jaccard',
'linkage':'single'Shortest distance (default)
'cutoff':Cutoff for inconsistent or distance measure
'maxclust':Maximum number of clusters to form
'criterion':Either 'inconsistent' or 'distance';
'depth':inconsistent的计算深度
*/
// ASSERT(nReNum==nVecNum);
// TRACE0( " CMatlabFun::Cluster() entered\n" );
mxArray *T=NULL,*R=NULL;
T = mxCreateDoubleMatrix(nVecLen,nVecNum,mxREAL);
memcpy((void *) mxGetPr(T),(void*)pSData,nVecLen*nVecNum*sizeof(double));
// mxSetName(T, "T");
// engPutArray(ep, T);
engPutVariable(ep,"T",T);
engEvalString(ep, "T=T'");//因存储顺序问题
//==此处用的是分级聚类方法;该方法为分为指定的类
//CString strT,str="Y=pdist(T);Z=linkage(Y);R=cluster(Z,";
CString strT,str="R=clusterdata(X,";
strT.Format("%d);",dThreshold);
str=str+strT;
engEvalString(ep,str);
// R=engGetArray(ep,"R");
R=engGetVariable(ep,"R");
//==debug
int row=mxGetM(R);
//--debug
double *pT= new double[nVecNum];
memcpy((void*)pT,(void*)mxGetPr(R),nVecNum*sizeof(double));
//==复制结果并计数
nReNum=0;
for(int i=0;i<nVecNum;i++)
{
pRe[i]=int(pT[i]);
if(pRe[i]>nReNum)
nReNum=pRe[i];
}
delete pT;
mxDestroyArray(T);
return;
// return true;
}
// ==================================================================
//
// FUNCTION : CMatlabFun::FCMeam()
//
// * Description :
//
//
// * Author : [Wenyu Ye], Created : [2003-3-31 8:39:35]
//
// * Returns : [void] -模糊C均值
//
// * Function parameters :
// [*pSData] -
// [nVecLen] -
// [nVecNum] -
// [dThreshold] -
// [*pRe] -分类结果,形成模糊隶属矩阵
// [&nReNum] -
//
// ==================================================================
void CMatlabFun::FCMeam(double *pSData, int nVecLen, int nVecNum, int nCluster, float *pRe, int &nReNum)
{//[center,U,obj_fcn] = fcm(data,cluster_n)
/*可更该参数
options(1): exponent for the partition matrix U (default: 2.0)
options(2): maximum number of iterations (default: 100)
options(3): minimum amount of improvement (default: 1e-5)
options(4): info display during iteration (default: 1)
*/
return;
}
//k均值
void CMatlabFun::KMeans(double *pSData, int nVecLen, int nVecNum, int nClass, float *pRe)
{
/* IDX = kmeans(X,k)
[IDX,C] = kmeans(X,k)
[IDX,C,sumd] = kmeans(X,k)
[IDX,C,sumd,D] = kmeans(X,k)
[...] = kmeans(...,'param1',val1,'param2',val2,...) */
//可定义参数'distance'距离;'start':初始化聚类中心的方法;'sqEuclidean';。。。。
return;
}
// ==================================================================
//
// FUNCTION : CMatlabFun::HECGCluster()
//
// * Description :层次聚类分析(默认为Euliadan距离,类间距为最短距离,可考虑进行修改)
// 专用与ECG波形的自动聚类,自动划分标准:以相临级别连接差值最大处进行划分,
// 该差值大于总距离的dPar倍(默认为0.3)
//
// * Author : [Wenyu Ye], Created : [2002-9-21 9:53:05]
//
// * Returns : [bool] -
//
// * Function parameters :
// [*pSData] -原始数据
// [nVecLen] -单个向量常
// [nVecNum] -向量个数
// [nClass] -待划分类别个数
// [*pRe] -结果指针
// [nReNum] -结果个数(=向量个数)
//
// ==================================================================
void CMatlabFun::HECGCluster(double *pSData, int nVecLen, int nVecNum, float dPar,int *pRe, int &nReNum)
{
if(nVecNum<=2)
{
pRe[0]=0;
pRe[1]=0;
nReNum=1;
return;
}
// ASSERT(nReNum==nVecNum);
TRACE0( " CMatlabFun::Cluster() entered\n" );
mxArray *T=NULL,*R=NULL,*Temp=NULL;
T = mxCreateDoubleMatrix(nVecLen,nVecNum,mxREAL);
memcpy((void *) mxGetPr(T),(void*)pSData,nVecLen*nVecNum*sizeof(double));
// mxSetName(T, "T");
// engPutArray(ep, T);
engPutVariable(ep,"T",T);
engEvalString(ep, "T=T'");//因存储顺序问题聚类时以行为对象
//==此处用的是分级聚类方法;该方法为分为指定的类
// CString strT,str="Y=pdist(T);Z=linkage(Y);R=cluster(Z,";
CString strT,str="Y=pdist(T);Z=linkage(Y);DZ=diff(Z(:,3));MH=Z(end,3);MDZ=max(DZ);";
str+="nC=find(DZ==MDZ);nC=length(Z(:,3))-nC+1;R=cluster(Z,nC);";//将最大分类点处作为分类的边界
engEvalString(ep,str);
//squareform(Y);dendrogram(Z)
//==确定分类边界的合理性看是否MDZ>dPar*MH;若是表明分类合理,否则所有数据归为一类
double dMDZ,dMH;
Temp=engGetVariable(ep,"MDZ");
dMDZ=*mxGetPr(Temp);
//memcpy(&dMDZ,(void*)mxGetPr(Temp),1*sizeof(double));
Temp=engGetVariable(ep,"MH");
//memcpy(&dMH,(void*)mxGetPr(Temp),1*sizeof(double));
dMH=*mxGetPr(Temp);
Temp=engGetVariable(ep,"nC");
nReNum=(int)*mxGetPr(Temp);
if(dMH*dPar<dMDZ)
{//cluster result is valid
R=engGetVariable(ep,"R");
//==debug
int row=mxGetM(R);
//--debug
double *pT= new double[nVecNum];
memcpy((void*)pT,(void*)mxGetPr(R),nVecNum*sizeof(double));
for(int i=0;i<nVecNum;i++)
pRe[i]=int(pT[i]);
delete pT;
}
else
{//not vavlid;
nReNum=1;
for(int i=0;i<nVecNum;i++)
pRe[i]=0;
}
mxDestroyArray(T);
return;
}
//直接送入二维指针
void CMatlabFun::PutToMatlab(int **ppSData, int nRow, int nCol, CString strName)
{
double *p=new double[nRow*nCol];
int i,j;
for(i=0;i<nRow;i++)
for(j=0;j<nCol;j++)
p[j*nRow+i]=ppSData[i][j];
PutToMatlab(p,nRow,nCol,strName);
delete [] p;
return;
}
void CMatlabFun::PutToMatlab(__int16 **ppSData, int nRow, int nCol, CString strName)
{
double *p=new double[nRow*nCol];
int i,j;
for(i=0;i<nRow;i++)
for(j=0;j<nCol;j++)
p[j*nRow+i]=ppSData[i][j];
PutToMatlab(p,nRow,nCol,strName);
delete [] p;
return;
}
void CMatlabFun::PutToMatlab(__int16 ppSData[12][5000], int nRow, int nCol, CString strName)
{
double *p=new double[nRow*nCol];
int i,j;
for(i=0;i<nRow;i++)
for(j=0;j<nCol;j++)
p[j*nRow+i]=ppSData[i][j];
PutToMatlab(p,nRow,nCol,strName);
delete [] p;
return;
}
void CMatlabFun::PutToMatlab(__int16 *pSData, int nRow, int nCol, CString strName)
{
double *p=new double[nRow*nCol];
for(int i=0;i<nRow*nCol;i++)
p[i]=pSData[i];
PutToMatlab(p,nRow,nCol,strName);
delete [] p;
return;
}
#endif USE_MATLAB
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -