【问题标题】:Vectorize function that outputs a row using arrayfun, returning a matrix使用arrayfun输出一行的向量化函数,返回一个矩阵
【发布时间】:2013-12-28 07:38:20
【问题描述】:

我正在使用 Octave 并希望对一个函数进行向量化,该函数接受单个实数作为输入并输出固定长度的行向量。我知道arrayfun 应该能够从其不清楚的文档中做到这一点。来自 Octave 3.2 中的 help arrayfun

如果参数 VAL 在另一个字符串输入参数之后 “UniformOutput”设置为“true”(默认),然后命名为 函数 FUNC 必须返回一个元素,然后将 连接到返回值并且是矩阵类型。 否则,如果该参数设置为“假”,则输出 连接在一个元胞数组中。

但似乎Matlab's version is more forgiving:

[B1,...,Bm] = arrayfun(func,A1,...,An) 调用函数句柄 func 指定的函数,并从数组 A1,...,An 中传递元素,其中 n 是函数 func 的输入数。输出数组 B1,...,Bm,其中 m 是函数 func 的输出数,包含函数调用的组合输出。第 i 次迭代对应于语法 [B1(i),...,Bm(i)] = func(A1{i},...,An{i})。 arrayfun 函数不按特定顺序执行对函数 func 的调用。

看起来这在 Matlab 中有效,但在 Octave 中无效。我是否正确,不能在 Octave 中使用 arrayfun 执行这种概括?有没有更聪明的方法可以在不使用非向量化循环的情况下实现这一点?

作为参考,这是我的 Octave 结果:

八度:5> 数字
数字=

@(c) ([c, c + 2, c + 4])

octave:6> arrayfun(nums,[1,2,3])
错误:cellfun:期望所有值都是 UniformOutput = true
的标量 错误:调用自:
错误:/opt/local/share/octave/3.2.4/m/general/arrayfun.m 第 168 行第 21 列
八度:6>

【问题讨论】:

标签: matlab octave vectorization


【解决方案1】:

使用arrayfun将函数nums应用于数组[1,2,3]

CellArray = arrayfun(nums, [1,2,3], "UniformOutput", false);

这为您提供了一个元胞数组。如果您想在矩阵中得到答案,请使用cell2mat

cell2mat(CellArray);

如果您的实际nums 更复杂,那么我们需要一个更好的示例来提出解决方案。

【讨论】:

  • arrayfun"UniformOutput", false 返回一个“行”元胞数组(即沿第二维)。 nums 的输出也是行向量(即也沿着第二维)。 cell2mat 将它们连接成一个长行向量。要获得矩阵,首先将元胞数组重塑为沿着预期的连接维度:cell2mat( reshape(CellArray, numel(CellArray), 1) )
  • 您也可以简单地转置向量arrayfun(nums, [1,2,3].', "UniformOutput", false); 以获得列元胞数组。注意 [1,2,3] 的转置!
【解决方案2】:

错误已经提示了如何解决问题:

arrayfun(nums,[1,2,3],'UniformOutput',false)

Matlab 和 Octave 没有区别。

Matlab:

>> nums=@(c) ([c, c + 2, c + 4])

nums = 

    @(c)([c,c+2,c+4])

EDU>> arrayfun(nums,[1,2,3])
Error using arrayfun
Non-scalar in Uniform output, at
index 1, output 1.
Set 'UniformOutput' to false.

>> arrayfun(nums,[1,2,3],'UniformOutput',false)

ans = 

  Columns 1 through 2

    [1x3 double]    [1x3 double]

  Column 3

    [1x3 double]

八度:

octave:1> nums=@(c) ([c, c + 2, c + 4])
nums =

@(c) ([c, c + 2, c + 4])

octave:2> arrayfun(nums,[1,2,3])
error: arrayfun: all values must be scalars when UniformOutput = true
octave:2> arrayfun(nums,[1,2,3],'UniformOutput',false)
ans = 
{
  [1,1] =

     1   3   5

  [1,2] =

     2   4   6

  [1,3] =

     3   5   7

}
octave:3> 

如果你的功能真的那么简单,我建议使用:

nums([1,2,3]')

【讨论】:

  • 不幸的是,我的实际nums 有点复杂。它更像nums = @(c)(other_function(c, curried_argument))。我认为这就是你最后一个解决方案失败的原因。是的,我可以禁用 UniformOutput 并转换输出,这可能是最优雅的做法,但仍在研究中。
  • @djechlin 那么,如果可能,您应该考虑编写other_function 来接受向量。
  • @carandraug 我不拥有它。 (这是fmincg。)
猜你喜欢
  • 2018-07-31
  • 2016-01-20
  • 1970-01-01
  • 1970-01-01
  • 2015-09-11
  • 1970-01-01
  • 1970-01-01
  • 2021-12-28
  • 1970-01-01
相关资源
最近更新 更多