我在编写要优化的函数时遇到问题,其中有两个求和和一个生成,都有不同的索引。为简单起见,我将代码分成两个函数。
在第一个函数中,j从0变为k:
w = function(n,k,gam){
j = 0:k
w = (1 / factorial(k)) * n * sum(choose(k, j * gam))
return(w)}
在第二个函数中,k从0变为n(固定为10);生产从1到长度(x):
f = function(gam,del){
x = mydata #vector of 500 elements
n = 10
k = 0:10
for (i in 0:10)
pdf = prod( sum( w(n, k[i], gam) * (1 / del + (n/x)^(n+1))
return(-pdf)}
当我尝试该功能时,我得到以下错误:
Error in 0:k : argument of length 0
修改:这就是我尝试编码的原因
我希望使用optim
和
和n
固定为特定值。
答案 0 :(得分:1)
将for (i in 0:10)
更改为for ( i in 1:11 )
。注意:当我复制并运行您的代码时,我也注意到您可能需要修复的一些不相关的括号/括号遗漏。
您的问题是R
使用基于1的索引系统而不是基于0的索引系统,就像许多其他编程语言或某些数学公式一样。如果您运行以下代码,您将得到相同的错误,并确定问题所在:
k = 0:10
for ( i in 0:10 ) {
print(0:k[i])
}
Error in 0:k[i] : argument of length 0
第一次迭代时出现错误,因为0
没有k
个元素。将其与以下循环进行比较:
k = 0:10
for ( i in 1:11 ) {
print(0:k[i])
}
[1] 0
[1] 0 1
[1] 0 1 2
[1] 0 1 2 3
[1] 0 1 2 3 4
[1] 0 1 2 3 4 5
[1] 0 1 2 3 4 5 6
[1] 0 1 2 3 4 5 6 7
[1] 0 1 2 3 4 5 6 7 8
[1] 0 1 2 3 4 5 6 7 8 9
[1] 0 1 2 3 4 5 6 7 8 9 10
您对答案的评论澄清了您需要的一些其他信息:
只是为了完全理解一切,我在某种情况下如何知道 这是R将x上的生产量和k上的总和编入索引
简短的回答是,它取决于您如何嵌套循环和函数调用。更详细:
f()
时,您会对for
的元素开始k
循环,因此R
正在为for
中的代码块编制索引循环(我的重新格式化的f()
版本中的大括号中的所有内容)“on k
。对于k
中的每个元素,您将prod(...)
分配给pdf
(旁注:我不知道为什么您在每次迭代中重写pdf
环)sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1))
生成一个长度为max(length(w(n, k[i], gam)), length(s))
的向量(旁注:谨防回收! - 请参阅Section 2.2 of "An Introduction to R"); prod(sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)))
有效地索引该向量的元素w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)
生成一个长度为max(length(w(n, k[i], gam)), length(s))
的向量; sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1))
有效地索引该向量的元素您通过向量化操作显式或隐式索引的内容取决于您正在讨论的嵌套循环或函数调用的级别。您可能需要仔细考虑并计划何时想要索引什么内容,这将告诉您如何嵌套内容。在最里面的调用上放置索引应该变化最快的操作。例如,在效果中,prod(1:3 + sum(1:3))
将对sum(1:3)
进行索引以首先生成该总和,然后在1:3 + sum(1:3)
上进行索引以生成产品。即,sum(1:3)
= 1 + 2 + 3 = 6,然后prod(1:3 + sum(1:3))
=(1 + 6)*(2 + 6)*(3 + 6)= 7 * 8 * 9 = 504.这是就像括号在数学中的工作方式一样。
另外,另一方面,我不会像在f()
中那样从函数中引用全局变量 - 我在下面的代码中突出显示了你这样做并提供了一个替代方案不行。
f = function(gam, del){
x = mydata # don't refer to a global variable "mydata", make it an argument
n = 10
s = n / x
k = 1:11
for (i in 1:11){
pdf = prod( sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)))
}
return(-pdf)
}
# Do this instead
# (though there are still other things to fix,
# like re-writing over "pdf" eleven times and only using the last value)
f = function(gam, del, x, n = 10) {
s = n / x
s = n / x
k = 0:10
for (i in 1:11){
pdf = prod( sum( w(n, k[i], gam) * gamma(1 / del + k[i]) * s^(n + 1)))
}
return(-pdf)
}