我想计算RSI函数,如下所示:
RSI = 100 * RS / ( 1 + RS ), where RS = n_up / n_down
and n_up( t ) = ( 1 - b ) * n_up( t - 1 )
+ b * U( t ),
and n_down( t ) = ( 1 - b ) * n_down( t - 1 )
+ b * D( t ).
where U( t ) = 1 for P( t ) > P( t - 1 ) and
0 otherwise;
and D( t ) = 1 for P( t ) < P( t - 1 ) and
0 otherwise.
所以这是我的代码:
p <- data[,6]
rsi <- function(P,t,n)
{
U <- function(P,t)
{
if (diff(P)[t] > 0)
{
return(1)
} else {
return(0)
}
}
D <- function(P,t)
{
if (diff(P)[t] < 0)
{
return(1)
} else {
return(0)
}
}
recursive.n_up <- function(P,t,b)
{
return((1-b)*recursive.n_up(P,t-1,b) + b*U(P,t))
}
recursive.n_down <- function(P,t,b)
{
return((1-b)*recursive.n_down(P,t-1,b) + b*D(P,t))
}
b <- 2/(n+1)
rs <- function(P,t,b)
{
return(recursive.n_up(P,t,b)/recursive.n_down(P,t,b))
}
return(100*rs(P,t,b)/(1+rs(P,t,b)))
}
n <- 14
RSI <- rep(0,length(p)-1)
for (i in 1:length(RSI))
{
RSI[i] <- rsi(p,i,n)
}
print(RSI)
我收到一条消息错误说明:
C堆栈使用7970184太靠近了 限制
所以我想知道我的算法设计是非常糟糕的还是在使用递归函数时会出现这种情况?谢谢你帮我解决这个问题。
答案 0 :(得分:1)
虽然已知递归可能有助于以聪明的方式表达某些问题,但核心逻辑是,它必须有一些“底部”线,其中递归从任何潜水深处停止 - 易于确定point - 从目前为止嵌套的递归开始返回并且(在路上回到第一个调用者)递归返回进程组装正确的答案作为这个从最深处回来的副作用从已知的,易于判断的已知返回值的点开始。
简而言之,您的算法化中缺少这一点。
即使在TimeSeries数据的第一个历史栏中,您的代码也会尝试深入(更及时)潜水。
如果你正确地处理了这个案子,那么代码将会停止其无拘无束的潜水习惯并开始组装结果。
递归适用于一站式微积分。
递归对于重复微积分来说是个坏主意,如果已经计算过的“步骤”再次被重新计算,如果一个糟糕的重用策略强制执行一次又一次地重新一次又一次地重新潜水到非常相同的“终点”,仅仅归因于原始(性能未优化)递归公式。
让我们在阶乘上显示它。
使用其简单,最简单的递归形式,出于说明目的,而所有原则都与任何更复杂的基于递归的处理相关 - 这只是简单地适用于一个SLOC:
的 factorial( N ) = ( N == 1 ) ? 1 : N * factorial( N - 1 )
强>
如果只是计算一次 factorial( 15 )
,那么就不能反对一个单词而不必去整个链:
fact15 = ( 15 * 14 * 13 * 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 )
缺少任何单个步骤会导致流程无法正确计算因子。
问题会以不同的方式出现,如果接下来有责任计算下一个问题 - factorial( 16 )
一个表现无知的实现将在那里再回到同一条道路上:
fact16 = ( 16 * 15 * 14 * 13 * 12 * 11 * 10 * 9 * 8 * 7 * 6 * 5 * 4 * 3 * 2 * 1 )
而一个聪明的,以表现为动机的实现永远不会重复马戏团的尾部,而只会增加头部:
fact16 = ( 16 * fact15 )
永远不要重复已经计算过一次的部分。
想象一下这种明显差异的尺度,随着递归深度逐渐增长到数百,数千,数万,数十万,数百万的递归步骤......一次又一次地重复它们中的每一个然后再次。不,不。
这是所有高性能,低延迟时间序列数据处理的核心逻辑,RSI是您自己遇到的明确案例。
答案 1 :(得分:1)
我完全同意user3666197
提供的先前答案;你的递归函数没有停止条件。它会一直持续......
此外,您在功能方面做了非常低效的事情。你算了
return( 100 * rs( P, t, b )
/ ( 1 + rs( P, t, b )
)
)
所以rs(...)
使用完全相同的参数计算两次。为什么不:
Z <- rs( P, t, b )
return( 100 * Z / ( 1 + Z )
您必须整合正确的停止条件。
答案 2 :(得分:0)
对我来说,我使用以下命令清除了R并使其正常工作:
#Clear plots
if(!is.null(dev.list())) dev.off()
# Clear console
cat("\014")
# Clean workspace
rm(list=ls())