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/*
022 * @(#)NormalizingKernel.java      0.1 00/01/20
023 *
024 * By Thomas Down <td2@sanger.ac.uk>
025 */
026
027package org.biojava.stats.svm;
028
029/**
030 * Performs a normalization on the results of a nested kernel.
031 * <p>
032 * This is equivalent to making the locations in feature space of the nested
033 * kernel unit vectors lying on a unit sphere. The dot product in feature space
034 * then becomes just <code>cos theta</code> rather than
035 * <code>||a|| * ||b|| * cos theta</code> as both lengths are 1. The length of
036 * a in the feature space of kernel k is <code>sqrt( k(a, a) )</code>, so that
037 * the normalizing kernel ends up calculating
038 * <code>k(a, b) / sqrt( k(a, a) * k(b, b) )</code>.
039 * <p>
040 * As the values of k(x, x) are required repeatedly, it may be worth making the
041 * nested kernel a DiagonalCachingKernel.
042 *
043 * @author Thomas Down
044 * @author Matthew Pocock
045 */
046public class NormalizingKernel extends NestedKernel {
047  public NormalizingKernel() {}
048  
049  public NormalizingKernel(SVMKernel k) {
050    setNestedKernel(k);
051  }
052  
053    public double evaluate(Object a, Object b) {
054      SVMKernel k = getNestedKernel();
055      double kAA = k.evaluate(a, a);
056      double kBB = k.evaluate(b, b);
057      double kAB = k.evaluate(a, b);
058      return kAB / Math.sqrt(kAA * kBB);
059    }
060    
061    public String toString() {
062      return "Normalizing Kernel K(x, y | k) = " +
063             " k(x, y) / sqrt(k(x, x) * k(y, y)); k(x,y) = " +
064             getNestedKernel().toString();
065    }
066}