/* * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or (at * your option) any later version. * * This program is distributed in the hope that it will be useful, but * WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ /* * ChisqMixture.java * Copyright (C) 2002 University of Waikato, Hamilton, New Zealand * */ package weka.classifiers.functions.pace; import weka.core.RevisionHandler; import weka.core.RevisionUtils; import weka.core.matrix.DoubleVector; import weka.core.matrix.FlexibleDecimalFormat; import weka.core.matrix.IntVector; /** Class for handling discrete functions. <p> * * A discrete function here is one that takes non-zero values over a finite * set of points. <p> * * @author Yong Wang (yongwang@cs.waikato.ac.nz) * @version $Revision: 1.4 $ */ public class DiscreteFunction implements RevisionHandler { protected DoubleVector points; protected DoubleVector values; /** Constructs an empty discrete function */ public DiscreteFunction() { this(null, null); } /** Constructs a discrete function with the point values provides and the * function values are all 1/n. * @param p the point values */ public DiscreteFunction( DoubleVector p ) { this( p, null ); } /** Constructs a discrete function with both the point values and * function values provided. * @param p the point values * @param v the function values */ public DiscreteFunction( DoubleVector p, DoubleVector v ) { points = p; values = v; formalize(); } private DiscreteFunction formalize() { if( points == null ) points = new DoubleVector(); if( values == null ) values = new DoubleVector(); if( points.isEmpty() ) { if( ! values.isEmpty() ) throw new IllegalArgumentException("sizes not match"); } else { int n = points.size(); if( values.isEmpty() ) { values = new DoubleVector( n, 1./n ); } else { if( values.size() != n ) throw new IllegalArgumentException("sizes not match"); } } return this; } /** * Normalizes the function values with L1-norm. */ public DiscreteFunction normalize() { if ( ! values.isEmpty() ) { double s = values.sum(); if( s != 0.0 && s != 1.0 ) values.timesEquals( 1. / s ); } return this; } /** * Sorts the point values of the discrete function. */ public void sort() { IntVector index = points.sortWithIndex(); values = values.subvector( index ); } /** * Clones the discrete function */ public Object clone() { DiscreteFunction d = new DiscreteFunction(); d.points = (DoubleVector) points.clone(); d.values = (DoubleVector) values.clone(); return d; } /** * Makes each individual point value unique */ public DiscreteFunction unique() { int count = 0; if( size() < 2 ) return this; for(int i = 1; i <= size() - 1; i++ ) { if( points.get( count ) != points.get( i ) ) { count++; points.set( count, points.get( i ) ); values.set( count, values.get( i ) ); } else { values.set( count, values.get(count) + values.get(i) ); } } points = (DoubleVector) points.subvector(0, count); values = (DoubleVector) values.subvector(0, count); return this; } /** * Returns the size of the point set. */ public int size() { if( points == null ) return 0; return points.size(); } /** * Gets a particular point value * @param i the index */ public double getPointValue( int i ) { return points.get(i); } /** * Gets a particular function value * @param i the index */ public double getFunctionValue( int i ) { return values.get(i); } /** * Sets a particular point value * @param i the index */ public void setPointValue( int i, double p ) { points.set(i, p); } /** * Sets a particular function value * @param i the index */ public void setFunctionValue( int i, double v ) { values.set(i, v); } /** * Gets all point values */ protected DoubleVector getPointValues() { return points; } /** * Gets all function values */ protected DoubleVector getFunctionValues() { return values; } /** * Returns true if it is empty. */ public boolean isEmpty() { if( size() == 0 ) return true; return false; } // public void addPoint( double x, double y ) { // points.addPoint( x ); // values.addPoint( y ); // } /** * Returns the combined of two discrete functions * @param d the second discrete function * @return the combined discrte function */ public DiscreteFunction plus( DiscreteFunction d ) { return ((DiscreteFunction) clone()).plusEquals( d ); } /** * Returns the combined of two discrete functions. The first function is * replaced with the new one. * @param d the second discrete function * @return the combined discrte function */ public DiscreteFunction plusEquals( DiscreteFunction d ) { points = points.cat( d.points ); values = values.cat( d.values ); return this; } /** * All function values are multiplied by a double * @param x the multiplier */ public DiscreteFunction timesEquals( double x ) { values.timesEquals( x ); return this; } /** * Converts the discrete function to string. */ public String toString() { StringBuffer text = new StringBuffer(); FlexibleDecimalFormat nf1 = new FlexibleDecimalFormat( 5 ); nf1.grouping( true ); FlexibleDecimalFormat nf2 = new FlexibleDecimalFormat( 5 ); nf2.grouping( true ); for(int i = 0; i < size(); i++) { nf1.update( points.get(i) ); nf2.update( values.get(i) ); } text.append("\t" + nf1.formatString("Points") + "\t" + nf2.formatString("Values") + "\n\n"); for(int i = 0; i <= size() - 1; i++) { text.append( "\t" + nf1.format( points.get(i) ) + "\t" + nf2.format( values.get(i) ) + "\n" ); } return text.toString(); } /** * Returns the revision string. * * @return the revision */ public String getRevision() { return RevisionUtils.extract("$Revision: 1.4 $"); } public static void main( String args[] ) { double points[] = {2,1,2,3,3}; double values[] = {3,2,4,1,3}; DiscreteFunction d = new DiscreteFunction( new DoubleVector( points ), new DoubleVector( values )); System.out.println( d ); d.normalize(); System.out.println( "d (after normalize) = \n" + d ); points[1] = 10; System.out.println( "d (after setting [1]) = \n" + d); d.sort(); System.out.println( "d (after sorting) = \n" + d); d.unique(); System.out.println( "d (after unique) = \n" + d ); } }