2009-08-03 2 views
7

Я ищу библиотеку java или некоторую помощь для написания моей собственной функции интерполяции. То есть у меня есть два массива двойников, которые могут быть разных размеров, но упорядочены. Мне нужно сделать оценку промежуточных значений и вставить так, чтобы оба массива стали одного размера. Фактически общее количество точек, входящих в интерполяцию, представляет собой сумму двух размеров массива минус 1. Диапазон каждого массива должен оставаться неизменным, поэтому нет необходимости экстраполяции.Интерполяция по массиву (или двум)

например. a1 = [1, 4, 9, 16, 25, 36] и a2 = [6, 9, 14, 30]

результаты могут быть, например.

a1 = [1, 2,25, 4, 6,25, 9, 12,25, 16, 25, 36] и а2 = [6, 6,5625, 7,25, 9, 10,0625, 11,25, 14, 25,25, 30]

эти примеры: f(x) = x^2 and g(x) = x^2 + 5, однако легко мог быть любым полином - точка должна быть в состоянии оценить/приблизить функцию из набора данных достаточно хорошо, чтобы обеспечить достаточно достаточную интерполяцию. Здесь значение x является только индексом входного массива. На выходе важны только значения y.

+0

Ваш вопрос немного неясно. Не могли бы вы дать нам тривиальный конкретный пример? – skaffman

+0

Я отредактировал, чтобы показать пример, хотя это не обязательно результат, который могла бы дать функция, но я думаю, что он демонстрирует один приемлемый вывод. – Robert

ответ

13

Другие ответы дают вам линейные интерполяции - на самом деле они не работают для сложных нелинейных данных. Вы хотите spline fit, (сплайн-интерполяция) Я верю.

Сплайн подходит для описания областей данных с использованием набора контрольных точек из данных, а затем применяет полиномиальную интерполяцию между контрольными точками. Больше контрольных точек дает вам более точную подгонку, менее общую форму. Сплайны гораздо точнее, чем линейные, более быстрые в использовании, чем общая регрессия, лучше, чем полином высокого порядка, потому что он не будет делать сумасшедшие вещи между контрольными точками.

Я не могу вспомнить имена с верхней части головы, но на Java есть отличные библиотеки для подгонки - я предлагаю вам искать один, а не писать свою собственную функцию.


** EDIT: Библиотеки, которые могут быть полезны: **

** Теория/код, который может быть полезен: **

  • Сплайновые апплеты с кодом: link
  • Arkan сплайна подходящих для поли-линия Безье сплайнов
  • Theory сплайнов, а некоторые математические для установки. Больше математики, меньше кода, может помочь, если библиотеки нет.
+0

Да, это именно то, что мне нужно ... точнее, что и где эти библиотеки. – Robert

+0

Я добавил ссылки на некоторые библиотеки и теорию кода + для работы с сплайнами, если библиотеки не работают. Не забудьте принять ответ, если он вам полезен! – BobMcGee

0

Простая линейная интерполяция может быть вычислена с помощью что-то вроде:

Point2D interp1_lin(Point2D p1, Point2D p2, double x) { 
//Pre conditions 
assert p1.x<x; 
assert x<p2.x; 
//Calculate slope from p1 to p2 
double m = (p2.x-p1.x)/(p2.y-p1.y); 
//Calculate y position of x 
double y = (x-p1.x)*m+p1.y; 
//create new point 
return new Point2D.Double(x,y); 
} 

ли эта помощь?

0

Вам нужно получить значения x, соответствующие значениям y. В противном случае ни один алгоритм не сможет определить, является ли [1, 16, 81] x^2 для [1, 4, 9] или x^4 для [1, 2, 3]. Вы бы интерполировали шесть значений или нет?

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

+0

ОК, я не продумал свой пример правильно - предположим, что каждый индекс массива является значением x для ввода, а затем после интерполяции нас больше не интересует x-значение. – Robert

2

Предназначен для массива данных в одном измерении

import java.util.ArrayList; 

