如何在MATLAB匿名函数中集成条件?

如何在MATLAB匿名函数中集成条件?,matlab,function,if-statement,anonymous,Matlab,Function,If Statement,Anonymous,我下面的代码相当耗时,因为a矩阵相当大(150000^2)。我能否将这些条件集成为accumarray中的函数@(x)?这样我就可以对所有行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 sam

我下面的代码相当耗时,因为a矩阵相当大(150000^2)。我能否将这些条件集成为
accumarray
中的函数
@(x)
?这样我就可以对所有行
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
tic
[abc]=查找(a.);%提取A的非零元素的位置
add_sym=accumarray(b,c,[],@(x){x});%重新排列同一行b的值
加上_r=[];
对于i=1:size(add_sym)%
r=vertcat(add_sym{i});%将单元转化为双向量
如果大小(r,2)=1%,则为每行应用3个条件
加上_r0=0;

elseif size(r,2)>1&&any(r 1&&any)(r原则上,您是在稀疏矩阵的行上循环。与转换为单元格和返回相比,显式提取行并进行检查可能更方便。我的尝试:

% 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
%A虚拟对象,随机包含0、1或2
N=1e4;
A=稀疏(randi(2,[N,N]));%A包含1和2
(兰特([N,N])0
如果~any(tmp(tmp>0)0)==2))=2;
结束
结束
%增量
国际热核实验堆=国际热核实验堆+国际热核实验堆增量;
结束
toc

这在我的笔记本电脑上运行大约20秒,我不得不在几分钟后终止您的解决方案。请注意,我目前无法测试更大的矩阵,这是一个10000 x 10000的矩阵,可能与您的数据结构不太相似。

您能添加一个吗?这样可以更轻松地计时执行和尝试代码,没有评论,很难看到它一开始做了什么。谢谢你的评论。我确实添加了评论,希望更清楚。我可以上传矩阵,但我找不到可以插入文件的位置?是的,确实快得多。非常感谢。但是你注意到add_r在最后更改了它的大小,而不是nnz(a)还有?所以我真的不知道用替换的值把新的稀疏矩阵加法的形式放回去。你是对的,我已经更新了答案(前面的
find
语句读
find(tmp==2)
)。是的,它现在可以工作了,非常快!!只是一个小问题,这个条件不存在(tmpAh,
tmp
也包含零,因此需要将该行更改为
any(tmp(tmp>0)