001/*
002 *                    BioJava development code
003 *
004 * This code may be freely distributed and modified under the
005 * terms of the GNU Lesser General Public Licence.  This should
006 * be distributed with the code.  If you do not have a copy,
007 * see:
008 *
009 *      http://www.gnu.org/copyleft/lesser.html
010 *
011 * Copyright for this code is held jointly by the individual
012 * authors.  These should be listed in @author doc comments.
013 *
014 * For more information on the BioJava project and its aims,
015 * or to join the biojava-l mailing list, visit the home page
016 * at:
017 *
018 *      http://www.biojava.org/
019 *
020 */
021
022package org.biojava.stats.svm;
023
024import java.util.NoSuchElementException;
025
026/**
027 *
028 * @author Matthew Pocock
029 * @author Thomas Down
030 */
031
032public class SVMRegressionModel {
033  private SVMKernel kernel;
034  private double threshold;
035
036  private double[][] kvals;
037
038  private Object[] vectors;
039  private double[] alphas;
040  private double[] alphaStars;
041  private int size;
042
043  public SVMRegressionModel() {
044    this(100);
045  }
046
047  public SVMRegressionModel(int capacity) {
048    vectors    = new Object[capacity];
049    alphas     = new double[capacity];
050    alphaStars = new double[capacity];
051    size = 0;
052  }
053
054  public SVMKernel getKernel() {
055    return kernel;
056  }
057
058  public void setKernel(SVMKernel k) {
059    kernel = k;
060  }
061
062  public double getThreshold() {
063    return threshold;
064  }
065
066  public void setThreshold(double t) {
067    threshold = t;
068  }
069
070  public void addVector(Object v, double alpha, double alphaStar) {
071    if ((size + 1) >= vectors.length) {
072            Object [] nVectors = new Object[vectors.length * 2];
073            System.arraycopy(vectors, 0, nVectors, 0, size);
074            vectors = nVectors;
075            double [] nAlphas = new double[alphas.length * 2];
076            System.arraycopy(alphas, 0, nAlphas, 0, size);
077            alphas = nAlphas;
078      double [] nAlphaStars = new double[alphaStars.length * 2];
079      System.arraycopy(alphaStars, 0, nAlphaStars, 0, size);
080    }
081
082    vectors[size] = v;
083    alphas[size] = alpha;
084    alphaStars[size] = alphaStar;
085    size++;
086  }
087
088  public void addVector(Object v) {
089    addVector(v, 0.0, 0.0);
090  }
091
092  public int size() {
093    return size;
094  }
095
096  public Object getVector(int pos) {
097    if (pos >= size) {
098      throw new NoSuchElementException();
099    }
100    return vectors[pos];
101  }
102
103  public double getAlpha(int pos) {
104    if (pos >= size) {
105      throw new NoSuchElementException();
106    }
107    System.out.println("retrieving alpha " + pos + "=" + alphas[pos]);
108    return alphas[pos];
109  }
110
111  public void setAlpha(int pos, double a) {
112    if (pos >= size) {
113            throw new NoSuchElementException();
114    }
115    alphas[pos] = a;
116    System.out.println("setting alpha " + pos + "=" + alphas[pos]);
117  }
118
119  public double getAlphaStar(int pos) {
120    if (pos >= size) {
121      throw new NoSuchElementException();
122    }
123    System.out.println("retrieving alpha* " + pos + "=" + alphaStars[pos]);
124    return alphaStars[pos];
125  }
126
127  public void setAlphaStar(int pos, double a) {
128    if (pos >= size) {
129            throw new NoSuchElementException();
130    }
131    alphaStars[pos] = a;
132    System.out.println("setting alpha* " + pos + "=" + alphaStars[pos]);
133  }
134
135  public double classify(Object v) {
136    double delta=0;
137    for (int i = 0; i < size; ++i) {
138      double a = alphas[i] - alphaStars[i];
139            if (a != 0) {
140        delta += a * kernel.evaluate(vectors[i], v);
141      }
142    }
143    return delta + threshold;
144  }
145
146  public double internalClassify(int obj) {
147    double delta=0;
148    for (int i = 0; i < size; ++i) {
149      double a = alphas[i] - alphaStars[i];
150            delta += a * kvals[i][obj];
151    }
152    return delta + threshold;
153  }
154
155  public void calcKernel() {
156    kvals = new double[size][size];
157
158    for(int i = 0; i < size; i++) {
159      for(int j = 0; j < i; j++) {
160        kvals[i][j] = kvals[j][i] = kernel.evaluate(vectors[i], vectors[j]);
161      }
162      kvals[i][i] = kernel.evaluate(vectors[i], vectors[i]);
163      System.out.print(".");
164    }
165  }
166
167  public double getKernelValue(int i, int j) {
168    return kvals[i][j];
169  }
170}