AlgVector.java
Upload User: rhdiban
Upload Date: 2013-08-09
Package Size: 15085k
Code Size: 9k
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.  *    AlgVector.java
  18.  *    Copyright (C) 2002 University of Waikato
  19.  *
  20.  */
  21. package weka.clusterers;
  22. import weka.core.*;
  23. import java.util.Random;
  24. //import java.io.Writer;
  25. //import java.io.Reader;
  26. //import java.io.LineNumberReader;
  27. import java.io.Serializable;
  28. //import java.util.StringTokenizer;
  29. /**
  30.  * Class for performing operations on an algebraic vector
  31.  * of floating-point values.
  32.  *
  33.  * @author Gabi Schmidberger (gabi@cs.waikato.ac.nz)
  34.  * @version $Revision: 1.1 $
  35.  */
  36. public class AlgVector implements Cloneable, Serializable {
  37.   /**
  38.    * The values of the matrix */
  39.   protected double [] m_Elements;
  40.   /**
  41.    * Constructs a vector and initializes it with default values.
  42.    *
  43.    * @param n the number of elements
  44.    */
  45.   public AlgVector(int n) {
  46.     m_Elements = new double[n];
  47.     initialize();
  48.   }
  49.  /**
  50.    * Constructs a vector using a given array.
  51.    *
  52.    * @param array the values of the matrix
  53.    */
  54.   public AlgVector(double[] array) throws Exception {
  55.     
  56.     m_Elements = new double[array.length];
  57.     for (int i = 0; i < array.length; i++) {
  58.       m_Elements[i] = array[i];
  59.     }
  60.   }
  61.   /**
  62.    * Constructs a vector using a given data format.
  63.    * The vector has an element for each numerical attribute.
  64.    * The other attributes (nominal, string) are ignored.
  65.    * Random is used to initialize the attributes.
  66.    *
  67.    * @param array the values of the matrix
  68.    */
  69.   public AlgVector(Instances format, Random random) throws Exception {
  70.     
  71.     int len = format.numAttributes();
  72.     for (int i = 0; i < format.numAttributes(); i++) {
  73.       if (!format.attribute(i).isNumeric()) len--;
  74.     }
  75.     if (len > 0) {
  76.       m_Elements = new double[len];
  77.       initialize(random);
  78.     }
  79.   }
  80.   /**
  81.    * Constructs a vector using an instance.
  82.    * The vector has an element for each numerical attribute.
  83.    * The other attributes (nominal, string) are ignored.
  84.    *
  85.    * @param instance with numeric attributes, that AlgVector gets build from
  86.    * @exception if instance doesn't have access to the data format
  87.    */
  88.   public AlgVector(Instance instance) throws Exception {
  89.     
  90.     int len = instance.numAttributes();
  91.     for (int i = 0; i < instance.numAttributes(); i++) {
  92.       if (!instance.attribute(i).isNumeric()) len--;
  93.     }
  94.     if (len > 0) {
  95.       m_Elements = new double[len];
  96.       for (int i = 0; i < len; i++) {
  97. m_Elements[i] = instance.valueSparse(i);
  98.       }
  99.     }
  100.   }
  101.   /**
  102.    * Creates and returns a clone of this object.
  103.    *
  104.    * @return a clone of this instance.
  105.    * @exception CloneNotSupportedException if an error occurs
  106.    *
  107.   public Object clone() throws CloneNotSupportedException {
  108.     Matrix m = (Matrix)super.clone();
  109.     m.m_Elements = new double[numRows()][numColumns()];
  110.     for (int r = 0; r < numRows(); r++) {
  111.       for (int c = 0; c < numColumns(); c++) {
  112.         m.m_Elements[r][c] = m_Elements[r][c];
  113.       }
  114.     }
  115.     return m;
  116.   }
  117.   /**
  118.    * Writes out a matrix.
  119.    *
  120.    * @param w the output Writer
  121.    * @exception Exception if an error occurs
  122.    *
  123.   public void write(Writer w) throws Exception {
  124.     w.write("% RowstColumnsn");
  125.     w.write("" + numRows() + "t" + numColumns() + "n");
  126.     w.write("% Matrix elementsn");
  127.     for(int i = 0; i < numRows(); i++) {
  128.       for(int j = 0; j < numColumns(); j++) {
  129. w.write("" + m_Elements[i][j] + "t");
  130.       }
  131.       w.write("n");
  132.     }
  133.     w.flush();
  134.   }
  135.   /**
  136.    * Resets the elements to the default value which is 0.0.
  137.    */
  138.   protected void initialize() {
  139.     for (int i = 0; i < m_Elements.length; i++) {
  140.       m_Elements[i] = 0.0;
  141.     }
  142.   }
  143.   /**
  144.    * Resets the elements to the default value which is 0.0.
  145.    */
  146.   protected void initialize(Random random) {
  147.     for (int i = 0; i < m_Elements.length; i++) {
  148.       m_Elements[i] = random.nextDouble();
  149.     }
  150.   }
  151.   /**
  152.    * Returns the value of a cell in the matrix.
  153.    *
  154.    * @param index the row's index
  155.    * @return the value of the cell of the vector
  156.    */
  157.   public final double getElement(int index) {
  158.     
  159.     return m_Elements[index];
  160.   }
  161.   /**
  162.    * Returns the number of elements in the vector.
  163.    *
  164.    * @return the number of rows
  165.    */
  166.   public final int numElements() {
  167.   
  168.     return m_Elements.length;
  169.   }
  170.   /**
  171.    * Sets an element of the matrix to the given value.
  172.    *
  173.    * @param index the elements index
  174.    * @param value the new value
  175.    */
  176.   public final void setElement(int index, double value) {
  177.     
  178.     m_Elements[index] = value;
  179.   }
  180.   /**
  181.    * Sets the elements of the vector to values of the given array.
  182.    * Performs a deep copy.
  183.    *
  184.    * @param elements an array of doubles
  185.    */
  186.   public final void setElements(double[] elements) {
  187.     for (int i = 0; i < elements.length; i++) {
  188.       m_Elements[i] = elements[i];
  189.     }
  190.   }
  191.   
  192.   /**
  193.    * Gets the elements of the vector and returns them as double array.
  194.    *
  195.    * @return an array of doubles
  196.    */
  197.   public double[] getElements(int index) {
  198.     double [] elements = new double[this.numElements()];
  199.     for (int i = 0; i < elements.length; i++) {
  200.       elements[i] = m_Elements[i];
  201.     }
  202.     return elements;
  203.   }
  204.   /**
  205.    * Gets the elements of the vector as an instance.
  206.    *
  207.    * !! NON-numeric data is ignored sofar
  208.    * @return an array of doubles
  209.    * @exception if length of vector is not number of numerical attributes
  210.    */
  211.   public Instance getAsInstance(Instances model) 
  212.     throws Exception {
  213.     Instance newInst = new Instance(model.numAttributes());
  214.     newInst.setDataset(model);
  215.     for (int i = 0, j = 0; i < model.numAttributes(); i++) {
  216.       if (model.attribute(i).isNumeric()) {
  217. if (j >= m_Elements.length)
  218.   throw new Exception("Datatypes are not compatible."); 
  219. newInst.setValue(i, m_Elements[j++]);
  220.       }
  221.       if (model.attribute(i).isNominal()) {
  222. newInst.setValue(i, 0);
  223.       }
  224.     }
  225.     return newInst;
  226.   }
  227.   /** 
  228.    * Converts a vector to a string
  229.    *
  230.    * @return the converted string
  231.    */
  232.   public String toString() {
  233.     StringBuffer text = new StringBuffer();
  234.     for (int i = 0; i < m_Elements.length; i++) {
  235.       if (i > 0) text.append(",");
  236.       text.append(Utils.doubleToString(m_Elements[i],6));
  237.     }
  238.     text.append("n");
  239.     return text.toString();
  240.   }
  241.     
  242.   /**
  243.    * Returns the sum of this vector with another.
  244.    *
  245.    * @return a vector containing the sum.
  246.    */
  247.   public final AlgVector add(AlgVector other) {
  248.   
  249.     int n = m_Elements.length;
  250.     AlgVector b;
  251.     try {
  252.       b = (AlgVector)clone();
  253.     } catch (CloneNotSupportedException ex) {
  254.       b = new AlgVector(n);
  255.     }
  256.     
  257.     for(int i = 0; i < n; i++) {
  258.       b.m_Elements[i] = m_Elements[i] + other.m_Elements[i];
  259.     }
  260.     
  261.     return b;
  262.   }
  263.   /**
  264.    * Returns the difference of this vector minus another.
  265.    *
  266.    * @return a vector containing the difference vector.
  267.    */
  268.   public final AlgVector substract(AlgVector other) {
  269.   
  270.     int n = m_Elements.length;
  271.     AlgVector b;
  272.     try {
  273.       b = (AlgVector)clone();
  274.     } catch (CloneNotSupportedException ex) {
  275.       b = new AlgVector(n);
  276.     }
  277.     
  278.     for(int i = 0; i < n; i++) {
  279.       b.m_Elements[i] = m_Elements[i] - other.m_Elements[i];
  280.     }
  281.     
  282.     return b;
  283.   }
  284.   
  285.  
  286.   /**
  287.    * Returns the inner (or dot) product of two vectors
  288.    *
  289.    * @param b the multiplication matrix
  290.    * @return the double representing the dot product
  291.    */
  292.   public final double dotMultiply(AlgVector b) {
  293.    
  294.     int n = m_Elements.length;
  295.     int bn = b.m_Elements.length;
  296.     double sum = 0.0;
  297.     for(int i = 0; i < n; i++) {
  298.       sum += m_Elements[i] * b.m_Elements[i];
  299.     }
  300.     
  301.     return sum;
  302.   }
  303.   /**
  304.    * Computes the scalar product of this vector with a scalar
  305.    *
  306.    * @param s the scalar
  307.    */
  308.   public final void scalarMultiply(double s) {
  309.    
  310.     int n = m_Elements.length;
  311.     for(int i = 0; i < n; i++) {
  312.       m_Elements[i] = s * m_Elements[i];
  313.     }
  314.   }
  315.   /**
  316.    * Changes the length of a vector.
  317.    *
  318.    * @param the new length of the vector
  319.    * @return the norm of the vector
  320.    */
  321.   public void changeLength(double len) {
  322.    
  323.     double factor = this.norm();
  324.     factor = len / factor;
  325.     scalarMultiply(factor);
  326.   }
  327.   /**
  328.    * Returns the norm of the vector
  329.    *
  330.    * @return the norm of the vector
  331.    */
  332.   public double norm() {
  333.    
  334.     int n = m_Elements.length;
  335.     double sum = 0.0;
  336.     
  337.     for(int i = 0; i < n; i++) {
  338.       sum += m_Elements[i] * m_Elements[i];
  339.     }
  340.     return Math.pow(sum, 0.5);
  341.   }
  342.   /**
  343.    * Norms this vector to length 1.0
  344.    *
  345.    */
  346.   public final void normVector() {
  347.    
  348.     double len = this.norm();
  349.     this.scalarMultiply(1 / len);
  350.   }
  351.   /**
  352.    * Main method for testing this class.
  353.    */
  354.   public static void main(String[] ops) {
  355.   
  356.     double[] first = {2.3, 1.2, 5.0};
  357.     
  358.     try {
  359.       AlgVector test = new AlgVector(first);
  360.       System.out.println("test:n " + test);
  361.      
  362.     } catch (Exception e) {
  363.       e.printStackTrace();
  364.     }
  365.   }
  366. }