Function.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.  *    Function.java
  18.  *    Copyright (C) 1999 Yong Wang
  19.  *
  20.  */
  21. package weka.classifiers.m5;
  22. import java.io.*;
  23. import java.util.*;
  24. import weka.core.*;
  25. /**
  26.  * Class for handling a linear function.
  27.  * @author Yong Wang (yongwang@cs.waikato.ac.nz)
  28.  * @version $Revision: 1.4 $
  29.  */
  30. public final class Function implements Serializable {
  31.   int terms[];
  32.   double coeffs[];
  33.   /**
  34.    * Constructs a function of constant value
  35.    */
  36.   public Function() {
  37.     terms = new int[1];
  38.     terms[0] = 0;
  39.     coeffs = new double[1];
  40.     coeffs[0] = 0.0;
  41.   }
  42.   /**
  43.    * Constucts a function with all attributes except the class in the inst
  44.    * @param inst instances 
  45.    */
  46.   public Function(Instances inst) {
  47.     
  48.     int i,count=0;
  49.     
  50.     terms = new int[inst.numAttributes()];
  51.     for(i=0;i<inst.numAttributes()-1;i++)
  52.       if(i != inst.classIndex()) terms[++count]=i;
  53.     terms[0] = count;
  54.     coeffs = new double[count+1];
  55.   }
  56.   /**
  57.    * Constructs a function with one attribute 
  58.    * @param attr an attribute
  59.    */
  60.   public Function(int attr) {
  61.     terms = new int[2];
  62.     terms[0] = 1;
  63.     terms[1] = attr;
  64.     coeffs = new double[2];
  65.     coeffs[0] = 0.0;
  66.     coeffs[1] = 0.0;
  67.   }
  68.   
  69.   /**
  70.    * Makes a copy of a function
  71.    * @return the copy of the function
  72.    */
  73.   public final Function  copy() {
  74.     Function fcopy = new Function();
  75.     
  76.     fcopy.terms = Ivector.copy(terms,terms[0]+1);
  77.     fcopy.coeffs = Dvector.copy(coeffs,terms[0]+1);
  78.     return fcopy;
  79.   }
  80.   /**
  81.    * Converts a function to a string
  82.    * @param inst instances 
  83.    * @param startPoint the starting point on the screen; used to feed line before reaching beyond 80 characters
  84.    * @return the converted string
  85.    * @exception Exception if something goes wrong
  86.    */ 
  87.   public final String  toString(Instances inst,int startPoint) throws Exception {
  88.     
  89.     int i,j,count1,count,precision=3;
  90.     String string;
  91.     StringBuffer text = new StringBuffer();
  92.     count1 = count = startPoint + inst.classAttribute().name().length() + 3;   
  93.     string = M5Utils.doubleToStringG(coeffs[0],1,precision);
  94.     if(coeffs[0]>=0.0)count += string.length();
  95.     else count += 1 + string.length();
  96.     text.append(inst.classAttribute().name() + " = " + string);
  97.     for(i=1;i<=terms[0];i++){
  98.       string = M5Utils.doubleToStringG(Math.abs(coeffs[i]),1,precision);
  99.       count += 3 + string.length() + inst.attribute(terms[i]).name().length();
  100.       if(count>80){
  101. text.append("n");
  102. for(j=1;j<=count1-1;j++)text.append(" ");
  103. count = count1-1 + 3 + string.length() + inst.attribute(terms[i]).name().length();
  104.       }
  105.       if(coeffs[i] >= 0.0)text.append(" + "); else text.append(" - ");
  106.       text.append(string + inst.attribute(terms[i]).name());
  107.     }
  108.     
  109.     return text.toString();
  110.   }
  111.   /**
  112.    * Constructs a new function of which the variable list is a combination of those of two functions
  113.    * @param f1 function 1
  114.    * @param f2 function 2
  115.    * @return the newly constructed function
  116.    */
  117.   public final static Function  combine(Function f1,Function f2) {
  118.     Function f= new Function();
  119.     
  120.     f.terms = Ivector.combine(f1.terms,f2.terms);
  121.     f.coeffs = new double[f.terms[0]+1];
  122.     return f;
  123.   }
  124.   /**
  125.    * Evaluates a function 
  126.    * @param inst instances 
  127.    * @return the evaluation results
  128.    * @exception Exception if something goes wrong
  129.    */
  130.   public final Errors  errors(Instances inst) throws Exception {
  131.     int i;
  132.     double tmp;
  133.     Errors e = new Errors(0,inst.numInstances()-1);
  134.     for(i=0;i<=inst.numInstances()-1;i++){
  135.       tmp = this.predict(inst.instance(i)) - inst.instance(i).classValue();
  136.       e.sumErr += tmp;
  137.       e.sumAbsErr += Math.abs(tmp);
  138.       e.sumSqrErr += tmp * tmp;
  139.     }
  140.   
  141.     e.meanAbsErr = e.sumAbsErr / e.numInstances;
  142.     e.meanSqrErr = (e.sumSqrErr - e.sumErr * e.sumErr / e.numInstances)/e.numInstances;
  143.     e.meanSqrErr = Math.abs(e.meanSqrErr);
  144.     e.rootMeanSqrErr = Math.sqrt(e.meanSqrErr);
  145.     
  146.     return e;
  147.   }
  148.   /**
  149.    * Returns the predicted value of instance i by a function
  150.    * @param i instance i
  151.    * @param inst instances 
  152.    * @return the predicted value
  153.    */
  154.   public final double  predict(Instance instance){
  155.     int j;
  156.     double y;
  157.     
  158.     y = coeffs[0];
  159.     for(j=1;j<=terms[0];j++){
  160.       y += coeffs[j] * instance.value(terms[j]);
  161.     }
  162.     return y;
  163.   }
  164.   
  165.   /**
  166.    * Detects the most insignificant variable in the funcion 
  167.    * @param sdy the standard deviation of the class variable
  168.    * @param inst instances 
  169.    * @return the index of the most insignificant variable in the function
  170.    */
  171.   public final int  insignificant(double sdy,Instances inst)
  172.   {
  173.     int j,jmin=-1,jmax=-1;
  174.     double min=2.0,max=2.5,sdx,contribution;
  175.     
  176.     for(j=1;j<=terms[0];j++){
  177.       sdx=M5Utils.stdDev(terms[j],inst);
  178.       if(sdy==0.0)contribution = 0.0;
  179.       else contribution = Math.abs(coeffs[j] * sdx / sdy);
  180.       if(contribution <  min){
  181. min=contribution;jmin=j;
  182.       }
  183.       if(contribution > max){
  184. max=contribution;jmax=j;
  185.       }
  186.     }
  187.     if(max>2.5)jmin=jmax; 
  188.     
  189.     return jmin;
  190.   }
  191.   
  192.   /**
  193.    * Removes a term from the function 
  194.    * @param j the j-th index in the variable list in the function
  195.    * @return the new function with the term removed
  196.    */
  197.   public final Function  remove(int j) {
  198.     int i;
  199.     Function f = new Function();
  200.   
  201.     f.terms = new int[terms[0]];
  202.     f.terms[0] = terms[0]-1;
  203.     for(i=1;i<j;i++)f.terms[i] = terms[i];
  204.     for(i=j;i<=terms[0]-1;i++){
  205.       f.terms[i] = terms[i+1];
  206.     }
  207.     f.coeffs = new double[f.terms[0]+1];
  208.    
  209.     return f;
  210.   }
  211.   
  212. }