n维中未知点数的多线性插值

时间:2013-11-11 10:14:11

标签: java multidimensional-array interpolation

我正在尝试创建一种方法,可以在n维空间中对未知数量的点(数字等于2 ^ n)进行多线性插值。

n = 1(无插值)和n = 2(线性插值)的情况已经实现并且似乎有效。但是现在我已经在努力使双线性插值(对于n = 4的情况)维度不可知,我不知道我应该从那一点开始(n = 8,...,2 ^ n)。 / p>

是否存在解决此问题的一般方法,或者我应该对某些情况进行硬编码,否则会抛出UnsupportedOperationException?

下面我添加了一个SSCCE,希望能澄清我的问题。它由一个存储坐标和一个值的点类组成,还包含一些功能,如计算到另一个点的距离,以及插值方法,它已包含我对n = 1和n = 2的情况的实现。

代码


import java.util.ArrayList;
import java.util.List;

public class Interpolator {

    public static void main(String[] args) {
        Interpolator ip = new Interpolator();

        Point currentPoint = new Point(new long[]{5, 5}, 0);

        List<Point> neighbors = new ArrayList<Point>() {{
            add(new Point(new long[]{3, 3}, 7));
            add(new Point(new long[]{10, 10}, 4));
        }};

        System.out.println(ip.interpolate(currentPoint, neighbors));
    }

    public float interpolate(Point currentPoint, List<Point> neighbors) {

        if (neighbors.size() == 1) {
            // no interpolation necessary with only one neighbor
            return neighbors.get(0).getValue();
        } else if (neighbors.size() == 2) {
            // distance between point and the two neighbors
            float distanceOne = currentPoint.distance(neighbors.get(0));
            float distanceTwo = currentPoint.distance(neighbors.get(1));
            float completeDistance = distanceOne + distanceTwo;

            // calculate weights
            float weightOne = 1 - distanceOne / completeDistance;
            float weightTwo = 1 - distanceTwo / completeDistance;

            // linear interpolation
            return neighbors.get(0).getValue() * weightOne
                    + neighbors.get(1).getValue() * weightTwo;
        } else if (neighbors.size() == 4) {
            //TODO: bilinear interpolation
        } else if(neighbors.size() == 8){
            //TODO: trilinear interpolation
        }

        //TODO: quadlinear interpolation or higher?
        return -1;
    }

    public static class Point {

        private long[] m_coordinates;
        private float m_value;

        public Point(final long[] coordinates, float value) {
            this.m_coordinates = coordinates;
            this.m_value = value;
        }

        public long[] getCoordinates() {
            return this.m_coordinates;
        }

        public int numDim() {
            return m_coordinates.length;
        }

        public long dim(final int i) {
            return this.m_coordinates[i];
        }

        public float distance(final Point otherPoint) {
            if (this.numDim() != otherPoint.numDim()) {
                throw new IllegalArgumentException(
                        "Can't measure distance between points with different dimensionality");
            }

            float sum = 0;
            for (int i = 0; i < this.numDim(); i++) {
                sum += Math.pow(this.dim(i) - otherPoint.dim(i), 2);
            }

            return (float) Math.sqrt(sum);
        }

        public float getValue() {
            return m_value;
        }
    }
}

1 个答案:

答案 0 :(得分:1)

这似乎与您的算法有关,但与维度无关。我不是说你的计算是正确的 - 我只是说我认为这是相同的计算,但对于 n 维度:

public float interpolate(Point currentPoint, List<Point> neighbors) {
  int dimensions = neighbors.size();
  float[] distance = new float[dimensions];
  float sumDistances = 0;
  for (int i = 0; i < dimensions; i++) {
    distance[i] = currentPoint.distance(neighbors.get(i));
    sumDistances += distance[i];
  }
  float[] weight = new float[dimensions];
  for (int i = 0; i < dimensions; i++) {
    weight[i] = 1 - distance[i] / sumDistances;
  }
  float interpolatedDistance = 0;
  for (int i = 0; i < dimensions; i++) {
    interpolatedDistance += neighbors.get(i).getValue() * weight[i];
  }
  return interpolatedDistance;
}