Package com.opengamma.analytics.math.interpolation.data

Source Code of com.opengamma.analytics.math.interpolation.data.KrigingInterpolatorDataBundle

/**
* Copyright (C) 2009 - present by OpenGamma Inc. and the OpenGamma group of companies
*
* Please see distribution for license.
*/
package com.opengamma.analytics.math.interpolation.data;

import java.util.Arrays;
import java.util.List;

import org.apache.commons.lang.ObjectUtils;
import org.apache.commons.lang.Validate;

import com.opengamma.analytics.math.function.Function1D;
import com.opengamma.analytics.math.interpolation.DistanceCalculator;
import com.opengamma.analytics.math.linearalgebra.Decomposition;
import com.opengamma.analytics.math.linearalgebra.DecompositionFactory;
import com.opengamma.analytics.math.linearalgebra.DecompositionResult;
import com.opengamma.analytics.math.matrix.DoubleMatrix1D;
import com.opengamma.analytics.math.matrix.DoubleMatrix2D;
import com.opengamma.util.tuple.Pair;

/**
*
*/
public class KrigingInterpolatorDataBundle extends InterpolatorNDDataBundle {
  private final Decomposition<?> _decomp = DecompositionFactory.LU_COMMONS;
  private final Function1D<Double, Double> _variogram;
  private final double[] _weights;

  /**
   * @param data The data
   * @param beta The beta
   */
  public KrigingInterpolatorDataBundle(final List<Pair<double[], Double>> data, final double beta) {
    super(data);
    Validate.isTrue(beta >= 1 && beta < 2, "Beta was not in acceptable range (1 <= beta < 2");
    _variogram = calculateVariogram(data, beta);
    _weights = calculateWeights(data, _variogram);
  }

  /**
   * Gets the variogram field.
   * @return the variogram
   */
  public Function1D<Double, Double> getVariogram() {
    return _variogram;
  }

  /**
   * Gets the weights field.
   * @return the weights
   */
  public double[] getWeights() {
    return _weights;
  }

  private Function1D<Double, Double> calculateVariogram(final List<Pair<double[], Double>> data, final double beta) {
    final int n = data.size();
    double sum = 0.0;
    double normSum = 0.0;
    double[] x1, x2;
    double y1, y2;
    Pair<double[], Double> dataPoint;
    double rBeta;
    for (int i = 0; i < n; i++) {
      dataPoint = data.get(i);
      x1 = dataPoint.getFirst();
      y1 = dataPoint.getSecond();
      for (int j = i + 1; j < n; j++) {
        dataPoint = data.get(j);
        x2 = dataPoint.getFirst();
        y2 = dataPoint.getSecond();
        rBeta = Math.pow(DistanceCalculator.getDistance(x1, x2), beta);
        sum += (y1 - y2) * (y1 - y2) * rBeta;
        normSum += rBeta * rBeta;
      }
    }

    final double alpha = sum / 2.0 / normSum;

    return new Function1D<Double, Double>() {

      @Override
      public Double evaluate(final Double x) {
        return alpha * Math.pow(x, beta);
      }
    };
  }

  private double[] calculateWeights(final List<Pair<double[], Double>> data, final Function1D<Double, Double> variogram) {
    final int n = data.size();
    final double[] y = new double[n + 1];
    final double[][] v = new double[n + 1][n + 1];
    Pair<double[], Double> dataPoint;
    double[] x1, x2;

    for (int i = 0; i < n; i++) {
      dataPoint = data.get(i);
      x1 = dataPoint.getFirst();
      y[i] = dataPoint.getSecond();
      for (int j = i + 1; j < n; j++) {
        dataPoint = data.get(j);
        x2 = dataPoint.getFirst();
        final double temp = variogram.evaluate(DistanceCalculator.getDistance(x1, x2));
        v[i][j] = temp;
        v[j][i] = temp;
      }
      v[i][n] = 1;
      v[n][i] = 1;
    }
    v[n][n] = 0;
    y[n] = 0;

    double[] res;
    try {
      res = solve(v, y, _decomp);
    } catch (final IllegalArgumentException e) {
      final Decomposition<?> decomp = DecompositionFactory.SV_COMMONS;
      res = solve(v, y, decomp);
    }

    return res;
  }

  private double[] solve(final double[][] v, final double[] y, final Decomposition<?> decomp) {
    final DecompositionResult decompRes = decomp.evaluate(new DoubleMatrix2D(v));
    final DoubleMatrix1D res = decompRes.solve(new DoubleMatrix1D(y));
    return res.getData();
  }

  @Override
  public int hashCode() {
    final int prime = 31;
    int result = super.hashCode();
    result = prime * result + _decomp.hashCode();
    result = prime * result + _variogram.hashCode();
    result = prime * result + Arrays.hashCode(_weights);
    return result;
  }

  @Override
  public boolean equals(final Object obj) {
    if (this == obj) {
      return true;
    }
    if (!super.equals(obj)) {
      return false;
    }
    if (!(obj instanceof KrigingInterpolatorDataBundle)) {
      return false;
    }
    final KrigingInterpolatorDataBundle other = (KrigingInterpolatorDataBundle) obj;
    if (!ObjectUtils.equals(_decomp, other._decomp)) {
      return false;
    }
    if (!ObjectUtils.equals(_variogram, other._variogram)) {
      return false;
    }
    if (!Arrays.equals(_weights, other._weights)) {
      return false;
    }
    return true;
  }

}
TOP

Related Classes of com.opengamma.analytics.math.interpolation.data.KrigingInterpolatorDataBundle

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.