Кто-нибудь знает билинейную интерполяцию данных с использованием любого из этих языков 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
Пожалуйста помоги
(Отредактировано, чтобы учесть движущуюся цель.)
Следующие работы на вашем (очень ограничено!) образец набора данных. Это работает так:
Поскольку ваш примерный набор данных очень мал, трудно предложить оптимизацию. Если расстояние между последовательными строками и столбцами неизвестно (данные в случайном порядке, как в вашем примере), лучше всего попытаться прочитать весь файл в память.
Если ваши данные предварительно отсортированы по строка, Вы можете прочитать одну строку в начале, а затем для каждого цикла прочитать следующую строку. Если, кроме того, данные также сортируются по колонка, Вы можете пропустить весь 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
...
(и т. д. — бегите, чтобы увидеть результаты)
Похоже, работа для sort -k1 -k2 -g data.txt
,