2014-02-15 2 views
-2

Кто-нибудь знает билинейной интерполяции данных, используя любой из этих языков с/AWK/оболочка/C++билинейной интерполяции 2d данных с использованием с/AWK/оболочка

Мой файл данных, этот файл не отсортирован не знаю как сделать :(очень большой файл

row col data 
20 14 91 
21 15 95 
21 14 162 
20 15 210 

Я ожидаю Ouput как этот 0,5 интервала для столбца и 0,2 для ряда

20 14 91 
20 14.5 150.5 
20 15 210 
20.2 14.5 146.1 
..... 
..... 
..... 
21 14 162 
21 14.5 128.5 
21 15 95 

Пожалуйста, помогите

+0

Где дополнительные 'данные 'исходит, как' 150.5'? Это очень неясно. – Jotne

+0

Уважаемый Jotne, очень ясно, что вы не знаете, что такое билинейная интерполяция, большое спасибо за негативное голосование. – user3304642

+0

Я не дал вам отрицательного голоса, что вы должны обвинять других. – Jotne

ответ

1

(под редакцией, чтобы для Moving Target.)

следующие работы на вашем (самого ограниченного!) Набора выборочных данных. Он работает следующим образом:

  1. Загрузите набор данных в память и сохраните его в простой структуре.
  2. Для каждого элемента данных столбца/столбца найдите нужные элементы: (строка, col> = 1), (строка> = 1, col) и (строка> = 1, col> = 1). Непроверенный (из-за отсутствия данных), но он должен использовать ближайшее значение.
  3. Если все четыре точки данных известны, интерполируйте слева направо и сверху вниз.

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

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

Пух, окружающий все printf, состоит в том, что ваш предпочтительный формат вывода недоступен со стандартными спецификаторами форматирования C printf.

#include <stdio.h> 
#include <stdlib.h> 
#include <string.h> 

#define MAX_ITEM 25 

struct data_t { 
    int row; 
    int col; 
    int data; 
} array[MAX_ITEM]; 

int n_item = 0; 

// interpolate A > B 
//    v v 
//    C > D 
void interpolate (int A, int B, int C, int D) 
{ 
    int i,j, deltaCol,deltaRow; 
    float a,b, delta_AC, delta_BD, value; 

    a = array[A].data; 
    b = array[B].data; 

    deltaCol = 2*(array[B].col-array[A].col); 
    deltaRow = 5*(array[C].row-array[A].row); 

    delta_AC = (array[C].data-array[A].data)/(float)deltaRow; 
    delta_BD = (array[D].data-array[B].data)/(float)deltaRow; 

    // rows 
    for (j=0; j<=deltaRow; j++) 
    { 
     // columns 
     for (i=0; i<=deltaCol; i++) 
     { 
      if (j % 5) 
       printf ("%.1f ", array[A].row+(j/5.0f)); 
      else 
       printf ("%d ", array[A].row+j/5); 
      if (i % 2) 
       printf ("%.1f ", array[A].col+(i/2.0f)); 
      else 
       printf ("%d ", array[A].col+i/2); 

      value = a+(b-a)*((float)i/deltaCol); 
      if ((int)(100*value+0.5) % 100) 
       printf ("%.1f\n", value); 
      else 
       printf ("%d\n", (int)(value+0.5f)); 

     } 
     a += delta_AC; 
     b += delta_BD; 
    } 
} 

// For a start row/col A find B,C,D 
// where B = A(0,>=1), C=A(>=1,0), D=A(>=1,>=1) 
void interpolate_from (int A) 
{ 
    int i, B=-1, C=-1, D=-1; 

    for (i=0; i<n_item; i++) 
    { 
     if (i == A) continue; 
     if (array[A].row == array[i].row) 
     { 
      if (array[A].col < array[i].col || (B != -1 && array[i].col < array[B].col)) 
      { 
       B = i; 
      } 
     } else 
     if (array[A].row < array[i].row) 
     { 
      if (array[A].col == array[i].col) 
      { 
       C = i; 
      } else 
      { 
       if (array[A].col < array[i].col || (D != -1 && array[i].col < array[D].col)) 
       { 
        D = i; 
       } 
      } 
     } 
     if (B+1 && C+1 && D+1) 
     { 
      interpolate (A,B,C,D); 
      return; 
     } 
    } 

} 

int main (void) 
{ 
    int i,j,k; 
    FILE *f; 

    f = fopen ("data.txt", "r"); 
    while (n_item < MAX_ITEM && fscanf (f, "%d %d %d", &i,&j, &k) == 3) 
    { 
     array[n_item].row = i; 
     array[n_item].col = j; 
     array[n_item].data = k; 
     n_item++; 
    } 
    fclose (f); 

    for (i=0; i<n_item; i++) 
     interpolate_from (i); 

    printf ("\n"); 
    return 0; 
} 

С измененными набора данных

20 14 91 
21 14 162 
21 18 95 
20 18 210 

выход:

20 14 91 
20 14.5 105.9 
20 15 120.8 
20 15.5 135.6 
... 

(и т.д. - бежать, чтобы увидеть результаты)

+0

Объяснение: Это довольно простая двулинейная интерполяция, от строки до строки и столбца к столбцу. Нарисуйте свои цифры на листе бумаги и выведите вручную то, что должно быть приращением на строку. Затем, используя эти числа, интерполируйте по столбцам слева направо. Измененная программа работает как с вашим исходным набором данных, так и с вашим новым - но обратите внимание, цифры должны по-прежнему составлять квадрат. – usr2564301

-1

Звучит как работа для sort -k1 -k2 -g data.txt.

+0

Мой вопрос ясный. Я ищу билинейную интерполяцию не 'sort' – user3304642

+0

@Peter Приносим извинения, я думал, что у вас полный набор данных, просто вышел из строя. В любом случае вам нужно будет сортировать, прежде чем вы начнете; то вы можете заполнить пробелы программой. Поскольку вы не согласны с тем, какие номера вы хотели заполнить, я не знаю, какие из них вам нужны; но вы сможете обработать его за один проход, я бы подумал. – tabstop

+0

Его хорошо, спасибо за ответ – user3304642

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