我有一个循环公式。JMP 可以解决这个问题,但每次我创建新公式时它都会发出有关循环的警告。
我怎么能够:
- 强制进行新的迭代?
- 配置迭代次数(或停止标准)来解决递归问题?
- 阻止评估再次发生? 抑制公式菜单中的 Eval 选项不起作用。
该函数稍微复杂一点,但与下面的没有什么不同,它的工作没有抱怨。
X (k+1) = 0.99 * X(k)
If(
Selected() == 1, 1,
Row() == 1, 1,
Lag( :X ) * 0.99
)
您提供的功能应该按原样运行,没有任何警告。如果您实际上在 B 的公式中引用 A 列,在 A 的公式中引用 B 列,那么您可以尝试将该逻辑编写为单个公式或遵循@Craige_Hales的建议并使用脚本来完成此操作。
包含示例公式的表格,其计算结果应该不会出现警告或错误。
New Table( "Untitled 16",
Add Rows( 10 ),
New Column( "X",
Numeric,
"Continuous",
Format( "Best", 12 ),
Formula( If( Selected() == 1, 1, Row() == 1, 1, Lag( :X ) * 0.99 ) ),
Set Selected
),
Set Row States( [0, 0, 0, 0, 1, 0, 0, 0, 1, 0] )
)
JMP 的公式计算器的工作方式是,首先评估仅依赖于非公式列的公式列,然后评估依赖于已评估的公式列的公式列。 如果 A 列的公式取决于 B 列,而 B 列的公式又取决于 A 列,则 JMP 无法选择首先计算哪一个。 如果您设法欺骗 JMP 创建循环依赖关系,您将无法确定哪一列正在使用另一列的旧数据。
JMP 从上到下评估列。 在公式中,您可以使用滞后函数(或子脚本)来查看较早的行并获取先前计算的值。 我不确定如果您查看未来的行会发生什么,但该值尚未计算。
您可能认为有些公式可以基于 Excel 规则起作用,但是JMP 不是电子表格并按上述规则进行游戏。 如果需要使 A 列引用 B 列的滞后,B 列引用 A 列的滞后,则应将 A 和 B 设为非公式列,并编写 JSL 来填充它们。 将该 JSL 添加到名称类似于“Run Me When The Data Needs To Be Updated”的表脚本中。
如果您有递归函数,则可以创建一个调用自身的 JSL 函数。 JSL 对允许的递归深度有相当低的限制,100 左右。 您必须编写自己的 if 语句来决定何时停止递归。 通常,深度参数用于停止递归,例如(未经测试,毫无意义......)
f = function({depth}, if(depth < 10, /* do something */ f(depth + 1) ) );
f(0)