【问题标题】:Recurring Function with Matrix Input带有矩阵输入的循环函数
【发布时间】:2014-09-17 03:16:01
【问题描述】:

我相信MATLAB中的大部分函数都应该能够接收矩阵输入并以矩阵的形式返回输出。

例如 sqrt([1 4 9]) 将返回 [1 2 3]。

但是,当我尝试这个循环阶乘函数时:

function k = fact(z)
if z ~= 0
    k = z * fact(z-1);
else
    k = 1;
end

end

当一个数字输入到事实中时,它可以完美地工作。但是,当一个矩阵输入到 fact 时,它返回矩阵本身,而不执行阶乘函数。

例如

fact(3) 返回 6 fact([1 2 3]) 返回 [1 2 3] 而不是 [1 2 6]。

感谢任何帮助。非常感谢!

【问题讨论】:

  • 认为您需要一个循环,因为使用 z ~= 0 您正在比较整个矩阵,我认为您需要满足 z 的所有元素来满足它。
  • 尽管您说这些更改对您有用,但我想最好不要让这个问题得不到回答(或者如果这是正确的术语,则不接受)。那么,也许发布您自己的解决方案并接受它,或者从这里已经提出的解决方案中选择最好的一个并接受它?

标签: matlab


【解决方案1】:

由于不知道 MATLAB 擅长递归函数,那么向量化方法怎么样?试试这个作为向量输入 -

mat1 =  repmat([1:max(z)],[numel(z) 1])
mat1(bsxfun(@gt,1:max(z),z'))=1
output1 = prod(mat1,2)

示例运行 -

z =
     1     2     7
output1 =
           1
           2
        5040

为了回答您的原始问题,这里是向量或 2D 矩阵作为输入的烦人的循环代码 -

function k1 = fact1(z1)

k1 = zeros(size(z1));
for ii = 1:size(z1,1)
    for jj = 1:size(z1,2)
        z = z1(ii,jj);
        if z ~= 0
            k1(ii,jj) = z .* fact1(z-1);
        else
            k1(ii,jj) = 1;
        end
    end
end

return

示例运行 -

>> fact1([1 2 7;3 2 1])
ans =
           1           2        5040
           6           2           1

【讨论】:

  • 您之前的评论也很有效 :) 我添加了一个 for i=1:numel(z) 循环,并将 z 和 k 的所有实例替换为 z(i) 和 k(i)。这个示例代码在我的舞台上看起来相当先进,但谢谢:)
【解决方案2】:

您可以使用gamma 函数来计算阶乘而无需递归:

function k = fact(z)
k = gamma(z+1);

例子:

>> fact([1 2 3 4])
ans =
     1     2     6    24

【讨论】:

【解决方案3】:

不确定你们是否都知道,但在 MATLAB 中定义了一个实际的 factorial 函数,它可以接收任何大小的数组/矩阵,并按元素计算阶乘。例如:

k = factorial([1 2 3 4; 5 6 7 8])

k =

           1           2           6          24
         120         720        5040       40320

尽管这篇文章正在寻找递归实现,并且 Divakar 提供了一个解决方案,但我仍然想投入两分钱并提出一个替代方案。另外,假设我们无权访问factorial,我们想从第一原理计算它。我个人要做的是创建一个与输入矩阵大小相同的单元格数组,但此单元格数组中的每个元素都是从1 到为原始矩阵中每个位置定义的数字的线性索引数组。然后将prod 应用于每个单元格元素以计算阶乘。一个前提是没有一个数小于 1,并且所有元素都是整数。因此:

z1 = ... ; %// Define input matrix here
z1_matr = arrayfun(@(x) 1:x, z1, 'uni', 0);
out = cellfun(@prod, z1_matr);

如果z1 = [1 2 3 4; 5 6 7 8];,从我之前的示例中,我们得到与上面代码相​​同的输出:

out =

       1           2           6          24
     120         720        5040       40320

这显然会更慢,因为有一个arrayfun 然后cellfun 调用之后立即,但我想我会添加另一种方法,只是为了添加另一种方法:) 不确定这是多么有建设性,但我想我会添加自己的方法并加入 Divakar 和 Luis Mendo :)

【讨论】:

  • 我猜 OP 无法访问实际的阶乘函数,不知何故他/她没有,因为否则太愚蠢了;)您的方法也有效! +1
猜你喜欢
  • 2018-03-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-04-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多