绘图日志(n超过k)

时间:2019-05-23 14:56:52

标签: matlab

我以前从未使用过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)

4 个答案:

答案 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 值,但实际上二项式系数仅针对非负整数定义。

enter image description here

答案 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)

syms函数类型完全复制了您想要的内容

syms x

y = log(nchoosek(1000,x));
fplot(y,[1 1000]);

enter image description here

答案 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

Plot of nchoosek with n = 1000