0

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

n = 1(无插值)和 n = 2(线性插值)的情况已经实现并且似乎有效。但是现在我已经在努力使双线性插值(对于 n = 4 的情况)维度不可知,我不知道从那时起我应该如何进展(n = 8,...,2^n)。

是否有解决此问题的通用方法,或者我是否应该对某些情况进行硬编码并抛出 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;
        }
    }
}

4

1 回答 1

0

这似乎与您的算法一样,但与维度无关。我并不是说您的计算是正确的 - 我只是说我认为这是相同的计算,但对于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;
}
于 2013-11-11T10:58:10.667 回答