2014-06-16 2 views
4

Math.NET 수치를 사용하여 DateTime - 값 계열 보간 작업을 시도하고 있습니다. 직선 보간법부터 시작했지만 결과가 매우 좋지 않습니다.Math.Net 숫자를 사용하여 큰 x 값으로 선형 보간이 잘못되었습니다.

이 테스트를 실행 :

public class script{ 

public void check_numerics() 
    { 
    var ticks = DateTime.Now.Ticks; 
    Console.WriteLine("Ticks: " + ticks); 
    var xValues = new double[] { ticks, ticks + 1000, ticks + 2000, ticks + 3000, ticks + 4000, ticks + 5000 }; 
    var yValues = new double[] {0, 1, 2, 3, 4, 5}; 
    var spline = Interpolate.LinearBetweenPoints(xValues, yValues); 
    var ticks2 = ticks; 
    for (int i = 0; i < 10; i++) 
    { 
     ticks2 += 500; 
     Console.WriteLine(spline.Interpolate(ticks2)); 
    } 
    } 
} 

이 제공 :

Ticks: 635385235576843379 
0.5 
1 
1.5 
2 
2.42857142857143 // this should be 2.5 
3 
3.5 
4 
4.5 
5 

공지 2.4285 것을 상당히 잘못된 것입니다. 다른 시간 (다른 틱 값)에서는 다른 값이 "잘못"됩니다. Math.NET에 큰 x 값을 가진 "버그"가 있습니까? 아니면 너무 많이 기대합니까?

+1

그것을 두 배에만 15 - 17 sf가 있다고 가정하면 완전히 정확하지는 않습니다. 당신은 그 값을 초과하고 있습니다. 따라서 double은 값을 정확하게 표현할 수는 없지만, 그것보다 더 가까울 것이라고 생각했을 것입니다. –

+0

감사합니다. @JamesBarrass, 그래서 현재 시간을 double - good으로 표현할 수 없습니다. 알고있다! – jdpilgrim

+1

그 정확도, 밀리 초, 아마도 10 마이크로 초가 아닙니다. 별로 작지 않다. IIRC 진드기는 약 100 나노초입니다. –

답변

5

그냥 위의 Math.NET 메릭스의 메인테이너로 의견 확인 : 이중 정밀도로 표현 될 수있는이 정도의 가까운 숫자 사이

거리 (엡실론)를 128 :

Precision.EpsilonOf(ticks); // 128 

long ticks = DateTime.Now.Ticks // 635385606515570758 
((long)(double)ticks)   // 635385606515570816 
((long)(63+(double)ticks))  // 635385606515570816 
((long)(-63+(double)ticks))  // 635385606515570816 
((long)(65+(double)ticks))  // 635385606515570944 
((long)(-65+(double)ticks))  // 635385606515570688 

증분 :

이 추가하거나이 번호에서 빼기 128/2-1 = 63 경우, 당신은 정확히 같은 번호를 다시 얻을 수 있음을 의미 500의 단계가 이들 128에 매우 가깝고 효과적으로 128의 배수로 반올림됩니다 (예 : 512), 이와 같은 유물이 있다는 것은 놀라운 일이 아닙니다. 당신이 제임스에 의해 제안, 10000으로 진드기를 나누어 밀리 초 시간 정밀도를 줄일 경우

, 당신은 0.0078125의 엡실론을 얻고, 정확하고도 1의 단계에 대한 결과 대신 (500)는

Precision.EpsilonOf(ticks/10000); // 0.0078125 
관련 문제