KStarCache.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 8k
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.  *    KStarCache.java
  18.  *    Copyright (c) 1995-97 by Len Trigg (trigg@cs.waikato.ac.nz).
  19.  *    Java port to Weka by Abdelaziz Mahoui (am14@cs.waikato.ac.nz).
  20.  *
  21.  */
  22. package weka.classifiers.kstar;
  23. import java.util.*;
  24. /**
  25.  * A class representing the caching system used to keep track of each attribute
  26.  * value and its corresponding scale factor or stop parameter.
  27.  *
  28.  * @author Len Trigg (len@intelligenesis.net)
  29.  * @author Abdelaziz Mahoui (am14@cs.waikato.ac.nz)
  30.  * @version $Revision 1.0 $
  31.  */
  32. public class KStarCache {
  33.   
  34.   /**
  35.    * cache table
  36.    */
  37.   CacheTable m_Cache = new CacheTable();
  38.   
  39.   /**
  40.    * Stores the specified values in the cahce table for easy retrieval.
  41.    *
  42.    * @param key attribute value used key to lookup the cache table.
  43.    * @param value cache parameter: attribute scale/stop parameter.
  44.    * @param pmiss cache parameter: transformation probability to 
  45.    * attribute with missing value.
  46.    */
  47.   public void store(double key, double value, double pmiss) {
  48.     if ( !m_Cache.containsKey(key) ) {
  49.       m_Cache.insert(key, value, pmiss);
  50.     }
  51.   }
  52.   
  53.   /**
  54.    * Checks if the specified key maps with an entry in the cache table
  55.    *
  56.    * @param key the key to map with an entry in the hashtable.
  57.    */
  58.   public boolean containsKey(double key) {
  59.     if ( m_Cache.containsKey(key) ) {
  60.       return true;
  61.     }
  62.     return false;
  63.   }
  64.   
  65.   /**
  66.    * Returns the values in the cache mapped by the specified key
  67.    *
  68.    * @param key the key used to retrieve the table entry.
  69.    */
  70.   public TableEntry getCacheValues( double key ) {
  71.     if ( m_Cache.containsKey(key) ) {
  72.       return m_Cache.getEntry(key);
  73.     }
  74.     return null;
  75.   }
  76.   /**
  77.    * A custom hashtable class to support the caching system.
  78.    *
  79.    */
  80.   public class CacheTable {
  81.     /** The hash table data. */
  82.     private transient TableEntry [] m_Table;
  83.     /** The total number of entries in the hash table. */
  84.     private transient int m_Count;
  85.     /** Rehashes the table when count exceeds this threshold. */
  86.     private int m_Threshold;
  87.     /** The load factor for the hashtable. */
  88.     private float m_LoadFactor;
  89.     /** The default size of the hashtable */
  90.     private final int DEFAULT_TABLE_SIZE = 101;
  91.     /** The default load factor for the hashtable */
  92.     private final float DEFAULT_LOAD_FACTOR = 0.75f;
  93.     //    private final float DEFAULT_LOAD_FACTOR = 0.5f;
  94.     /** Accuracy value for equality */
  95.     private final double EPSILON = 1.0E-5;
  96.     
  97.     /**
  98.      * Constructs a new hashtable with a default capacity and load factor.
  99.      */
  100.     public CacheTable(int size, float loadFactor) {
  101.       m_Table = new TableEntry[size];
  102.       m_LoadFactor = loadFactor;
  103.       m_Threshold = (int)(size * loadFactor);
  104.       m_Count = 0;
  105.     }
  106.     
  107.     /**
  108.      * Constructs a new hashtable with a default capacity and load factor.
  109.      */
  110.     public CacheTable() {
  111.       this(101, 0.75f);
  112.     }
  113.     
  114.     /**
  115.      * Tests if the specified double is a key in this hashtable.
  116.      */
  117.     public boolean containsKey(double key) {
  118.       TableEntry [] table = m_Table;
  119.       int hash = hashCode(key);
  120.       int index = (hash & 0x7FFFFFFF) % table.length;
  121.       for (TableEntry e = table[index] ; e != null ; e = e.next) {
  122. if ((e.hash == hash) && (Math.abs(e.key - key) < EPSILON)) {
  123.   return true;
  124. }
  125.       }
  126.       return false;
  127.     }
  128.     
  129.     /**
  130.      * Inserts a new entry in the hashtable using the specified key. 
  131.      * If the key already exist in the hashtable, do nothing.
  132.      */
  133.     public void insert(double key, double value, double pmiss) {
  134.       // Makes sure the key is not already in the hashtable.
  135.       TableEntry e, ne;
  136.       TableEntry [] table = m_Table;
  137.       int hash = hashCode(key);
  138.       int index = (hash & 0x7FFFFFFF) % table.length;
  139.       // start looking along the chain
  140.       for (e = table[index] ; e != null ; e = e.next) {
  141. if ((e.hash == hash) && (Math.abs(e.key - key) < EPSILON)) {
  142.   return;
  143. }
  144.       }
  145.       // At this point, key is not in table.
  146.       // Creates a new entry.
  147.       ne = new TableEntry( hash, key, value, pmiss, table[index] );
  148.       // Put entry at the head of the chain.
  149.       table[index] = ne;
  150.       m_Count++;
  151.       // Rehash the table if the threshold is exceeded
  152.       if (m_Count >= m_Threshold) {
  153. rehash();
  154.       }
  155.     }
  156.     
  157.     /**
  158.      * Returns the table entry to which the specified key is mapped in 
  159.      * this hashtable.
  160.      * @return a table entry.
  161.      */
  162.     public TableEntry getEntry(double key) {
  163.       TableEntry [] table = m_Table;
  164.       int hash = hashCode(key);
  165.       int index = (hash & 0x7FFFFFFF) % table.length;
  166.       for (TableEntry e = table[index] ; e != null ; e = e.next) {
  167. if ((e.hash == hash) && (Math.abs(e.key - key) < EPSILON)) {
  168.   return e;
  169. }
  170.       }
  171.       return null;
  172.     }
  173.     
  174.     /**
  175.      * Returns the number of keys in this hashtable.
  176.      * @return the number of keys in this hashtable.
  177.      */
  178.     public int size() {
  179.       return m_Count;
  180.     }
  181.     
  182.     /**
  183.      * Tests if this hashtable maps no keys to values.
  184.      * @return true if this hastable maps no keys to values.
  185.      */
  186.     public boolean isEmpty() {
  187.       return m_Count == 0;
  188.     }
  189.     
  190.     /**
  191.      * Clears this hashtable so that it contains no keys.
  192.      */
  193.     public void clear() {
  194.       TableEntry table[] = m_Table;
  195.       for (int index = table.length; --index >= 0; ) {
  196. table[index] = null;
  197.       }
  198.       m_Count = 0;
  199.     }
  200.     
  201.     /**
  202.      * Rehashes the contents of the hashtable into a hashtable with a 
  203.      * larger capacity. This method is called automatically when the 
  204.      * number of keys in the hashtable exceeds this hashtable's capacity 
  205.      * and load factor. 
  206.      */
  207.     private void rehash() {
  208.       int oldCapacity = m_Table.length;
  209.       TableEntry [] oldTable = m_Table;    
  210.       int newCapacity = oldCapacity * 2 + 1;
  211.       TableEntry [] newTable = new TableEntry[newCapacity];
  212.       m_Threshold = (int)(newCapacity * m_LoadFactor);
  213.       m_Table = newTable;
  214.       TableEntry e, old;
  215.       for (int i = oldCapacity ; i-- > 0 ;) {
  216. for (old = oldTable[i] ; old != null ; ) {
  217.   e = old;
  218.   old = old.next;
  219.   int index = (e.hash & 0x7FFFFFFF) % newCapacity;
  220.   e.next = newTable[index];
  221.   newTable[index] = e;
  222. }
  223.       }
  224.     }
  225.     
  226.     /**
  227.      * Returns the hash code of the specified double.
  228.      * @return the hash code of the specified double.
  229.      */
  230.     private int hashCode(double key) {
  231.       long bits = Double.doubleToLongBits(key);
  232.       return (int)(bits ^ (bits >> 32));
  233.     }
  234.   
  235.   } // CacheTable
  236.   
  237.   /**
  238.    * Hashtable collision list.
  239.    */
  240.   public class TableEntry {
  241.     /** attribute value hash code */
  242.     public int hash;
  243.     /** attribute value */
  244.     public double key;
  245.     /** scale factor or stop parameter */
  246.     public double value;
  247.     /** transformation probability to missing value */
  248.     public double pmiss;
  249.     /** next table entry (separate chaining) */
  250.     public TableEntry next = null;
  251.     /** Constructor */
  252.     public TableEntry(int hash, double key, double value, 
  253.       double pmiss, TableEntry next) {
  254.       this.hash  = hash;
  255.       this.key   = key;
  256.       this.value = value;
  257.       this.pmiss = pmiss;
  258.       this.next  = next;
  259.     }
  260.   }  // TableEntry
  261.   
  262. } // Cache