MahalanobisEstimator.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 6k
Category:

Windows Develop

Development Platform:

Java

  1. /*
  2.  *    This program is free software; you can redistribute it and/or modify
  3.  *    it under the terms of the GNU General Public License as published by
  4.  *    the Free Software Foundation; either version 2 of the License, or
  5.  *    (at your option) any later version.
  6.  *
  7.  *    This program is distributed in the hope that it will be useful,
  8.  *    but WITHOUT ANY WARRANTY; without even the implied warranty of
  9.  *    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  10.  *    GNU General Public License for more details.
  11.  *
  12.  *    You should have received a copy of the GNU General Public License
  13.  *    along with this program; if not, write to the Free Software
  14.  *    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  15.  */
  16. /*
  17.  *    MahalanobisEstimator.java
  18.  *    Copyright (C) 1999 Len Trigg
  19.  *
  20.  */
  21. package weka.estimators;
  22. import java.util.*;
  23. import weka.core.*;
  24. /** 
  25.  * Simple probability estimator that places a single normal distribution
  26.  * over the observed values.
  27.  *
  28.  * @author Len Trigg (trigg@cs.waikato.ac.nz)
  29.  * @version $Revision: 1.4 $
  30.  */
  31. public class MahalanobisEstimator implements Estimator {
  32.   /** The inverse of the covariance matrix */
  33.   private Matrix m_CovarianceInverse;
  34.   /** The determinant of the covariance matrix */
  35.   private double m_Determinant;
  36.   /**
  37.    * The difference between the conditioning value and the conditioning mean
  38.    */
  39.   private double m_ConstDelta;
  40.   /** The mean of the values */
  41.   private double m_ValueMean;
  42.   /** 2 * PI */
  43.   private static double TWO_PI = 2 * Math.PI;
  44.   /**
  45.    * Returns value for normal kernel
  46.    *
  47.    * @param x the argument to the kernel function
  48.    * @param variance the variance
  49.    * @return the value for a normal kernel
  50.    */
  51.   private double normalKernel(double x) {
  52.     
  53.     Matrix thisPoint = new Matrix(1, 2);
  54.     thisPoint.setElement(0, 0, x);
  55.     thisPoint.setElement(0, 1, m_ConstDelta);
  56.     return Math.exp(-thisPoint.multiply(m_CovarianceInverse).
  57.     multiply(thisPoint.transpose()).getElement(0, 0) 
  58.     / 2) / (Math.sqrt(TWO_PI) * m_Determinant);
  59.   }
  60.   
  61.   /**
  62.    * Constructor
  63.    *
  64.    * @param the number of possible symbols
  65.    */
  66.   public MahalanobisEstimator(Matrix covariance, double constDelta,
  67.       double valueMean) {
  68.     
  69.     m_CovarianceInverse = null;
  70.     if ((covariance.numRows() == 2) && (covariance.numColumns() == 2)) {
  71.       double a = covariance.getElement(0, 0);
  72.       double b = covariance.getElement(0, 1);
  73.       double c = covariance.getElement(1, 0);
  74.       double d = covariance.getElement(1, 1);
  75.       if (a == 0) {
  76. a = c; c = 0;
  77. double temp = b;
  78. b = d; d = temp;
  79.       }
  80.       if (a == 0) {
  81. return;
  82.       }
  83.       double denom = d - c * b / a;
  84.       if (denom == 0) {
  85. return;
  86.       }
  87.       m_Determinant = covariance.getElement(0, 0) * covariance.getElement(1, 1)
  88. - covariance.getElement(1, 0) * covariance.getElement(0, 1);
  89.       m_CovarianceInverse = new Matrix(2, 2);
  90.       m_CovarianceInverse.setElement(0, 0, 1.0 / a + b * c / a / a / denom);
  91.       m_CovarianceInverse.setElement(0, 1, -b / a / denom);
  92.       m_CovarianceInverse.setElement(1, 0, -c / a / denom);
  93.       m_CovarianceInverse.setElement(1, 1, 1.0 / denom);
  94.       m_ConstDelta = constDelta;
  95.       m_ValueMean = valueMean;
  96.    }
  97.   }
  98.   /**
  99.    * Add a new data value to the current estimator. Does nothing because the
  100.    * data is provided in the constructor.
  101.    *
  102.    * @param data the new data value 
  103.    * @param weight the weight assigned to the data value 
  104.    */
  105.   public void addValue(double data, double weight) {
  106.     
  107.   }
  108.   /**
  109.    * Get a probability estimate for a value
  110.    *
  111.    * @param data the value to estimate the probability of
  112.    * @return the estimated probability of the supplied value
  113.    */
  114.   public double getProbability(double data) {
  115.     
  116.     double delta = data - m_ValueMean;
  117.     if (m_CovarianceInverse == null) {
  118.       return 0;
  119.     }
  120.     return normalKernel(delta);
  121.   }
  122.   /** Display a representation of this estimator */
  123.   public String toString() {
  124.     
  125.     if (m_CovarianceInverse == null) {
  126.       return "No covariance inversen";
  127.     }
  128.     return "Mahalanovis Distribution. Mean = "
  129.       + Utils.doubleToString(m_ValueMean, 4, 2)
  130.       + "  ConditionalOffset = "
  131.       + Utils.doubleToString(m_ConstDelta, 4, 2) + "n"
  132.       + "Covariance Matrix: Determinant = " + m_Determinant 
  133.       + "  Inverse:n" + m_CovarianceInverse;
  134.   }
  135.   /**
  136.    * Main method for testing this class.
  137.    *
  138.    * @param argv should contain a sequence of numeric values
  139.    */
  140.   public static void main(String [] argv) {
  141.     
  142.     try {
  143.       double delta = 0.5;
  144.       double xmean = 0;
  145.       double lower = 0;
  146.       double upper = 10;
  147.       Matrix covariance = new Matrix(2, 2);
  148.       covariance.setElement(0, 0, 2);
  149.       covariance.setElement(0, 1, -3);
  150.       covariance.setElement(1, 0, -4);
  151.       covariance.setElement(1, 1, 5);
  152.       if (argv.length > 0) {
  153. covariance.setElement(0, 0, Double.valueOf(argv[0]).doubleValue());
  154.       }
  155.       if (argv.length > 1) {
  156. covariance.setElement(0, 1, Double.valueOf(argv[1]).doubleValue());
  157.       }
  158.       if (argv.length > 2) {
  159. covariance.setElement(1, 0, Double.valueOf(argv[2]).doubleValue());
  160.       }
  161.       if (argv.length > 3) {
  162. covariance.setElement(1, 1, Double.valueOf(argv[3]).doubleValue());
  163.       }
  164.       if (argv.length > 4) {
  165. delta = Double.valueOf(argv[4]).doubleValue();
  166.       }
  167.       if (argv.length > 5) {
  168. xmean = Double.valueOf(argv[5]).doubleValue();
  169.       }
  170.       
  171.       MahalanobisEstimator newEst = new MahalanobisEstimator(covariance,
  172.      delta, xmean);
  173.       if (argv.length > 6) {
  174. lower = Double.valueOf(argv[6]).doubleValue();
  175. if (argv.length > 7) {
  176.   upper = Double.valueOf(argv[7]).doubleValue();
  177. }
  178. double increment = (upper - lower) / 50;
  179. for(double current = lower; current <= upper; current+= increment)
  180.   System.out.println(current + "  " + newEst.getProbability(current));
  181.       } else {
  182. System.out.println("Covariance Matrixn" + covariance);
  183. System.out.println(newEst);
  184.       }
  185.     } catch (Exception e) {
  186.       System.out.println(e.getMessage());
  187.     }
  188.   }
  189. }