我以前从未使用过Matlab,而且我真的不知道如何修复代码。我需要用k从1到1000绘制log(1000 over k)。
y = @(x) log(nchoosek(1000,x));
fplot(y,[1 1000]);
错误:
Warning: Function behaves unexpectedly on array inputs. To improve performance, properly
vectorize your function to return an output with the same size and shape as the input
arguments.
In matlab.graphics.function.FunctionLine>getFunction
In matlab.graphics.function.FunctionLine/updateFunction
In matlab.graphics.function.FunctionLine/set.Function_I
In matlab.graphics.function.FunctionLine/set.Function
In matlab.graphics.function.FunctionLine
In fplot>singleFplot (line 241)
In fplot>@(f)singleFplot(cax,{f},limits,extraOpts,args) (line 196)
In fplot>vectorizeFplot (line 196)
In fplot (line 166)
In P1 (line 5)
答案 0 :(得分:3)
代码有几个问题:
nchoosek
不会在第二个输入上向量化,也就是说,它不接受数组作为输入。 fplot
适用于矢量化函数。否则可以使用,但是会发出警告。nchoosek
的结果几乎溢出。例如,nchoosek(1000,500)
给出2.702882409454366e+299
,并发出警告。nchoosek
需要整数输入。 fplot
通常使用指定范围内的非整数值,因此nchoosek
会发出错误消息。您可以利用阶乘与gamma function之间的关系以及Matlab具有gammaln
的事实来解决这三个问题,该事实可以直接计算伽玛函数的对数:
n = 1000;
y = @(x) gammaln(n+1)-gammaln(x+1)-gammaln(n-x+1);
fplot(y,[1 1000]);
请注意,您得到的图具有指定范围内所有 x 的 y 值,但实际上二项式系数仅针对非负整数定义。
答案 1 :(得分:2)
好吧,由于您现在无论如何都要进行家庭作业,因此,我将发布一个我认为更容易理解的答案。
multiplicative formula for the binomial coefficient说
n超过k =乘积 i = 1到k ((n + 1-i)/ i)
(抱歉,无法在SO上编写适当的公式,如果不清楚,请参阅Wikipedia链接)。
要计算产品的对数,我们可以计算对数之和:
log(product(x(sub i )))= sum(log(x i ))
因此,我们可以为所有(n+1-i)/i
计算i
的值,取对数,然后求和第一个k
的值,得出给定{{1 }}。
此代码使用k
(累积总和)完成此过程。它在数组元素cumsum
上的输出是从1到k
的所有输入数组元素的总和。
k
还要注意n = 1000;
i = 1:1000;
f = (n+1-i)./i;
f = cumsum(log(f));
plot(i,f)
,即逐元素划分。 ./
在MATLAB中执行矩阵除法,这不是您所需要的。
答案 2 :(得分:2)
答案 3 :(得分:1)
此解决方案使用arrayfun
处理nchoosek(n,k)
要求k
为标量的事实。这种方法不需要任何工具箱。
此外,它使用plot
而不是fplot
,因为this clever answer已经解决了如何处理fplot
。
% MATLAB R2017a
n = 1000;
fh=@(k) log(nchoosek(n,k));
K = 1:1000;
V = arrayfun(fh,K); % calls fh on each element of K and return all results in vector V
plot(K,V)
请注意,对于某些k
大于或等于500的值,您将收到警告
警告:结果可能不正确。系数大于9.007199e + 15,并且只能精确到15位数字
因为nchoosek(1000,500) = 2.7029e+299
。正如@Luis Mendo所指出的,这是由于realmax = 1.7977e+308
是受支持的最大实数浮点数。有关更多信息,请参见here。