添加了mex混合编程文件
This commit is contained in:
parent
ba9b3d63d3
commit
a149240783
|
|
@ -107,9 +107,7 @@
|
|||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="PropertySheet.props" />
|
||||
<Text Include="readme.txt">
|
||||
<DeploymentContent>false</DeploymentContent>
|
||||
</Text>
|
||||
<None Include="readme.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="kthread.h" />
|
||||
|
|
|
|||
|
|
@ -17,9 +17,7 @@
|
|||
<ItemGroup>
|
||||
<None Include="PropertySheet.props" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="readme.txt" />
|
||||
<None Include="readme.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="matlab_io.h">
|
||||
|
|
|
|||
|
|
@ -14,6 +14,92 @@
|
|||
#include "matlab_io.h"
|
||||
using namespace std;
|
||||
|
||||
// 将matlab存储方式转换成c存储方式
|
||||
#define TRANS_ROW_COL(dst, src, rowNum, colNum) \
|
||||
for (int rowI = 0; rowI < rowNum; ++rowI) { \
|
||||
for (int colJ = 0; colJ < colNum; ++colJ) { \
|
||||
dst[rowI * colNum + colJ] = src[colJ * rowNum + rowI]; \
|
||||
} \
|
||||
}
|
||||
|
||||
/* 读取结构体中的二维字符串矩阵(一维的cell,每个cell又有一层cell,每个cell是一个字符串)*/
|
||||
bool ReadChildString2D(const string& filePath, const string& parentName, const string& selfName, vector<vector<string> >& vvStr) {
|
||||
MATFile* pMatFile = nullptr;
|
||||
mxArray* pMxArray = nullptr;
|
||||
mxArray* pCell = nullptr;
|
||||
int rowNum, colNum;
|
||||
char strBuf[STRING_BUF_SIZE];
|
||||
|
||||
pMatFile = matOpen(filePath.c_str(), "r"); //打开.mat文件
|
||||
if (pMatFile == nullptr) {
|
||||
cout << "filePath is error!" << endl;
|
||||
return false;
|
||||
}
|
||||
mxArray* pMxParent = matGetVariable(pMatFile, parentName.c_str()); //获取G变量
|
||||
|
||||
// 读取字符串
|
||||
pMxArray = mxGetField(pMxParent, 0, selfName.c_str()); // ds
|
||||
rowNum = (int)mxGetM(pMxArray);
|
||||
colNum = (int)mxGetN(pMxArray);
|
||||
for (int i = 0; i < rowNum; ++i) {
|
||||
for (int j = 0; j < colNum; ++j) {
|
||||
pCell = mxGetCell(pMxArray, j * rowNum + i);
|
||||
int childRowNum = (int)mxGetM(pCell);
|
||||
int childColNum = (int)mxGetN(pCell);
|
||||
vvStr.push_back(vector<string>());
|
||||
vvStr.back().resize(childRowNum * childColNum);
|
||||
for (int ii = 0; ii < childRowNum; ii++) {
|
||||
for (int jj = 0; jj < childColNum; jj++) {
|
||||
mxArray* pChildCell = mxGetCell(pCell, jj * childRowNum + ii);
|
||||
if (mxGetString(pChildCell, strBuf, STRING_BUF_SIZE) != 0) {
|
||||
cout << "String is too large to fit in the buffer! " << i + 1 << '\t' << j + 1 << endl;
|
||||
return false;
|
||||
}
|
||||
vvStr.back()[ii * childColNum + jj] = strBuf;
|
||||
// auto& lastStr = vvStr.back()[ii * childColNum + jj];
|
||||
// transform(lastStr.begin(), lastStr.end(), lastStr.begin(), ::toupper); // 转成大写
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
mxDestroyArray(pMxArray);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* 读取结构体中的二维double矩阵(一维的cell,每个cell又有一层cell,每个cell是一个字符串)*/
|
||||
bool ReadChildDouble2D(const string& filePath, const string& parentName, const string& selfName, vector<vector<double> >& vvDouble) {
|
||||
MATFile* pMatFile = nullptr;
|
||||
mxArray* pMxArray = nullptr;
|
||||
mxArray* pCell = nullptr;
|
||||
int rowNum, colNum;
|
||||
|
||||
pMatFile = matOpen(filePath.c_str(), "r"); //打开.mat文件
|
||||
if (pMatFile == nullptr) {
|
||||
cout << "filePath is error!" << endl;
|
||||
return false;
|
||||
}
|
||||
mxArray* pMxParent = matGetVariable(pMatFile, parentName.c_str()); //获取G变量
|
||||
|
||||
// 读取double数据
|
||||
pMxArray = mxGetField(pMxParent, 0, selfName.c_str()); // ds
|
||||
rowNum = (int)mxGetM(pMxArray);
|
||||
colNum = (int)mxGetN(pMxArray);
|
||||
for (int i = 0; i < rowNum; ++i) {
|
||||
for (int j = 0; j < colNum; ++j) {
|
||||
pCell = mxGetCell(pMxArray, j * rowNum + i);
|
||||
int childRowNum = (int)mxGetM(pCell);
|
||||
int childColNum = (int)mxGetN(pCell);
|
||||
|
||||
vvDouble.push_back(vector<double>());
|
||||
vvDouble.back().resize(childRowNum * childColNum);
|
||||
double* pVal = (double*)mxGetData(pCell); //获取指针
|
||||
TRANS_ROW_COL(vvDouble.back(), pVal, childRowNum, childColNum); // 行列存储方式转换
|
||||
}
|
||||
}
|
||||
mxDestroyArray(pMxArray);
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ¶ÁÈ¡×Ö·û´®¾ØÕó */
|
||||
bool ReadMtxString(const string& filePath, const string& mtxName,
|
||||
vector<string>& vStr, int* pRowNum, int* pColNum) {
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@
|
|||
#include <vector>
|
||||
using namespace std;
|
||||
|
||||
#define STRING_BUF_SIZE 10240
|
||||
#define STRING_BUF_SIZE 204800
|
||||
typedef double T;
|
||||
/*
|
||||
注意参数的区别,读取时候直接传递文件路径名,写入的时候需要提供文件指针,
|
||||
|
|
@ -31,4 +31,11 @@ T* ReadMtxDouble(const string& filePath, const string& mtxName, int* pRowNum, in
|
|||
/* 将数据写入mat文件中,用给定的名称命名 */
|
||||
bool SaveMtxDouble(T* src, MATFile* pMatFile, string matrixName, int rowNum, int colNum);
|
||||
|
||||
/* 读取结构体中的字符串数据 */
|
||||
bool ReadChildString2D(const string& filePath, const string& parentName, const string& selfName, vector<vector<string> >& vvStr);
|
||||
|
||||
/* 读取结构体中的二维double矩阵(一维的cell,每个cell又有一层cell,每个cell是一维double数组)*/
|
||||
bool ReadChildDouble2D(const string& filePath, const string& parentName, const string& selfName, vector<vector<double> >& vvDouble);
|
||||
|
||||
|
||||
#endif
|
||||
|
|
@ -129,9 +129,7 @@
|
|||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="PropertySheet.props" />
|
||||
<Text Include="readme.txt">
|
||||
<DeploymentContent>false</DeploymentContent>
|
||||
</Text>
|
||||
<None Include="readme.md" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
|||
|
|
@ -33,8 +33,6 @@
|
|||
<ItemGroup>
|
||||
<None Include="PropertySheet.props" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="readme.txt" />
|
||||
<None Include="readme.md" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -92,7 +92,7 @@ bool ReadInfoFromMat(const string & filePath, vector<vector<string> >&vvDs, vect
|
|||
mxArray* pMxArray = nullptr;
|
||||
mxArray* pCell = nullptr;
|
||||
int rowNum, colNum;
|
||||
char strBuf[STRING_BUF_SIZE];
|
||||
char *strBuf = new char[STRING_BUF_SIZE];
|
||||
const string& parrentName = "G";
|
||||
const string& firstChildName = "ds";
|
||||
const string& secondChildName = "fr";
|
||||
|
|
@ -112,6 +112,7 @@ bool ReadInfoFromMat(const string & filePath, vector<vector<string> >&vvDs, vect
|
|||
INNTER_FOR_BEGIN
|
||||
if (mxGetString(pChildCell, strBuf, STRING_BUF_SIZE) != 0) {
|
||||
cout << "String is too large to fit in the buffer! " << i + 1 << '\t' << j + 1 << endl;
|
||||
delete[]strBuf;
|
||||
return false;
|
||||
}
|
||||
vvDs.back()[ii * childColNum + jj] = strBuf;
|
||||
|
|
@ -127,9 +128,10 @@ bool ReadInfoFromMat(const string & filePath, vector<vector<string> >&vvDs, vect
|
|||
vvFr.back().resize(childRowNum * childColNum);
|
||||
double *pVal = (double*)mxGetData(pCell); //获取指针
|
||||
TRANS_ROW_COL(vvFr.back(), pVal, childRowNum, childColNum); // 行列存储方式转换
|
||||
OUTER_FOR_END
|
||||
OUTER_FOR_END
|
||||
|
||||
// 没考虑完全哪些数据需要mxDestroyArray,可能会有内存泄漏
|
||||
// 没考虑完全哪些数据需要mxDestroyArray,可能会有内存泄漏
|
||||
delete[]strBuf;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
|
@ -233,7 +235,7 @@ void CalcEntropy(int argc, const char** argv) {
|
|||
string wordMatSuffix(argv[2]); // 高频词汇矩阵对应的mat文件的后缀名(可以是全文件名,可以是文件名后缀,必须保证唯一)
|
||||
fs::path outFileName(argv[4]);
|
||||
int numThread = 1;
|
||||
if (argc >= 5) numThread = atoi(argv[5]);
|
||||
if (argc > 5) numThread = atoi(argv[5]);
|
||||
if (numThread < 1) numThread = 1;
|
||||
|
||||
/* 读入处理后的pubmed文献信息的mat文件,只读入摘要信息,即变量abs1 */
|
||||
|
|
@ -281,7 +283,7 @@ void CalcEntropy(int argc, const char** argv) {
|
|||
cout << "read abstract time: " << (double)(finish - begin) / CLOCKS_PER_SEC << " s" << endl;
|
||||
/* 将分割结果写入mat文件 */
|
||||
begin = clock();
|
||||
if (argc >= 6) {
|
||||
if (argc > 6) {
|
||||
MATFile* pMatFile = matOpen(argv[6], "w");
|
||||
mxArray* pCellMtx= mxCreateCellMatrix(1, vvWordMtx.size());
|
||||
for (int i = 0; i < vvWordMtx.size(); ++i) {
|
||||
|
|
|
|||
|
|
@ -127,9 +127,7 @@
|
|||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="PropertySheet.props" />
|
||||
<Text Include="readme.txt">
|
||||
<DeploymentContent>false</DeploymentContent>
|
||||
</Text>
|
||||
<None Include="readme.md" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
|||
|
|
@ -36,8 +36,6 @@
|
|||
<ItemGroup>
|
||||
<None Include="PropertySheet.props" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="readme.txt" />
|
||||
<None Include="readme.md" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -128,6 +128,11 @@ T SquareAverage(vector<T>& vVal) {
|
|||
|
||||
/* 计算向量x和y的相关距离, 向量维度必须相等*/
|
||||
double CorrelationDistance(vector<double>& vX, vector<double>& vY) {
|
||||
double xMean = Average(vX);
|
||||
transform(vX.cbegin(), vX.cend(), vX.begin(), [&](double val) { return val - xMean; });
|
||||
double yMean = Average(vY);
|
||||
transform(vY.cbegin(), vY.cend(), vY.begin(), [&](double val) { return val - yMean; });
|
||||
|
||||
vector<double> vXY(vX.size());
|
||||
for (int i = 0; i < vXY.size(); ++i) {
|
||||
vXY[i] = vX[i] * vY[i];
|
||||
|
|
|
|||
|
|
@ -0,0 +1,237 @@
|
|||
#include <mex.h>
|
||||
#include <mat.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <ctime>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
|
||||
#define STRING_BUF_SIZE 204800
|
||||
|
||||
/* 读取二层cell包裹的字符串,和数值,ds,fr */
|
||||
#define OUTER_FOR_BEGIN \
|
||||
rowNum = (int)mxGetM(pMxArray); \
|
||||
colNum = (int)mxGetN(pMxArray); \
|
||||
for (int i = 0; i < rowNum; ++i) { \
|
||||
for (int j = 0; j < colNum; ++j) { \
|
||||
mxArray* pCell = mxGetCell(pMxArray, j * rowNum + i); \
|
||||
int childRowNum = (int)mxGetM(pCell); \
|
||||
int childColNum = (int)mxGetN(pCell);
|
||||
|
||||
#define OUTER_FOR_END \
|
||||
} \
|
||||
}
|
||||
|
||||
#define INNTER_FOR_BEGIN \
|
||||
for (int ii = 0; ii < childRowNum; ii++) { \
|
||||
for (int jj = 0; jj < childColNum; jj++) { \
|
||||
mxArray *pChildCell = mxGetCell(pCell, jj * childRowNum + ii);
|
||||
#define INNTER_FOR_END \
|
||||
} \
|
||||
}
|
||||
// 将matlab存储方式转换成c存储方式
|
||||
#define TRANS_ROW_COL(dst, src, rowNum, colNum) \
|
||||
for (int rowI = 0; rowI < rowNum; ++rowI) { \
|
||||
for (int colJ = 0; colJ < colNum; ++colJ) { \
|
||||
dst[rowI * colNum + colJ] = src[colJ * rowNum + rowI]; \
|
||||
} \
|
||||
}
|
||||
// 将二维索引转成一维的索引
|
||||
inline int Get1DIndex(int colNum, int row, int col) {
|
||||
return row * colNum + col;
|
||||
}
|
||||
|
||||
// 读取G结构体中的ds和fr
|
||||
void GetFrDs(const mxArray* pMxParent, vector<vector<string> >& vvDs, vector<vector<double> >& vvFr) {
|
||||
// 读取ds字符串
|
||||
int rowNum, colNum;
|
||||
char *strBuf = new char[STRING_BUF_SIZE];
|
||||
mxArray* pMxArray = mxGetField(pMxParent, 0, "ds"); // ds
|
||||
OUTER_FOR_BEGIN
|
||||
vvDs.push_back(vector<string>());
|
||||
vvDs.back().resize(childRowNum * childColNum);
|
||||
INNTER_FOR_BEGIN
|
||||
if (mxGetString(pChildCell, strBuf, STRING_BUF_SIZE) != 0) {
|
||||
cout << "String is too large to fit in the buffer! " << i + 1 << '\t' << j + 1 << endl;
|
||||
delete[]strBuf;
|
||||
return;
|
||||
}
|
||||
vvDs.back()[ii * childColNum + jj] = strBuf;
|
||||
auto& lastStr = vvDs.back()[ii * childColNum + jj];
|
||||
transform(lastStr.begin(), lastStr.end(), lastStr.begin(), ::toupper); // 转成大写
|
||||
INNTER_FOR_END
|
||||
OUTER_FOR_END
|
||||
|
||||
// 读取fr数值
|
||||
pMxArray = mxGetField(pMxParent, 0, "fr"); // fr
|
||||
OUTER_FOR_BEGIN
|
||||
vvFr.push_back(vector<double>());
|
||||
vvFr.back().resize(childRowNum * childColNum);
|
||||
double* pVal = (double*)mxGetData(pCell); //获取指针
|
||||
TRANS_ROW_COL(vvFr.back(), pVal, childRowNum, childColNum); // 行列存储方式转换
|
||||
OUTER_FOR_END
|
||||
delete[]strBuf;
|
||||
}
|
||||
|
||||
/* 读取abs */
|
||||
void GetAbstract(const mxArray* pMxAbs, vector<string>& vAbs) {
|
||||
int rowNum = (int)mxGetM(pMxAbs);
|
||||
int colNum = (int)mxGetN(pMxAbs);
|
||||
char *strBuf = new char[STRING_BUF_SIZE];
|
||||
|
||||
vAbs.resize(rowNum * colNum);
|
||||
for (int i = 0; i < rowNum; ++i) {
|
||||
for (int j = 0; j < colNum; ++j) {
|
||||
mxArray* pCell = mxGetCell(pMxAbs, j * rowNum + i);
|
||||
if (mxGetString(pCell, strBuf, STRING_BUF_SIZE) != 0) {
|
||||
cout << "String is too large to fit in the buffer! " << i + 1 << '\t' << j + 1 << endl;
|
||||
delete[]strBuf;
|
||||
return;
|
||||
}
|
||||
vAbs[i * colNum + j] = strBuf;
|
||||
}
|
||||
}
|
||||
delete[]strBuf;
|
||||
}
|
||||
|
||||
/*
|
||||
nlhs:输出参数数目(Number Left - hand side),等号左边
|
||||
plhs:指向输出参数的指针(Point Left - hand side),等号左边
|
||||
nrhs:输入参数数目(Number Right - hand side),等号右边
|
||||
prhs:指向输入参数的指针(Point Right - hand side),等号右边。要注意prhs是const的指针数组,即不能改变其指向内容。
|
||||
*/
|
||||
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
|
||||
//cout << "MexCalcEntropy" << endl;
|
||||
//cout << nlhs << '\t' << nrhs << endl;
|
||||
if (nrhs != 2) {
|
||||
cout << "2 arguments should be given for this function!" << endl;
|
||||
return;
|
||||
}
|
||||
clock_t begin, finish;
|
||||
begin = clock();
|
||||
vector<vector<string> > vvDs; // 每个知识颗粒的ds矩阵(词汇矩阵)
|
||||
vector<vector<double> > vvFr; // 词汇对应的频率
|
||||
GetFrDs(prhs[1], vvDs, vvFr);
|
||||
|
||||
vector<string> vAbstract; // 读取abs1, 然后分割成一个一个的单词
|
||||
GetAbstract(prhs[0], vAbstract);
|
||||
|
||||
/* 将摘要信息分割成一个一个的词汇 */
|
||||
// begin = clock();
|
||||
unordered_set<char> usWordChars; // 能组成单词的字符,要不要考虑数字?原版matlab是提取了数字的
|
||||
for (int i = 65; i <= 90; i++) usWordChars.insert(char(i)); // A - Z
|
||||
for (int i = 97; i <= 122; i++) usWordChars.insert(char(i)); // a - z
|
||||
for (int i = 48; i <= 57; i++) usWordChars.insert(char(i)); // 0 - 9
|
||||
usWordChars.insert('/'); usWordChars.insert('+'); usWordChars.insert('-');
|
||||
vector<vector<string> > vvWordMtx(vAbstract.size()); // 初始大小为文章的个数
|
||||
vector<unordered_set<string> > vusAbsWord(vAbstract.size()); // 将每篇文章摘要的单词放入hash表
|
||||
for (int i = 0; i < vAbstract.size(); i++) {
|
||||
auto& strAbs = vAbstract[i];
|
||||
// 遍历摘要字符串的每一个字符,取出每一个单词
|
||||
vector<string>& vWord = vvWordMtx[i];
|
||||
if (strAbs.size() == 0) continue; // 摘要信息为空,跳过(一般不会出现这个情况)
|
||||
int wordStartPos = 0;
|
||||
while (wordStartPos < strAbs.size() && usWordChars.find(strAbs[wordStartPos]) == usWordChars.end())
|
||||
wordStartPos++;
|
||||
for (int curPos = wordStartPos + 1; curPos < strAbs.size(); ++curPos) {
|
||||
if (usWordChars.find(strAbs[curPos]) == usWordChars.end()) { // 找到了分割符
|
||||
vWord.push_back(strAbs.substr(wordStartPos, curPos - wordStartPos));
|
||||
wordStartPos = curPos + 1; // 找下一个词语起始位置
|
||||
while (wordStartPos < strAbs.size() && usWordChars.find(strAbs[wordStartPos]) == usWordChars.end())
|
||||
wordStartPos++;
|
||||
curPos = wordStartPos; // 循环会自动加1
|
||||
}
|
||||
}
|
||||
// 将处理摘要之后的每个词语放入hash表
|
||||
for (auto& word : vWord) {
|
||||
string upWord(word);
|
||||
transform(upWord.begin(), upWord.end(), upWord.begin(), ::toupper);
|
||||
vusAbsWord[i].insert(upWord);
|
||||
}
|
||||
}
|
||||
// finish = clock();
|
||||
// cout << "Split abstract time: " << (double)(finish - begin) / CLOCKS_PER_SEC << " s" << endl;
|
||||
|
||||
// 存放结果,用一维数组存放二维数据
|
||||
vector<double> hs;
|
||||
vector<double> hr;
|
||||
const int numLiterature = vusAbsWord.size(); // pubmed 文件中包含的文献数量
|
||||
const int numGroup = vvDs.size(); // ds包含的组数
|
||||
hs.resize(numGroup * numLiterature);
|
||||
hr.resize(numLiterature * numGroup);
|
||||
|
||||
for (int groupIdx = 0; groupIdx < numGroup; ++groupIdx) { // 遍历知识颗粒中的每一组
|
||||
vector<string>& vDs = vvDs[groupIdx]; // 这一组ds
|
||||
vector<double>& vFr = vvFr[groupIdx]; // frequency
|
||||
const int numWord = vDs.size(); // 这一组数据中包含的单词数量
|
||||
vector<vector<int> > vX(numLiterature, vector<int>(numWord, 0));
|
||||
// 检查知识颗粒中的词语是否出现在pubmed摘要的词语中
|
||||
for (int i = 0; i < numLiterature; ++i) {
|
||||
for (int j = 0; j < numWord; ++j) {
|
||||
if (vusAbsWord[i].find(vDs[j]) != vusAbsWord[i].end()) { // 这一组单词中的j索引位置的单词在第i个文献中出现过
|
||||
vX[i][j] = 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 找词汇的最高频率
|
||||
double maxFr = *max_element(vFr.begin(), vFr.end());
|
||||
// 将fr的数值规范化到(0,0.368)之间
|
||||
const double normalMax = 0.368;
|
||||
for (auto& frVal : vFr) frVal = frVal * normalMax / maxFr;
|
||||
maxFr = normalMax;
|
||||
// 对每个知识颗粒每一组数据,计算信息熵
|
||||
for (int i = 0; i < numLiterature; ++i) {
|
||||
for (int j = 0; j < numWord; ++j) {
|
||||
if (vX[i][j] == 1) {
|
||||
hs[Get1DIndex(numLiterature, groupIdx, i)] -= vFr[j] * log2(vFr[j]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 找最高频词汇所在的索引位置
|
||||
vector<int> vMaxPos;
|
||||
int idx = 0;
|
||||
for_each(vFr.begin(), vFr.end(), [&idx, maxFr, &vMaxPos](double val) {
|
||||
if (val == maxFr) vMaxPos.push_back(idx);
|
||||
idx++;
|
||||
});
|
||||
|
||||
for (int i = 0; i < numLiterature; ++i) {
|
||||
int cumulateX = 0; // 计算在最高频词汇处,x值的累加结果
|
||||
for (int j = 0; j < vMaxPos.size(); ++j) cumulateX += vX[i][vMaxPos[j]];
|
||||
if (cumulateX == vMaxPos.size()) { // 如果频率最高的词汇都出现在了文献中
|
||||
hr[Get1DIndex(numGroup, i, groupIdx)] = 1; // 应该是表示知识颗粒的这一组数据跟这篇文献相关性比较高
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 将结果写入返回值 */
|
||||
if (nlhs > 0) {
|
||||
int datasize = numGroup * numLiterature;
|
||||
double* mtxData = new double[datasize];//待存储数据转为double格式
|
||||
mxArray* pWriteArray = NULL;//matlab格式矩阵
|
||||
//创建一个rowNum*colNum的矩阵
|
||||
pWriteArray = mxCreateDoubleMatrix(numGroup, numLiterature, mxREAL);
|
||||
for (int i = 0; i < numGroup; i++) {
|
||||
for (int j = 0; j < numLiterature; j++) {
|
||||
mtxData[j * numGroup + i] = hs[i * numLiterature + j];
|
||||
}
|
||||
}
|
||||
//把data的值赋给pWriteArray指针
|
||||
memcpy((void*)(mxGetPr(pWriteArray)), (void*)mtxData, sizeof(double) * datasize);
|
||||
plhs[0] = pWriteArray; // 赋值给返回值
|
||||
delete[]mtxData;
|
||||
}
|
||||
finish = clock();
|
||||
// cout << "CalcEntropy Total time: " << (double)(finish - begin) / CLOCKS_PER_SEC << " s" << endl;
|
||||
}
|
||||
|
||||
/* 供main调试调用 */
|
||||
void MexCalcEntropy(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
|
||||
mexFunction(nlhs, plhs, nrhs, prhs);
|
||||
}
|
||||
|
|
@ -0,0 +1,224 @@
|
|||
#include <mex.h>
|
||||
#include <mat.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <ctime>
|
||||
#include <immintrin.h>
|
||||
#include <zmmintrin.h>
|
||||
#include "CommonLib/kthread.h"
|
||||
#include "CommonLib/thread_pool.h"
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
|
||||
// 线程参数
|
||||
struct TPCorDist {
|
||||
vector<vector<float>>* pvvX;
|
||||
vector<double>* pvDist;
|
||||
vector<double>* pvSq;
|
||||
int rowIdxStart;
|
||||
int rowIdxEnd;
|
||||
int rowNum;
|
||||
int colNum;
|
||||
};
|
||||
|
||||
// 线程函数
|
||||
void ThreadCalcDist(TPCorDist& param) {
|
||||
vector<vector<float>>& vvX = *param.pvvX;
|
||||
vector<double>& vDist = *param.pvDist;
|
||||
vector<double>& vSq = *param.pvSq;
|
||||
int rowIdxStart = param.rowIdxStart;
|
||||
int rowIdxEnd = param.rowIdxEnd;
|
||||
int rowNum = param.rowNum;
|
||||
int colNum = param.colNum;
|
||||
double uv = 0;
|
||||
clock_t begin = clock(), finish;
|
||||
__m256 vec_zero = _mm256_set1_ps(0);
|
||||
for (int i = rowIdxStart; i < rowIdxEnd; ++i) {
|
||||
const int baseIdx = i * (rowNum * 2 - i - 1) / 2;
|
||||
for (int cur = i + 1, idx = 0; cur < rowNum; ++cur, ++idx) {
|
||||
double uv = 0;
|
||||
//for (int j = 0; j < colNum; ++j) { uv += vvX[i][j] * vvX[cur][j]; }
|
||||
__m256 vec_uv = vec_zero;
|
||||
int colNum8 = colNum / 8 * 8;
|
||||
int remain = colNum - colNum8;
|
||||
for (int j = 0; j < colNum8; j += 8) {
|
||||
__m256 vec_u = _mm256_loadu_ps(vvX[i].data() + j);
|
||||
__m256 vec_v = _mm256_loadu_ps(vvX[cur].data() + j);
|
||||
vec_uv = _mm256_add_ps(_mm256_mul_ps(vec_u, vec_v), vec_uv);
|
||||
}
|
||||
for (int j = colNum8; j < colNum; ++j) {
|
||||
uv += vvX[i][j] * vvX[cur][j];
|
||||
}
|
||||
float* pVec = (float*)&vec_uv;
|
||||
for (int j = 0; j < 8; ++j) uv += pVec[j];
|
||||
|
||||
uv /= colNum;
|
||||
const double dist = abs(1.0 - uv / sqrt(vSq[i] * vSq[cur]));
|
||||
vDist[baseIdx + idx] = dist;
|
||||
}
|
||||
}
|
||||
finish = clock();
|
||||
//cout << rowIdxEnd << " Thread time: " << (double)(finish - begin) / CLOCKS_PER_SEC << " s" << endl;
|
||||
}
|
||||
|
||||
/* 入口函数 */
|
||||
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, mxArray** prhs) {
|
||||
//cout << "WordSplit" << endl;
|
||||
//cout << nlhs << '\t' << nrhs << endl;
|
||||
//if (nrhs < 1) {
|
||||
// cout << "At least 1 arguments should be given for this function!" << endl;
|
||||
// return;
|
||||
//}
|
||||
clock_t begin = clock(), mid, finish;
|
||||
|
||||
int rowNum = (int)mxGetM(prhs[0]);
|
||||
int colNum = (int)mxGetN(prhs[0]);
|
||||
double* pData = (double*)mxGetData(prhs[0]);
|
||||
//
|
||||
//int numThread = 1;
|
||||
//if (nrhs > 1) {
|
||||
// double* pNumThread = (double*)mxGetData(prhs[1]);
|
||||
// numThread = (int)*pNumThread;
|
||||
// if (numThread < 1) numThread = 1;
|
||||
//}
|
||||
|
||||
|
||||
//for (int i = 0; i < rowNum; ++i) {
|
||||
// for (int j = 0; j < colNum; ++j) {
|
||||
// cout << pData[j * rowNum + i] << '\t';
|
||||
// }
|
||||
// cout << endl;
|
||||
//}
|
||||
|
||||
// int rowNum = 2;
|
||||
// int colNum = 5;
|
||||
// vector<double> pData = { 1,1,2,2,3,9,4,4,5,4 };
|
||||
|
||||
cout << rowNum << '\t' << colNum << endl;
|
||||
|
||||
/* 计算每一行的平均数 */
|
||||
mid = clock();
|
||||
vector<double> vMean(rowNum);
|
||||
for (int j = 0; j < colNum; ++j) {
|
||||
for (int i = 0; i < rowNum; ++i) {
|
||||
vMean[i] += pData[j * rowNum + i];
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < rowNum; ++i) {
|
||||
vMean[i] /= colNum;
|
||||
}
|
||||
finish = clock();
|
||||
cout << "计算平均数: " << (double)(finish - mid) / CLOCKS_PER_SEC << " s" << endl;
|
||||
/* 减去平均值, 计算平方 */
|
||||
mid = clock();
|
||||
vector<vector<float>> vvX(rowNum, vector<float>(colNum));
|
||||
vector<double> vSq(rowNum);
|
||||
for (int i = 0; i < rowNum; ++i) {
|
||||
for (int j = 0; j < colNum; ++j) {
|
||||
vvX[i][j] = pData[j * rowNum + i] - vMean[i];
|
||||
vSq[i] += vvX[i][j] * vvX[i][j];
|
||||
}
|
||||
}
|
||||
for (auto& val : vSq) { val /= colNum; }
|
||||
finish = clock();
|
||||
cout << "计算平方: " << (double)(finish - mid) / CLOCKS_PER_SEC << " s" << endl;
|
||||
|
||||
/* 计算相关距离 */
|
||||
// clock_t mid0 = clock();
|
||||
// const int distSize = rowNum * (rowNum - 1) / 2;
|
||||
// const int row2 = 2 * rowNum;
|
||||
// vector<double> vDist(distSize, 0.0);
|
||||
// //__m256d vec_zero = _mm256_set1_pd(0);
|
||||
// __m256 vec_zero = _mm256_set1_ps(0);
|
||||
// for (int i = 0; i < rowNum; ++i) {
|
||||
// if (i % 100 == 0) {
|
||||
// finish = clock();
|
||||
// cout << "time " << i << ": " << (double)(finish - mid) / CLOCKS_PER_SEC << " s; " <<
|
||||
// (double)(finish - begin) / CLOCKS_PER_SEC << " s" << endl;
|
||||
// mid = clock();
|
||||
// }
|
||||
// const int baseIdx = i * (row2 - i - 1) / 2;
|
||||
// for (int cur = i + 1, idx = 0; cur < rowNum; ++cur, ++idx) {
|
||||
// double uv = 0;
|
||||
// //for (int j = 0; j < colNum; ++j) { uv += vvX[i][j] * vvX[cur][j]; }
|
||||
// //__m256d vec_uv = vec_zero;
|
||||
// //int colNum4 = colNum / 4 * 4;
|
||||
// //int remain = colNum - colNum4;
|
||||
// //for (int j = 0; j < colNum4; j += 4) {
|
||||
// // __m256d vec_u = _mm256_loadu_pd(vvX[i].data() + j);
|
||||
// // __m256d vec_v = _mm256_loadu_pd(vvX[cur].data() + j);
|
||||
// // vec_uv = _mm256_add_pd(_mm256_mul_pd(vec_u, vec_v), vec_uv);
|
||||
// //}
|
||||
// //for (int j = colNum4; j < colNum; ++j) {
|
||||
// // uv += vvX[i][j] * vvX[cur][j];
|
||||
// //}
|
||||
// //double* pVec = (double*)&vec_uv;
|
||||
// //for (int j = 0; j < 4; ++j) uv += pVec[j];
|
||||
//
|
||||
// __m256 vec_uv = vec_zero;
|
||||
// int colNum8 = colNum / 8 * 8;
|
||||
// int remain = colNum - colNum8;
|
||||
// for (int j = 0; j < colNum8; j += 8) {
|
||||
// __m256 vec_u = _mm256_loadu_ps(vvX[i].data() + j);
|
||||
// __m256 vec_v = _mm256_loadu_ps(vvX[cur].data() + j);
|
||||
// vec_uv = _mm256_add_ps(_mm256_mul_ps(vec_u, vec_v), vec_uv);
|
||||
// }
|
||||
// for (int j = colNum8; j < colNum; ++j) {
|
||||
// uv += vvX[i][j] * vvX[cur][j];
|
||||
// }
|
||||
// float* pVec = (float*)&vec_uv;
|
||||
// for (int j = 0; j < 8; ++j) uv += pVec[j];
|
||||
//
|
||||
// uv /= colNum;
|
||||
// const double dist = abs(1.0 - uv / sqrt(vSq[i] * vSq[cur]));
|
||||
// vDist[baseIdx + idx] = dist;
|
||||
// }
|
||||
// }
|
||||
// finish = clock();
|
||||
// cout << "计算相关距离: " << (double)(finish - mid0) / CLOCKS_PER_SEC << " s" << endl;
|
||||
// for (auto& val : vDist) {cout << val << endl;}
|
||||
|
||||
/* 多线程计算相关距离 */
|
||||
const int distSize = rowNum * (rowNum - 1) / 2;
|
||||
const int row2 = 2 * rowNum;
|
||||
vector<double> vDist(distSize, 0.0);
|
||||
mid = clock();
|
||||
vector<TPCorDist> vTP;
|
||||
ThreadPool thPool(6);
|
||||
int span = 32;
|
||||
int rowNumSpan = rowNum / span * span;
|
||||
int i = 0;
|
||||
for (i = 0; i < rowNumSpan; i += span) {
|
||||
// vTP.push_back({&vvX, &vDist, &vSq, i, rowNum, colNum});
|
||||
TPCorDist tp = { &vvX, &vDist, &vSq, i, i + span, rowNum, colNum };
|
||||
thPool.enqueue(ThreadCalcDist, tp);
|
||||
//vTP.push_back(tp);
|
||||
}
|
||||
if (i < rowNum) {
|
||||
TPCorDist tp = { &vvX, &vDist, &vSq, i, rowNum, rowNum, colNum };
|
||||
thPool.enqueue(ThreadCalcDist, tp);
|
||||
//vTP.push_back(tp);
|
||||
}
|
||||
thPool.~ThreadPool();
|
||||
//kt_for(6, ThreadCalcDist, vTP);
|
||||
|
||||
finish = clock();
|
||||
cout << "多线程计算相关距离: " << (double)(finish - mid) / CLOCKS_PER_SEC << " s" << endl;
|
||||
// for (auto& val : vDist) {cout << val << endl;}
|
||||
|
||||
/* 写入结果 */
|
||||
if (nlhs > 0) { // b
|
||||
mxArray* pWriteArray = NULL;
|
||||
//创建一个rowNum*colNum的矩阵
|
||||
pWriteArray = mxCreateDoubleMatrix(1, distSize, mxREAL);
|
||||
memcpy((void*)(mxGetPr(pWriteArray)), (void*)vDist.data(), sizeof(double) * 6);
|
||||
plhs[0] = pWriteArray; // 赋值给返回值
|
||||
}
|
||||
|
||||
finish = clock();
|
||||
cout << "Correlation Dist Total time: " << (double)(finish - begin) / CLOCKS_PER_SEC << " s" << endl;
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,146 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project DefaultTargets="Build" ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props')" />
|
||||
<PropertyGroup Label="Globals">
|
||||
<CppWinRTOptimized>true</CppWinRTOptimized>
|
||||
<CppWinRTRootNamespaceAutoMerge>true</CppWinRTRootNamespaceAutoMerge>
|
||||
<CppWinRTGenerateWindowsMetadata>true</CppWinRTGenerateWindowsMetadata>
|
||||
<MinimalCoreWin>true</MinimalCoreWin>
|
||||
<VCProjectVersion>15.0</VCProjectVersion>
|
||||
<ProjectGuid>{9f23b7f6-612c-41e6-8aaa-75c26b8ea6ad}</ProjectGuid>
|
||||
<Keyword>Win32Proj</Keyword>
|
||||
<RootNamespace>MexFunc</RootNamespace>
|
||||
<WindowsTargetPlatformVersion Condition=" '$(WindowsTargetPlatformVersion)' == '' ">10.0.18362.0</WindowsTargetPlatformVersion>
|
||||
<WindowsTargetPlatformMinVersion>10.0.17134.0</WindowsTargetPlatformMinVersion>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
|
||||
<ItemGroup Label="ProjectConfigurations">
|
||||
<ProjectConfiguration Include="Debug|Win32">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|Win32">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>Win32</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Debug|x64">
|
||||
<Configuration>Debug</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
<ProjectConfiguration Include="Release|x64">
|
||||
<Configuration>Release</Configuration>
|
||||
<Platform>x64</Platform>
|
||||
</ProjectConfiguration>
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Configuration">
|
||||
<ConfigurationType>Application</ConfigurationType>
|
||||
<PlatformToolset>v143</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '16.0'">v142</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '15.0'">v141</PlatformToolset>
|
||||
<PlatformToolset Condition="'$(VisualStudioVersion)' == '14.0'">v140</PlatformToolset>
|
||||
<CharacterSet>Unicode</CharacterSet>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Debug'" Label="Configuration">
|
||||
<UseDebugLibraries>true</UseDebugLibraries>
|
||||
<LinkIncremental>true</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup Condition="'$(Configuration)'=='Release'" Label="Configuration">
|
||||
<UseDebugLibraries>false</UseDebugLibraries>
|
||||
<WholeProgramOptimization>true</WholeProgramOptimization>
|
||||
<LinkIncremental>false</LinkIncremental>
|
||||
</PropertyGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
|
||||
<ImportGroup Label="ExtensionSettings">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="Shared">
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
|
||||
</ImportGroup>
|
||||
<ImportGroup Label="PropertySheets">
|
||||
<Import Project="PropertySheet.props" />
|
||||
</ImportGroup>
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
<PrecompiledHeader>NotUsing</PrecompiledHeader>
|
||||
<PrecompiledHeaderFile>pch.h</PrecompiledHeaderFile>
|
||||
<PrecompiledHeaderOutputFile>$(IntDir)pch.pch</PrecompiledHeaderOutputFile>
|
||||
<PreprocessorDefinitions>_CONSOLE;WIN32_LEAN_AND_MEAN;WINRT_LEAN_AND_MEAN;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<WarningLevel>Level4</WarningLevel>
|
||||
<AdditionalOptions>%(AdditionalOptions) /permissive- /bigobj</AdditionalOptions>
|
||||
</ClCompile>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Debug'">
|
||||
<ClCompile>
|
||||
<Optimization>Disabled</Optimization>
|
||||
<PreprocessorDefinitions>_DEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">$(SolutionDir);D:\matlab2023a\extern\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
<AdditionalLibraryDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">D:\matlab2023a\extern\lib\win64\microsoft;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|x64'">CommonLib.lib;libeng.lib;libmx.lib;libmex.lib;libmat.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Platform)'=='Win32'">
|
||||
<ClCompile>
|
||||
<PreprocessorDefinitions>WIN32;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">$(SolutionDir);D:\matlab2023a\extern\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<AdditionalLibraryDirectories Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">D:\matlab2023a\extern\lib\win64\microsoft;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">CommonLib.lib;libeng.lib;libmx.lib;libmex.lib;libmat.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemDefinitionGroup Condition="'$(Configuration)'=='Release'">
|
||||
<ClCompile>
|
||||
<Optimization>MaxSpeed</Optimization>
|
||||
<FunctionLevelLinking>true</FunctionLevelLinking>
|
||||
<IntrinsicFunctions>true</IntrinsicFunctions>
|
||||
<PreprocessorDefinitions>NDEBUG;%(PreprocessorDefinitions)</PreprocessorDefinitions>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">$(SolutionDir);D:\matlab2023a\extern\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<AdditionalIncludeDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">$(SolutionDir);D:\matlab2023a\extern\include;%(AdditionalIncludeDirectories)</AdditionalIncludeDirectories>
|
||||
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
|
||||
<EnableEnhancedInstructionSet Condition="'$(Configuration)|$(Platform)'=='Release|x64'">AdvancedVectorExtensions2</EnableEnhancedInstructionSet>
|
||||
</ClCompile>
|
||||
<Link>
|
||||
<SubSystem>Console</SubSystem>
|
||||
<EnableCOMDATFolding>true</EnableCOMDATFolding>
|
||||
<OptimizeReferences>true</OptimizeReferences>
|
||||
<GenerateWindowsMetadata>false</GenerateWindowsMetadata>
|
||||
<AdditionalLibraryDirectories Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">D:\matlab2023a\extern\lib\win64\microsoft;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalLibraryDirectories Condition="'$(Configuration)|$(Platform)'=='Release|x64'">D:\matlab2023a\extern\lib\win64\microsoft;$(OutDir);%(AdditionalLibraryDirectories)</AdditionalLibraryDirectories>
|
||||
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">CommonLib.lib;libeng.lib;libmx.lib;libmex.lib;libmat.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
<AdditionalDependencies Condition="'$(Configuration)|$(Platform)'=='Release|x64'">CommonLib.lib;libeng.lib;libmx.lib;libmex.lib;libmat.lib;%(AdditionalDependencies)</AdditionalDependencies>
|
||||
</Link>
|
||||
</ItemDefinitionGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="CorrelationDist.cpp" />
|
||||
<ClCompile Include="main.cpp" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="PropertySheet.props" />
|
||||
<Text Include="readme.md">
|
||||
<DeploymentContent>false</DeploymentContent>
|
||||
</Text>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="mex_func.h" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
<Import Project="..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets" Condition="Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets')" />
|
||||
</ImportGroup>
|
||||
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
|
||||
<PropertyGroup>
|
||||
<ErrorText>这台计算机上缺少此项目引用的 NuGet 程序包。使用“NuGet 程序包还原”可下载这些程序包。有关更多信息,请参见 http://go.microsoft.com/fwlink/?LinkID=322105。缺少的文件是 {0}。</ErrorText>
|
||||
</PropertyGroup>
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.props'))" />
|
||||
<Error Condition="!Exists('..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\packages\Microsoft.Windows.CppWinRT.2.0.210806.1\build\native\Microsoft.Windows.CppWinRT.targets'))" />
|
||||
</Target>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ItemGroup>
|
||||
<Filter Include="Source Files">
|
||||
<UniqueIdentifier>{4FC737F1-C7A5-4376-A066-2A32D752A2FF}</UniqueIdentifier>
|
||||
<Extensions>cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Header Files">
|
||||
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
|
||||
<Extensions>h;hh;hpp;hxx;hm;inl;inc;xsd</Extensions>
|
||||
</Filter>
|
||||
<Filter Include="Resource Files">
|
||||
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
|
||||
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
|
||||
</Filter>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClCompile Include="main.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="CorrelationDist.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="PropertySheet.props" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="readme.md" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="mex_func.h">
|
||||
<Filter>Header Files</Filter>
|
||||
</ClInclude>
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,16 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
|
||||
<ImportGroup Label="PropertySheets" />
|
||||
<PropertyGroup Label="UserMacros" />
|
||||
<!--
|
||||
To customize common C++/WinRT project properties:
|
||||
* right-click the project node
|
||||
* expand the Common Properties item
|
||||
* select the C++/WinRT property page
|
||||
|
||||
For more advanced scenarios, and complete documentation, please see:
|
||||
https://github.com/Microsoft/cppwinrt/tree/master/nuget
|
||||
-->
|
||||
<PropertyGroup />
|
||||
<ItemDefinitionGroup />
|
||||
</Project>
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
#include <mex.h>
|
||||
#include <mat.h>
|
||||
#include <iostream>
|
||||
#include <algorithm>
|
||||
#include <vector>
|
||||
#include <string>
|
||||
#include <unordered_set>
|
||||
#include <ctime>
|
||||
using std::cout;
|
||||
using std::endl;
|
||||
using namespace std;
|
||||
|
||||
#define STRING_BUF_SIZE 204800
|
||||
|
||||
/* 读取abs */
|
||||
void GetAbstract(const mxArray* pMxAbs, vector<string>& vAbs) {
|
||||
int rowNum = (int)mxGetM(pMxAbs);
|
||||
int colNum = (int)mxGetN(pMxAbs);
|
||||
char *strBuf = new char[STRING_BUF_SIZE];
|
||||
|
||||
vAbs.resize(rowNum * colNum);
|
||||
for (int i = 0; i < rowNum; ++i) {
|
||||
for (int j = 0; j < colNum; ++j) {
|
||||
mxArray* pCell = mxGetCell(pMxAbs, j * rowNum + i);
|
||||
if (mxGetString(pCell, strBuf, STRING_BUF_SIZE) != 0) {
|
||||
cout << "String is too large to fit in the buffer! " << i + 1 << '\t' << j + 1 << endl;
|
||||
delete[]strBuf;
|
||||
return;
|
||||
}
|
||||
vAbs[i * colNum + j] = strBuf;
|
||||
}
|
||||
}
|
||||
delete[]strBuf;
|
||||
}
|
||||
|
||||
/*
|
||||
nlhs:输出参数数目(Number Left - hand side),等号左边
|
||||
plhs:指向输出参数的指针(Point Left - hand side),等号左边
|
||||
nrhs:输入参数数目(Number Right - hand side),等号右边
|
||||
prhs:指向输入参数的指针(Point Right - hand side),等号右边。要注意prhs是const的指针数组,即不能改变其指向内容。
|
||||
*/
|
||||
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, const mxArray* prhs[]) {
|
||||
//cout << "WordSplit" << endl;
|
||||
//cout << nlhs << '\t' << nrhs << endl;
|
||||
if (nrhs != 1) {
|
||||
cout << "1 arguments should be given for this function!" << endl;
|
||||
return;
|
||||
}
|
||||
|
||||
/* 读取参数中的摘要信息 */
|
||||
vector<string> vAbstract; // 读取abs1, 然后分割成一个一个的单词
|
||||
GetAbstract(prhs[0], vAbstract);
|
||||
|
||||
/* 将摘要信息分割成一个一个的词汇 */
|
||||
clock_t begin, finish;
|
||||
begin = clock();
|
||||
unordered_set<char> usWordChars; // 能组成单词的字符,要不要考虑数字?原版matlab是提取了数字的
|
||||
for (int i = 65; i <= 90; i++) usWordChars.insert(char(i)); // A - Z
|
||||
for (int i = 97; i <= 122; i++) usWordChars.insert(char(i)); // a - z
|
||||
for (int i = 48; i <= 57; i++) usWordChars.insert(char(i)); // 0 - 9
|
||||
usWordChars.insert('/'); usWordChars.insert('+'); usWordChars.insert('-');
|
||||
vector<vector<string> > vvWordMtx(vAbstract.size()); // 初始大小为文章的个数
|
||||
for (int i = 0; i < vAbstract.size(); i++) {
|
||||
auto& strAbs = vAbstract[i];
|
||||
// 遍历摘要字符串的每一个字符,取出每一个单词
|
||||
vector<string>& vWord = vvWordMtx[i];
|
||||
if (strAbs.size() == 0) continue; // 摘要信息为空,跳过(一般不会出现这个情况)
|
||||
int wordStartPos = 0;
|
||||
while (wordStartPos < strAbs.size() && usWordChars.find(strAbs[wordStartPos]) == usWordChars.end())
|
||||
wordStartPos++;
|
||||
for (int curPos = wordStartPos + 1; curPos < strAbs.size(); ++curPos) {
|
||||
if (usWordChars.find(strAbs[curPos]) == usWordChars.end()) { // 找到了分割符
|
||||
vWord.push_back(strAbs.substr(wordStartPos, curPos - wordStartPos));
|
||||
wordStartPos = curPos + 1; // 找下一个词语起始位置
|
||||
while (wordStartPos < strAbs.size() && usWordChars.find(strAbs[wordStartPos]) == usWordChars.end())
|
||||
wordStartPos++;
|
||||
curPos = wordStartPos; // 循环会自动加1
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 将结果写入返回参数 */
|
||||
/* 将结果写入返回值 */
|
||||
if (nlhs > 0) {
|
||||
mxArray* pCellMtx = mxCreateCellMatrix(1, vvWordMtx.size());
|
||||
for (int i = 0; i < vvWordMtx.size(); ++i) {
|
||||
mxArray* pChildCellMtx = mxCreateCellMatrix(1, vvWordMtx[i].size());
|
||||
for (int j = 0; j < vvWordMtx[i].size(); ++j) {
|
||||
mxArray* mxStr = mxCreateString(vvWordMtx[i][j].c_str());
|
||||
mxSetCell(pChildCellMtx, j, mxStr);
|
||||
}
|
||||
mxSetCell(pCellMtx, i, pChildCellMtx);
|
||||
}
|
||||
plhs[0] = pCellMtx; // 赋值给返回值
|
||||
}
|
||||
|
||||
|
||||
finish = clock();
|
||||
//cout << "split abstract time: " << (double)(finish - begin) / CLOCKS_PER_SEC << " s" << endl;
|
||||
|
||||
}
|
||||
|
|
@ -0,0 +1,34 @@
|
|||
#include <iostream>
|
||||
#include <string>
|
||||
#include <vector>
|
||||
#include "mex_func.h"
|
||||
#include "CommonLib/matlab_io.h"
|
||||
using namespace std;
|
||||
|
||||
int main(int argc, const char** argv)
|
||||
{
|
||||
|
||||
string matFile = "D:\\x_large.mat";
|
||||
//string matFile = "D:\\x.mat";
|
||||
|
||||
MATFile* pMatFile = nullptr;
|
||||
mxArray* prhs[1];
|
||||
int rowNum, colNum;
|
||||
double* matData;
|
||||
pMatFile = matOpen(matFile.c_str(), "r"); //打开.mat文件
|
||||
if (pMatFile == nullptr) {
|
||||
cout << "filePath is error!" << endl;
|
||||
return 1;
|
||||
}
|
||||
prhs[0] = matGetVariable(pMatFile, "x"); //获取.mat文件里面名为matrixName的矩阵
|
||||
|
||||
mxArray* plhs = (mxArray*)malloc(sizeof(mxArray*));
|
||||
|
||||
mxArray** arg = &prhs[0];
|
||||
|
||||
mexFunction(1, &plhs, 1, arg);
|
||||
//mexFunction(0, 0, 0, 0);
|
||||
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -0,0 +1,3 @@
|
|||
#pragma once
|
||||
#include <mat.h>
|
||||
void mexFunction(int nlhs, mxArray* plhs[], int nrhs, mxArray** prhs);
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<packages>
|
||||
<package id="Microsoft.Windows.CppWinRT" version="2.0.210806.1" targetFramework="native" />
|
||||
</packages>
|
||||
|
|
@ -0,0 +1 @@
|
|||
# matlab可以直接调用的函数,mex编译
|
||||
|
|
@ -109,9 +109,7 @@
|
|||
<ItemGroup>
|
||||
<None Include="packages.config" />
|
||||
<None Include="PropertySheet.props" />
|
||||
<Text Include="readme.txt">
|
||||
<DeploymentContent>false</DeploymentContent>
|
||||
</Text>
|
||||
<None Include="readme.md" />
|
||||
</ItemGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
|
|
|
|||
|
|
@ -27,8 +27,6 @@
|
|||
<ItemGroup>
|
||||
<None Include="PropertySheet.props" />
|
||||
<None Include="packages.config" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Text Include="readme.txt" />
|
||||
<None Include="readme.md" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
17
Twirls.sln
17
Twirls.sln
|
|
@ -14,6 +14,11 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CppRun", "CppRun\CppRun.vcx
|
|||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "CommonLib", "CommonLib\CommonLib.vcxproj", "{C8434373-F2D6-459C-AC6D-79611ACEF9F5}"
|
||||
EndProject
|
||||
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "MexFunc", "MexFunc\MexFunc.vcxproj", "{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}"
|
||||
ProjectSection(ProjectDependencies) = postProject
|
||||
{C8434373-F2D6-459C-AC6D-79611ACEF9F5} = {C8434373-F2D6-459C-AC6D-79611ACEF9F5}
|
||||
EndProjectSection
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|ARM = Debug|ARM
|
||||
|
|
@ -72,6 +77,18 @@ Global
|
|||
{C8434373-F2D6-459C-AC6D-79611ACEF9F5}.Release|x64.Build.0 = Release|x64
|
||||
{C8434373-F2D6-459C-AC6D-79611ACEF9F5}.Release|x86.ActiveCfg = Release|Win32
|
||||
{C8434373-F2D6-459C-AC6D-79611ACEF9F5}.Release|x86.Build.0 = Release|Win32
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Debug|ARM.ActiveCfg = Debug|x64
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Debug|ARM.Build.0 = Debug|x64
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Debug|x64.ActiveCfg = Debug|x64
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Debug|x64.Build.0 = Debug|x64
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Debug|x86.ActiveCfg = Debug|Win32
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Debug|x86.Build.0 = Debug|Win32
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Release|ARM.ActiveCfg = Release|x64
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Release|ARM.Build.0 = Release|x64
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Release|x64.ActiveCfg = Release|x64
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Release|x64.Build.0 = Release|x64
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Release|x86.ActiveCfg = Release|Win32
|
||||
{9F23B7F6-612C-41E6-8AAA-75C26B8EA6AD}.Release|x86.Build.0 = Release|Win32
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
|
|||
Loading…
Reference in New Issue