【发布时间】:2015-01-12 22:07:47
【问题描述】:
让x = [3:10]。我想为每个i 找到nchoosek(x(i),3)。有没有不使用for 循环的函数(或更好的方法)?
函数nchoosek 确实接受向量作为其第一个参数,但输出是向量中不同的三个元素。
【问题讨论】:
标签: performance matlab combinations
让x = [3:10]。我想为每个i 找到nchoosek(x(i),3)。有没有不使用for 循环的函数(或更好的方法)?
函数nchoosek 确实接受向量作为其第一个参数,但输出是向量中不同的三个元素。
【问题讨论】:
标签: performance matlab combinations
您还可以使用factorial 函数并手动计算nchoosek。回想nchoosek 的公式:
因此,我们可以使用factorial 来帮助计算,它也接受任何形状的数组和矩阵。因此,您的代码将是:
y = factorial(x) ./ (factorial(3) .* factorial(x-3));
给定x = 3:10,我们得到:
y =
1 4 10 20 35 56 84 120
但是,如果您想对x >= 3 的任何值执行nchoosek(x, 3),您可以简单地找到封闭形式的表达式,而不必同时使用factorial。要实现您想要的,请使用上面的表达式替换 nchoosek 并简单地将 n 替换为 x 和 k 替换 3:
如您所见,您想要的简化为:
对于x 的任何值,只要它大于或等于3。因此,对于x 的每个值,只需计算一个元素表达式,如下所示:
y = x.*(x-1).*(x-2) / 6;
给定x = 3:10,我们因此再次得到:
y =
1 4 10 20 35 56 84 120
【讨论】:
利用阶乘与欧拉gamma函数之间的关系:
x = 3:10;
k = 3;
result = gamma(x+1)/gamma(k+1)./gamma(x-k+1);
更好的是,直接使用对数(使用gammaln)。这将让您计算大型 x 和 k 而不会溢出。在末尾应用round,以去除因有限数值精度引起的任何虚假小数部分。
result = round(exp(gammaln(x+1)-gammaln(k+1)-gammaln(x-k+1)));
另一种方法,对于 k,k+1, ... 形式的 x(如您的示例):
result = [1 cumprod(x(2:end)./(x(2:end)-k))];
【讨论】: