2D Интерполяция нерегулярной сетки Фортран
Как я могу реализовать 2-мерную интерполяцию в FORTRAN, где данные выглядят так, как показано ниже. x и y- две координаты, а z - значение, зависящее от них, x равномерно распределено, но y неравномерно, и максимальное значение y, соответствующее равномерным значениям x, продолжает увеличиваться. Не теряя много точности
- Какой самый простой способ получить значение z на основе заданных x и y?
- Какой самый быстрый способ получить значение z на основе данных х и у?
Спасибо СМ
x y z
-----------
0 0 -
0 0.014 -
0 0.02 -
.....
....
0.1 0 -
0.1 0.02 -
0.1 0.03 -
.......
.....
1.0 0 -
1.0 0.05 -
1.0 0.08 -
.......
.......
3 ответа
Я предполагаю, что вы уже прочитали свои данные в массив N x 3, следуя заданному вами формату. Я предполагаю, что вы не знаете заранее, что такое интервал X - вы точно не знаете интервал Y, поскольку он изменяется. Таким образом, я бы рекомендовал следующую стратегию:
- Выясните интервал X: начните с первого ряда и проходите по элементам X, пока не увидите изменение значения. Теперь вы знаете XSTART и XSTEP - они понадобятся вам позже.
- Выполните двоичный поиск в вашем массиве для значения X, пока не найдете значение XFOUND, такое, что XFOUND
- Предполагая, что вы указываете "где-то в списке", вы находите соответствующее значение Y - в зависимости от того, является ли оно больше или меньше требуемого значения, вы увеличиваете или уменьшаете массив, пока не найдете первую запись
- Вам нужно еще две точки, прежде чем вы сможете выполнить интерполяцию - повторите этот процесс, ища "следующее большее значение X". Это даст вам XYZ21 и XYZ22
- Теперь вы можете подумать о расчете интерполированного значения Z. В целом, существуют разные методики с разной точностью:
- "Ближайший сосед": найдите ближайшую точку и используйте ее значение Z (самое простое, наименее точное)
- "линейная интерполяция": найдите три ближайшие точки и выполните линейную интерполяцию значений на основе относительных расстояний
- "оценки более высокого порядка": для этого обычно требуется создать полное отображение связности точек сетки, чтобы можно было выполнить сплайн-интерполяцию и получить плавную интерполяцию, которая обычно будет более точной в точках между точками сетки (при условии, что функция, описываемая образцами, на самом деле является гладкой функцией!)
- Предполагая, что вы указываете "где-то в списке", вы находите соответствующее значение Y - в зависимости от того, является ли оно больше или меньше требуемого значения, вы увеличиваете или уменьшаете массив, пока не найдете первую запись
Мой Фортран немного ржавый - надеюсь, это поможет.
PS - потенциально более простой подход заключается в использовании факта, что значения X уже равномерно распределены. Это позволяет вам сделать лучшую интерполяцию. Смотрите эту картинку:
Прежде чем найти самый быстрый способ решения этой проблемы, я бы предложил найти способ решить эту проблему. Вкратце, я бы предложил:
1) Найти триангуляцию Делоне для точек (x,y). Код Fortran для этого, например, находится в GEOMPACK.
2) Для интерполяции, учитывая триангуляцию Делоне, найдите треугольник, содержащий точку, в которой должна выполняться интерполяция, а затем интерполируйте значение z на основе расположения точки относительно каждой из вершин треугольника.
(РЕДАКТИРОВАТЬ) Я забыл название метода (если я его когда-либо знал), но благодаря @Floris хороший подход к интерполяции в треугольнике называется барицентрической интерполяцией, которая находит интерполированное значение на основе соотношений площадей в трех меньших треугольниках, на которые можно разбить большой треугольник, рисуя линии от точки внутри большого треугольника до каждого из углов треугольника. Площадь каждого маленького треугольника можно определить по длине каждой стороны треугольника по формуле Герона.
Если бы были необходимы улучшения скорости, я думаю, что их можно было бы получить, главным образом, путем поиска быстрого способа нахождения треугольника, содержащего точку интерполяции, но я бы хотел профилировать некоторые тестовые прогоны, прежде чем выбирать, какие биты кода оптимизировать.
Я предлагаю использовать один из алгоритмов интерполяции TOMS:https://people.sc.fsu.edu/~jburkardt/f77_src/toms526/toms526.htmlhttps://people.sc.fsu.edu/~jburkardt/f77_src/toms660 /toms660.html https://people.sc.fsu.edu/~jburkardt/f77_src/toms790/toms790.html