public class Interpolator { 

public static Float CosineInterpolate(Float y1,Float y2,Float mu) 
{ 
    double mu2; 

    mu2 = (1.0f-Math.cos(mu*Math.PI))/2.0f; 
    Float f_mu2 = new Float(mu2); 
    return(y1*(1.0f-f_mu2)+y2*f_mu2); 
} 

public static Float LinearInterpolate(Float y1,Float y2,Float mu) 
{ 
    return(y1*(1-mu)+y2*mu); 
} 


public static Float[] Interpolate(Float[] a, String mode) { 

    // Check that have at least the very first and very last values non-null 
    if (!(a[0] != null && a[a.length-1] != null)) return null; 

    ArrayList<Integer> non_null_idx = new ArrayList<Integer>(); 
    ArrayList<Integer> steps = new ArrayList<Integer>(); 

    int step_cnt = 0; 
    for (int i=0; i<a.length; i++) 
    { 
     if (a[i] != null) 
     { 
      non_null_idx.add(i); 
      if (step_cnt != 0) { 
       steps.add(step_cnt); 
       System.err.println("aDDed step >> " + step_cnt); 
      } 
      step_cnt = 0; 
     } 
     else 
     { 
      step_cnt++; 
     } 
    } 

    Float f_start = null; 
    Float f_end = null; 
    Float f_step = null; 
    Float f_mu = null; 

    int i = 0; 
    while (i < a.length - 1) // Don't do anything for the very last element (which should never be null) 
    { 
     if (a[i] != null && non_null_idx.size() > 1 && steps.size() > 0) 
     { 
      f_start = a[non_null_idx.get(0)]; 
      f_end = a[non_null_idx.get(1)]; 
      f_step = new Float(1.0)/new Float(steps.get(0) + 1); 
      f_mu = f_step; 
      non_null_idx.remove(0); 
      steps.remove(0); 
     } 
     else if (a[i] == null) 
     { 
      if (mode.equalsIgnoreCase("cosine")) 
       a[i] = CosineInterpolate(f_start, f_end, f_mu); 
      else 
       a[i] = LinearInterpolate(f_start, f_end, f_mu); 
      f_mu += f_step; 
     } 
     i++; 
    } 

    return a; 
} 
} 

Не знаю, если это помогает ... Это очень быстро закодированы, так что если кто-то имеет более хороший/более исполнительский способ сделать то же самое , спасибо за вклад.

ПРИМЕНЕНИЕ:

input : Float[] a = {1.0f, null, null, 2.0f, null, null, null, 15.0f}; 

call : Interpolator.Interpolate(a, "Linear"); 

output : 1.0|1.3333333|1.6666667|2.0|5.25|8.5|11.75|15.0 
+0

возвращает нуль. –

1

Я знаю, что это старый ответ, но это первый Google хит при поиске Java интерполяции. В принятом ответе содержатся полезные ссылки, но JMSL необходимо приобрести, а веб-сайт JSpline + выглядит отрывочно.

Apache Commons Math имеет реализации линейных и сплайн-интерполяций, которые кажутся простыми, функциональными и заслуживающими доверия.

http://commons.apache.org/proper/commons-math/

0

Облегченная версия одномерный массив линейной интерпол:

public static float[] interpolate(float[] data) { 
    int startIdx = -1; 
    float startValue = 0f; 
    float element; 
    for (int i = 0; i < data.length - 1; i++) { 
     element = data[i]; 
     if (element != 0f) { 
      if (startIdx != -1) { 
       doInterpolate(startValue, element, startIdx + 1, i - startIdx - 1, data); 
      } 
      startValue = element; 
      startIdx = i; 
     } 
    } 
    return data; 
} 

private static void doInterpolate(float start, float end, int startIdx, int count, float[] data) { 
    float delta = (end - start)/(count + 1); 
    for (int i = startIdx; i < startIdx + count; i++) { 
     data[i] = start + delta * (i - startIdx + 1); 
    } 
} 
0

быть очень осторожным с сплайн-припадков и полиномиальных припадков. Эти два могут дать бессмысленное поведение, которое может сорвать многие виды использования (что считается представлением) данных.

Все, что использует производные (склоны) данных, может быть полностью разрушено.

Лучшая вещь, которую вы можете сделать, это нарисовать данные, понять, что она делает, и только после этого подставить (линейный, полиномиальный, лог-журнал) регрессию; как только вы это сделаете, вы должны построить свою подиновку над исходными данными и убедиться, что вы видите разумное согласие. Пропуск этого сравнительного шага - очень плохая идея.

Некоторые наборы данных не поддаются подгонке полиномов, log-log и т. Д .; если ваши точки данных надлежащим образом распределены по диапазону данных, нет ничего плохого в кусочно-интерполяционной (линейной или полиномиальной и т. д.). Чтобы победить мертвую лошадь, если вы используете кусочную интерполяцию, избегайте всего, что использует производные/наклоны вашей кусочной интерполяции, потому что оно будет иметь разрывы и приведет к тому, что вещи будут вести себя плохо.

Смежные вопросы