Билинейная интерполяция двумерных данных с использованием c / awk / shell

Кто-нибудь знает билинейную интерполяцию данных с использованием любого из этих языков c / awk / shell / c ++

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

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

Я ожидаю, что выходной как этот интервал 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

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

-2

Решение

(Отредактировано, чтобы учесть движущуюся цель.)

Следующие работы на вашем (очень ограничено!) образец набора данных. Это работает так:

  1. Загрузите набор данных в память и сохраните его в простой структуре.
  2. Для каждого элемента данных строки / столбца найдите необходимые следующие элементы: (строка, столбец> = 1), (строка> = 1, столбец) и (строка> = 1, столбец> = 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
...

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

1

Другие решения

Похоже, работа для sort -k1 -k2 -g data.txt,

-1

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector