如何在 MATLAB 匿名函数中集成条件?
How to integrate conditions in a MATLAB anonymous function?
我下面的代码非常耗时,因为 A 矩阵很大 (150,000^2)。我可以将条件作为函数 @(x)
集成到 accumarray
中吗?这样我就可以对所有行 b
进行基于单元格的处理,而不必转换为 double
并应用条件?我认为它会快得多!非常感谢!
tic
[a b c]=find(A.'); %extract the positions of non-zero elements of A
add_sym=accumarray(b,c,[],@(x){x}); % re-arrange the values of same row b
add_r = [];
for i = 1:size(add_sym) % go through every row to check the conditions
r = vertcat(add_sym{i})'; % inverting cell into double vector
if size(r,2)==1 % and apply the 3 conditions for each row
add_r0 = 0;
elseif size(r,2) > 1 && any(r<2)== 0 % many 2s
add_r0 = r;
add_r0(1) = -2;
add_r0(end) = 2;
add_r0(2:end-1) = 0;
elseif size(r,2) > 1 && any(r<2)~= 0 % 2 and 1
k = find(diff(r)==-1); % find right 2 position
add_r0 = r;
add_r0(1) = -1;
add_r0(end) = -1;
add_r0(k) = 2;
add_r0(2:k-1) = 0;
add_r0(k+1:end-1) = 0;
end
add_r = [add_r; add_r0']; % saving the replaced values as vectors
end
ADD = sparse(b,a,add_r,nm,nm,nzmax); % put it back to the same position of sparse matrix A (with replaced value)
toc
此代码是为here
提出的问题编写的
原则上,您正在遍历稀疏 A 矩阵的行。显式提取行并进行检查可能更方便,而不是转换为单元格并返回。我的尝试:
% dummy A, contains 0, 1 or 2's at random
N = 1e4;
A = sparse(randi(2,[N,N])); % A contains 1's and 2's
A(rand([N,N])<0.8) = 0; % randomly delete 80%
tic
add_r = zeros([nnz(A),1]);
iter = 0;
for n=1:size(A,1)
tmp = A(n,:);
iter_incr = nnz(tmp);
if iter_incr==1 % no need to set add_r element to zero
%
elseif iter_incr>0
if ~any(tmp(tmp>0)<2)
add_r(iter+1) = -2;
add_r(iter+iter_incr) = 2;
else
add_r(iter+1) = -1;
add_r(iter+iter_incr) = -1;
add_r(iter+find(tmp(tmp>0)==2)) = 2;
end
end
% increment
iter = iter + iter_incr;
end
toc
这在我的笔记本电脑上运行大约 20 秒,几分钟后我不得不终止你的解决方案。请注意,我目前无法测试更大的矩阵,这是一个 10000 x 10000 的矩阵,可能与您的数据结构不太相似。
我下面的代码非常耗时,因为 A 矩阵很大 (150,000^2)。我可以将条件作为函数 @(x)
集成到 accumarray
中吗?这样我就可以对所有行 b
进行基于单元格的处理,而不必转换为 double
并应用条件?我认为它会快得多!非常感谢!
tic
[a b c]=find(A.'); %extract the positions of non-zero elements of A
add_sym=accumarray(b,c,[],@(x){x}); % re-arrange the values of same row b
add_r = [];
for i = 1:size(add_sym) % go through every row to check the conditions
r = vertcat(add_sym{i})'; % inverting cell into double vector
if size(r,2)==1 % and apply the 3 conditions for each row
add_r0 = 0;
elseif size(r,2) > 1 && any(r<2)== 0 % many 2s
add_r0 = r;
add_r0(1) = -2;
add_r0(end) = 2;
add_r0(2:end-1) = 0;
elseif size(r,2) > 1 && any(r<2)~= 0 % 2 and 1
k = find(diff(r)==-1); % find right 2 position
add_r0 = r;
add_r0(1) = -1;
add_r0(end) = -1;
add_r0(k) = 2;
add_r0(2:k-1) = 0;
add_r0(k+1:end-1) = 0;
end
add_r = [add_r; add_r0']; % saving the replaced values as vectors
end
ADD = sparse(b,a,add_r,nm,nm,nzmax); % put it back to the same position of sparse matrix A (with replaced value)
toc
此代码是为here
提出的问题编写的原则上,您正在遍历稀疏 A 矩阵的行。显式提取行并进行检查可能更方便,而不是转换为单元格并返回。我的尝试:
% dummy A, contains 0, 1 or 2's at random
N = 1e4;
A = sparse(randi(2,[N,N])); % A contains 1's and 2's
A(rand([N,N])<0.8) = 0; % randomly delete 80%
tic
add_r = zeros([nnz(A),1]);
iter = 0;
for n=1:size(A,1)
tmp = A(n,:);
iter_incr = nnz(tmp);
if iter_incr==1 % no need to set add_r element to zero
%
elseif iter_incr>0
if ~any(tmp(tmp>0)<2)
add_r(iter+1) = -2;
add_r(iter+iter_incr) = 2;
else
add_r(iter+1) = -1;
add_r(iter+iter_incr) = -1;
add_r(iter+find(tmp(tmp>0)==2)) = 2;
end
end
% increment
iter = iter + iter_incr;
end
toc
这在我的笔记本电脑上运行大约 20 秒,几分钟后我不得不终止你的解决方案。请注意,我目前无法测试更大的矩阵,这是一个 10000 x 10000 的矩阵,可能与您的数据结构不太相似。