Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/matlab/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/ruby/22.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
单元阵列广播求和-MATLAB_Matlab_Vectorization_Cell Array - Fatal编程技术网

单元阵列广播求和-MATLAB

单元阵列广播求和-MATLAB,matlab,vectorization,cell-array,Matlab,Vectorization,Cell Array,假设我有一个矩阵,如下所示: C1=nx2单元每个单元都是[5x5双精度] C2=1x1单元包含一个[5x5双精度] 如何将C3计算为: C3{1,1} = C1{1,1}+C2{1,1}; C3{1,2} = C1{1,2}+C2{1,1}; . . C3{n,2} = C1{n,2}+C2{1,1}; 使用cellfun或任何其他不循环的方法对于具有规则大小数组的情况,最好使用多维数组,而不是慢速单元格数组。尽管如此,还是坚持使用单元数组,这里

假设我有一个矩阵,如下所示:

C1=nx2单元
每个单元都是
[5x5双精度]

C2=1x1单元
包含一个
[5x5双精度]

如何将
C3
计算为:

C3{1,1} =  C1{1,1}+C2{1,1};
C3{1,2} =  C1{1,2}+C2{1,1};
          .
          .
C3{n,2} =  C1{n,2}+C2{1,1};

使用
cellfun
或任何其他不循环的方法

对于具有规则大小数组的情况,最好使用多维数组,而不是慢速单元格数组。尽管如此,还是坚持使用单元数组,这里有一个向量化的解决方案,在将它们转换为多维数组之后,它将用作向量化广播求和的基础-

%// Store size of each cell and size of C1 for later reshaping purposes
[m,n] = size(C1{1,1})
[nr,nc] = size(C1);

%// Perform broadcasted summations with BSXFUN
sums = bsxfun(@plus,cat(3,C1{:}),C2{1,1})

%// Reshape and convert back to cell arrays as desired output 
out = reshape(mat2cell(sums,m,n,ones(1,nr*nc)),nr,nc)

对于具有规则大小数组的情况,最好使用多维数组,而不是慢速单元数组。尽管如此,还是坚持使用单元数组,这里有一个向量化的解决方案,在将它们转换为多维数组之后,它将用作向量化广播求和的基础-

%// Store size of each cell and size of C1 for later reshaping purposes
[m,n] = size(C1{1,1})
[nr,nc] = size(C1);

%// Perform broadcasted summations with BSXFUN
sums = bsxfun(@plus,cat(3,C1{:}),C2{1,1})

%// Reshape and convert back to cell arrays as desired output 
out = reshape(mat2cell(sums,m,n,ones(1,nr*nc)),nr,nc)
直接使用可以实现您想要的功能:

C3 = cellfun(@(x) x+C2{1,1},C1,'uniformoutput',false);
这将基本上在单元数组的每个元素上循环
C1
,并为每个元素应用匿名函数
@(x)x+C2{1,1}
,即每个元素将被添加到
C2{1,1}
。结果元素以与
C1
大小相同的单元格数组返回


对于一些较小的测试用例,我比较了这个解决方案和那个解决方案。结果并非微不足道,因为
cellfun
cat
(用于Divakar的解决方案)的速度都非常慢。我加入了第三个版本进行检查,其中我在匿名函数中定义了一个临时变量:

tmpvar=C2{1,1};
C3a2=cellfun(@(x) x+tmpvar,C1,'uniformoutput',false);
这背后的基本原理是,访问单个单元格元素应该有一些开销,我不确定整个单元格是否被拉入匿名函数的工作区

我定义了一个单独的函数来测试这三种情况,以便让JIT完成它的工作(但请注意,我使用的是R2012b,一个更新的版本可能会给出完全不同的结果,但需要注意)。我在相同的随机输入上运行所有三个案例(使用大小为
C2
的单元格数组
[1,1]
,并包含与
C1{k,l}
大小相同的数组),从10次尝试中选择最短的运行时间(基于
tic/toc

  • 5x5
    矩阵的
    10x10
    单元阵列:
    • cellfun
      0.000452s
    • cellfun
      +
      tmpvar
      0.000287s
    • bsxfun(cat)
      0.002970 s
  • 5x5
    矩阵的
    100x100
    单元阵列:
    • cellfun
      0.000988 s
    • cellfun
      +
      tmpvar
      0.000963s
    • bsxfun(cat)
      0.004661 s
  • 10x10
    矩阵的
    5x5
    单元阵列:
    • cellfun
      0.001580s
    • cellfun
      +
      tmpvar
      0.000945s
    • bsxfun(cat)
      0.011358 s
  • 100x100
    矩阵的单元阵列
    5x5
    矩阵:
    • cellfun
      0.108276s
    • cellfun
      +
      tmpvar
      0.082675 s
    • bsxfun(cat)
      1.132417s
  • 基于这些小测试用例,我很想得出这样的结论

  • 如果较大的单元格数组较大,在给定给
    cellfun
    的匿名函数中使用临时变量确实可以计数,这是有意义的(因为该函数的计算次数较大)
  • 基于
    bsxfun(cat)
    的解决方案对于小单元阵列稍微慢一点,对于大单元阵列则慢得多。我怀疑
    cat
    是罪魁祸首:
    cat
    需要花很多时间才能把额外的维度放在一起。我甚至可以想象,使用带有预分配的循环可能比
    cat
    更好
  • 对于新的执行引擎,以及更大的(
    n>1000
    )矩阵和单元数组,检查相同的情况会很有趣
  • 直接使用可以实现您想要的功能:

    C3 = cellfun(@(x) x+C2{1,1},C1,'uniformoutput',false);
    
    这将基本上在单元数组的每个元素上循环
    C1
    ,并为每个元素应用匿名函数
    @(x)x+C2{1,1}
    ,即每个元素将被添加到
    C2{1,1}
    。结果元素以与
    C1
    大小相同的单元格数组返回


    对于一些较小的测试用例,我比较了这个解决方案和那个解决方案。结果并非微不足道,因为
    cellfun
    cat
    (用于Divakar的解决方案)的速度都非常慢。我加入了第三个版本进行检查,其中我在匿名函数中定义了一个临时变量:

    tmpvar=C2{1,1};
    C3a2=cellfun(@(x) x+tmpvar,C1,'uniformoutput',false);
    
    这背后的基本原理是,访问单个单元格元素应该有一些开销,我不确定整个单元格是否被拉入匿名函数的工作区

    我定义了一个单独的函数来测试这三种情况,以便让JIT完成它的工作(但请注意,我使用的是R2012b,一个更新的版本可能会给出完全不同的结果,但需要注意)。我在相同的随机输入上运行所有三个案例(使用大小为
    C2
    的单元格数组
    [1,1]
    ,并包含与
    C1{k,l}
    大小相同的数组),从10次尝试中选择最短的运行时间(基于
    tic/toc

  • 5x5
    矩阵的
    10x10
    单元阵列:
    • cellfun
      0.000452s
    • cellfun
      +
      tmpvar
      0.000287s
    • bsxfun(cat)
      0.002970 s
  • 5x5
    矩阵的
    100x100
    单元阵列: