循环通过cellfun计算

时间:2012-08-06 13:27:15

标签: matlab

您好我有以下内容:

for j = 1:N
    for i = 1:N
        vecdir(i,:) = pos(i,:) - pos(j,:);
        dist(i,:) = pdist2(pos(i,:),pos(j,:));
        norm(i,:) = vecdir(i,:)./(dist(i,:)).^2;
    end
    r{j} = norm;

end

u = {or};

我有两个对象u和r:

>> u

u = 

    [9x3 double]

>> r

r = 

  Columns 1 through 8

    [9x3 double]    [9x3 double]    [9x3 double]    [9x3 double]    [9x3 double]    [9x3 double]    [9x3 double]    [9x3 double]

  Column 9

    [9x3 double]

并且我想获取r的每个单元格,并获取该单元格中每个元素的叉积,单元格中的每个元素u并将结果总和为一个向量大小[1 3]。到目前为止,我可以使用以下方法一次完成一个(r)单元格。

b_func = @(u)nansum(cell2mat(cellfun(@(v)cross(u,v)', {r{1}}, 'Un', 0))', 1);
b = cellfun(b_func, u, 'UniformOutput', 0)

其中

b = [1x3 double]

然而,我想要做的是为r中的所有单元格执行此操作,以便最终得到一个对象:

b = 

  Columns 1 through 8

    [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]

  Column 9

    [1x3 double]

其中每个单元格是上面提到的计算,但是迭代了r的每个单元格。任何想法如何做到这一点?

2 个答案:

答案 0 :(得分:1)

怎么样:

b= cellfun(@(x) nansum(cross(u{1},x)),r,'UniformOutput',false);

测试:

>> u = {randi(5,[9 3])}
u = 
    [9x3 double]
>> r = arrayfun(@(x) randi(5,[9 3]),1:8,'UniformOutput',false)
r = 
  Columns 1 through 6
    [9x3 double]    [9x3 double]    [9x3 double]    [9x3 double]    [9x3 double]    [9x3 double]
  Columns 7 through 8
    [9x3 double]    [9x3 double]
>> b = cellfun(@(x) nansum(cross(u{1},x)),r,'UniformOutput',false)
b  = 
  Columns 1 through 6
    [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]
  Columns 7 through 8
    [1x3 double]    [1x3 double]

答案 1 :(得分:0)

你可以重塑它,使得单元格沿着第三维,将其转换为数组并求和:

b = nansum(cell2mat(reshape(cellfun(@(v)cross(u,v), r, 'Un', 0),1,1,[])),1);

然后返回单元格并修复尺寸:

bfinal = shiftdim(mat2cell(b,[1],[3],ones(1,size(b,3))),1);

结果:

>> bfinal

bfinal = 

  Columns 1 through 6

    [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]    [1x3 double]

  Columns 7 through 9

    [1x3 double]    [1x3 double]    [1x3 double]