.NET интерполяционный расчет? - PullRequest
1 голос
/ 27 января 2011

Я ищу подходящее решение (если это должна быть библиотека .NET Math, так и быть) для следующего.

Я две DateTime переменные, скажем From и To.У меня также есть два числовых значения Start и Finish.

. Я хочу получить значение между Start и Finish в At TimeSpan относительно From.

См .:

//At is the TimeSpan which should be added to From to get the location of the point to be interpolated
GetInterpolatedValue(At, From, To, Start, Finish, InterpolationMethod, Optional InterpolationVars = Nothing)

Пример:

GetInterPolatedValue(TimeSpan.FromDays(1), Now(), Now.AddDays(2), 1, 3, InterpolationMethod.Linear, Nothing)

Должен вернуть: 2

Как мне реализовать это?Мне просто нужно иметь возможность интерполировать линейно и с кривой (экспоненциально? Извините за мой неалгебраический язык).

(кстати, я округляю DateTime / TimeSpan до дней)

Ответы [ 3 ]

1 голос
/ 27 января 2011

Я написал образец с тестовым кодом.Это работает, как вы описали, но без дополнительного параметра.Для чего вам это нужно?

    private static double GetValueAt(TimeSpan at, DateTime from, DateTime to, double start, double end, Func<TimeSpan, double> function)
    {
        // fullFunction(time) = k *  function(time) + a 
        // k and a are calculated according to start and end values
        TimeSpan totalTime = to - from;
        double k = (end - start) / function(totalTime);
        double a = start - k * function(new TimeSpan(0));
        Func<TimeSpan, double> fullFunction = t => k * function(t) + a;
        return fullFunction(at);
    }

    static void Main(string[] args)
    {
        Func<TimeSpan, double> f1 = t => t.TotalDays;
        Func<TimeSpan, double> fx2 = t => t.TotalDays * 2;
        Func<TimeSpan, double> fsquare = t => Math.Pow(t.TotalDays, 2);

        var f1Value = GetValueAt(TimeSpan.FromDays(1), DateTime.Today, DateTime.Today.AddDays(4), 1, 5, f1); // 2
        var fx2Value = GetValueAt(TimeSpan.FromDays(1), DateTime.Today, DateTime.Today.AddDays(4), 1, 9, fx2); // 3
        var fsquareValue = GetValueAt(TimeSpan.FromDays(1), DateTime.Today, DateTime.Today.AddDays(2), 1, 5, fsquare); // 2
    }
1 голос
/ 28 января 2011

Поскольку я писал что-то похожее снова и снова, я сначала написал класс, содержащий функции, такие как:

    /// <summary>
    /// Calculate the position, of a given value, within a certain range/size
    /// depending on the minimum and maximum (scale) for the value.
    /// </summary>
    /// <param name="data">Value for which to calculate the position.</param>
    /// <param name="minimum_value">Minimum value of the scale on which the value must lie.</param>
    /// <param name="maximum_value">Maximum value of the scale on which the value must lie.</param>
    /// <param name="size_begin">The begin value of the size on which the scale must be spread.</param>
    /// <param name="size_end">The end value of the size on which the scale must be spread.</param>
    /// <returns>The respectively positions of the data value.</returns>
    static public double Position_In_Size(double data, double minimum_value, double maximum_value, double size_begin, double size_end)
    {
        return size_begin + (((size_end - size_begin) / (maximum_value - minimum_value)) * (data - minimum_value));
    }

Это быстро стало действительно большим классом для поддержки всех типов типов.C # не поддерживает обобщений для типов значений из коробки.

Недавно я нашел библиотеку, которая реализует обобщения в .NET с обходным путем.

Используя эту библиотеку, у меня теперь более чистая реализация,Используя универсальный интервальный класс, я могу отображать значения из одного диапазона в другой независимо от типа.

// Result will be 0.
Interval<int> interval = new Interval<int>( 0, 10 );
double result = interval.Map<double>( 5, new Interval<double>( -100, 100 ) );

Я написал это как часть некоторых классов интерполяции, над которыми я работал: http://whathecode.wordpress.com/2011/01/24/interpolation-no-more/

Исходный код можно найти в моей библиотеке расширений FCL , в пространстве имен Whathecode.System.Arithmetic.Range .

1 голос
/ 27 января 2011

Я бы использовал что-то вроде (в псевдокоде) (((At-From)/(To-From)) * (Finish-Start)) + Start.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...