【问题标题】:Using a for loop to generate elements of a vector使用 for 循环生成向量的元素
【发布时间】:2014-02-11 23:17:39
【问题描述】:

我正在尝试用公式 进行计算

我想将每个值存储到一个行向量中。这是我的尝试:

multiA = [1];
multiB = [];
NA = 6;
NB = 4;
q = [0,1,2,3,4,5,6]; 


for i=2:7
  multiA = [multiA(i-1), (factorial(q(i) + NA - 1))/(factorial(q(i))*factorial(NA-1))];
  %multiA = [multiA, multiA(i)];
end

multiA

但这不起作用。我收到错误消息

Attempted to access multiA(3); index out
of bounds because numel(multiA)=2.

  multiA = [multiA(i-1), (factorial(q(i)
  + NA -
  1))/(factorial(q(i))*factorial(NA-1))];

我的代码是否与我想要实现的目标非常接近?我能做些什么来解决它?

【问题讨论】:

  • 下面给出的答案是正确的和推荐的方法,但在这里理解你的错误。当你这样做时,multiA = [multiA(i-1),<<big_expression>>],然后,在每次迭代中,你只会得到 2 元素长向量 multiA,因为 mutliA(i-1) 和你的 <<big_expression>> 都是标量。如果您想遵循您的方法,您应该在进入for 循环之前完成-> multiA = [multiA,<<big_expression>>] 并声明multiA=[]。这就是 MATLAB 告诉你的,numel(multiA)=2
  • +1 meshgrid 使用

标签: arrays matlab for-loop


【解决方案1】:

你不需要任何循环,直接使用向量即可。

NA = 6;
q = [0,1,2,3,4,5,6]; 

multiA = factorial(q + NA - 1)./(factorial(q).*factorial(NA-1))

给予

multiA =

     1     6    21    56   126   252   462

对于多个N,也不需要循环:

N = [6,8,10];
q = [0,1,2,3,4,5,6]; 
[N,q] = meshgrid(N,q)
multiA = factorial(q + N - 1)./(factorial(q).*factorial(N-1))

还请考虑以下关于n > 21 in 溢出的备注:

f = factorial(n)

限制

该结果仅对小于或等于 21 的 n 的双精度值是准确的。较大的 n 值产生的结果是 具有正确的数量级并且对于前 15 个是准确的 位数。这是因为双精度数只能精确到 到 15 位。
对于单精度输入,结果仅对小于或等于 13 的 n 值是准确的。较大的 n 值会产生 结果具有正确的数量级并且对于 前 8 位数字。这是因为单精度数只 精确到 8 位。

【讨论】:

  • 显然我想多了。非常感谢!!
【解决方案2】:

较大数字的因子可能导致溢出。防止这种情况的两种可能方法:

  1. 避免计算会取消的条款。这种方法特别适合q 的形式为 1,2,... 的情况,如您的示例所示。它还有一个优点是,对于q 的每个值,前一个值的结果都会被重新利用,从而最大限度地减少操作次数:

    >> q = 1:6;
    >> multiA = cumprod((q+NA-1)./q)
    multiA =
         6    21    56   126   252   462
    

    请注意,0 不允许在 q 中使用。但是0 的结果就是1,所以最终结果就是[1 multiA]

  2. 对于 q 任意(不一定是 1,2,... 的形式),您可以使用 gammaln 函数,它给出阶乘的对数

    >> q = [0 1 2 6 3];
    >> multiA = exp(gammaln(q+NA)-gammaln(q+1)-gammaln(NA));
    >>multiA =
           1.0000    6.0000   21.0000  462.0000   56.0000
    

【讨论】:

  • @thewaywewalk :-) 人们很少有机会有意义地使用对数伽马函数
【解决方案3】:

您想在 'multiA' 的末尾追加一个新元素:

for i=2:7
  multiA = [multiA, (factorial(q(i) + NA - 1))/(factorial(q(i))*factorial(NA-1))];
end

函数句柄让它变得更简单:

%define:
omega=@(q,N)(factorial(q + N - 1))./(factorial(q).*factorial(N-1))
%use:
omega(0:6,4) %q=0..6, N=4

【讨论】:

    【解决方案4】:

    使用nchoosek 可能比使用factorial 更好。我想后者很容易溢出。

    multiA=nan(1,7);
    
    for i=1:7
    
      multiA(i)=nchoosek(q(i)+N-1, q(i));
    
    end
    

    【讨论】:

      猜你喜欢
      • 2018-07-28
      • 1970-01-01
      • 2015-07-24
      • 1970-01-01
      • 2020-03-02
      • 1970-01-01
      • 1970-01-01
      • 2017-08-16
      • 1970-01-01
      相关资源
      最近更新 更多