gpt4 book ai didi

c++ - 在 C++ 中为 Matlab 准备矩阵

转载 作者:太空狗 更新时间:2023-10-29 20:42:12 25 4
gpt4 key购买 nike

我有一个维度为 dim*dim 的稀疏矩阵 P 作为指针通过

double* P

/* create the output matrix */
plhs[0] = mxCreateDoubleMatrix(dim,dim,mxREAL);

/* get a pointer to the real data in the output matrix*/
P = mxGetPr(plhs[0]);

我在 mex 文件中执行此操作,因为我需要大量 for 循环来填充 P,而 c++ 比 matlab 快得多。

目前,dim=22500,c++ 填充 P 大约需要 2 秒(使用 matlab 这个任务需要 50 秒),大约需要 100 秒在 matlab 中标准化矩阵,再次需要 100 秒来删除所有零列在 matlab 中。我在 matlab 中使用以下代码执行此操作:

for i=1:size(P,1)
if sum(P(i,:)) > 0
sum(P(i,:))
P(i,:)=(1/sum(P(i,:))).*P(i,:);
end
end

% clear empty rows and colunms
P(~any(P,2),:)=[];
P(:,~any(P))=[];

我现在的问题是:我也可以在 C++ 中执行此操作吗?我尝试通过以下方式在 C++ 中规范化 P:

int i;
int j;
int sum;
int get_idx(int x, int y, int rows) {
return x +y * rows;
}
/* NORMALIZE */
for(i = 0; i <dim; i++) {
sum=0;
for(j=0; j<dim;j++) {
sum = sum + P[get_idx(i,j,dim)];
}
if(sum > 0) {
for(j=0; j<dim;j++) {
P[get_idx(i,j,p_rows)]=P[get_idx(i,j,dim)]*(1/sum);
}
}
}

但出于某种原因,这段代码似乎并没有改变 P,而且这在 C++ 中大约需要 85 秒。有没有更快的方法也有效?另外,是否可以清除空行和空列?

最佳答案

为什么选择 C++?

在规范化之前清除空行/列 - 您不需要规范化空条目。

向量化归一化:

s = sum(P, 2);
valid = s > 0;
P( valid,: ) = bsxfun(@rdivide, P(valid,:), s(valid) );

哒哒!

太有趣了!


更新:关于减少行/列。
经过简短的调查后,我认为可以获得大约 3 倍的速度因子:

考虑这三个选项:

  1. P( ~any(P,2), :) = []; P( :, ~any(P,1) ) = [];
  2. P( :, ~any(P,1) ) = []; P( ~any(P,2), :) = [];
  3. P = P( 任意(P,2), 任意(P,1) );

测试这三个备选方案,您会发现第三个方案快约 3 倍,而第一个略微(但始终)比第二个慢。

为什么?
如果您还记得,Matlab 以列优先的方式将矩阵存储在内存中,因此在行之前消除列可以节省一些内存复制和重新分配。

然而,第一个和第二个备选方案复制和重新分配内存两次:一次用于行,一次用于列,而第三个备选方案只用了一次内存!

关于c++ - 在 C++ 中为 Matlab 准备矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19566787/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com