2 回答
TA贡献1909条经验 获得超7个赞
我认为算法是不同的。例如方差:
/* Do the MA calculation using tight loops. */
/* Add-up the initial periods, except for the last value. */
periodTotal1 = 0;
periodTotal2 = 0;
trailingIdx = startIdx-nbInitialElementNeeded;
i=trailingIdx;
if( optInTimePeriod > 1 )
{
while( i < startIdx ) {
tempReal = inReal[i++];
periodTotal1 += tempReal;
tempReal *= tempReal;
periodTotal2 += tempReal;
}
}
/* Proceed with the calculation for the requested range.
* Note that this algorithm allows the inReal and
* outReal to be the same buffer.
*/
outIdx = 0;
do
{
tempReal = inReal[i++];
/* Square and add all the deviation over
* the same periods.
*/
periodTotal1 += tempReal;
tempReal *= tempReal;
periodTotal2 += tempReal;
/* Square and add all the deviation over
* the same period.
*/
meanValue1 = periodTotal1 / optInTimePeriod;
meanValue2 = periodTotal2 / optInTimePeriod;
tempReal = inReal[trailingIdx++];
periodTotal1 -= tempReal;
tempReal *= tempReal;
periodTotal2 -= tempReal;
outReal[outIdx++] = meanValue2-meanValue1*meanValue1;
} while( i <= endIdx );
这看起来不像你的方差。如果您要重现算法以便它们执行完全相同的操作,那么 Go 版本应该产生相同的结果。Go 只是在做标准的 IEEE 754 浮点运算。
至于“顺序重要吗?”这个问题。确实如此。由于浮点算术不精确,您在计算时会丢失信息。大多数时候它不会产生太大的不同,但有时算法可能非常容易受到这些变化的影响。(因此以代数方式重新排列您的公式可能不会在实际代码中得到相同的答案)
您经常会在这些库中发现算法旨在解决这些问题,因此它们通常看起来不像是幼稚的实现。例如mean,通常是一个微不足道的函数,但以下是它在 GSL 中的计算方式:
double
FUNCTION (gsl_stats, mean) (const BASE data[], const size_t stride, const size_t size)
{
/* Compute the arithmetic mean of a dataset using the recurrence relation
mean_(n) = mean(n-1) + (data[n] - mean(n-1))/(n+1) */
long double mean = 0;
size_t i;
for (i = 0; i < size; i++)
{
mean += (data[i * stride] - mean) / (i + 1);
}
return mean;
}
因此,除非您完全匹配算法,否则您的答案将略有不同。(这并不一定意味着你的程序是错误的)
通常用于此的一种解决方案是在一个非常小的数字(math.Abs(expected-result) < ɛ,您定义 ɛ: 的地方const ɛ = 0.0000001)内进行相等比较,而不是使用==.
TA贡献1982条经验 获得超2个赞
正如 Caleb 和 Matteo 的评论/答案所建议的那样,即使代码排序方式的细微差异也会导致浮点值的差异。
我最终确认,至少在一个小样本量的情况下,完全像 TA-Lib 一样实现代码会产生正确的浮点值。正如预期的那样,即使稍微偏离 TA-Lib (C) 实现也会导致浮点值的微小差异。
- 2 回答
- 0 关注
- 186 浏览
添加回答
举报