001/** 002 * Copyright (c) 2011, The University of Southampton and the individual contributors. 003 * All rights reserved. 004 * 005 * Redistribution and use in source and binary forms, with or without modification, 006 * are permitted provided that the following conditions are met: 007 * 008 * * Redistributions of source code must retain the above copyright notice, 009 * this list of conditions and the following disclaimer. 010 * 011 * * Redistributions in binary form must reproduce the above copyright notice, 012 * this list of conditions and the following disclaimer in the documentation 013 * and/or other materials provided with the distribution. 014 * 015 * * Neither the name of the University of Southampton nor the names of its 016 * contributors may be used to endorse or promote products derived from this 017 * software without specific prior written permission. 018 * 019 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 020 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 021 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 022 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 023 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 024 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 025 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 026 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 027 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 028 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 029 */ 030package org.openimaj.ml.linear.kernel; 031 032import java.util.List; 033 034import no.uib.cipr.matrix.DenseVector; 035import no.uib.cipr.matrix.Vector; 036 037import org.openimaj.math.matrix.GramSchmidtProcess; 038import org.openimaj.util.pair.IndependentPair; 039 040/** 041 * 042 * @author Sina Samangooei (ss@ecs.soton.ac.uk) 043 */ 044public class LinearVectorKernel implements VectorKernel{ 045 046 @Override 047 public Double apply(IndependentPair<double[], double[]> in) { 048 double[] first = in.firstObject(); 049 double[] second = in.secondObject(); 050 return new DenseVector(first,false).dot(new DenseVector(second,false)); 051 } 052 053 /** 054 * On the plane 055 * @param supports 056 * @param weights 057 * @param bias 058 * @param setValues the dimentions of the point set to 0 059 * @return a point on the plane 060 */ 061 public static double[] getPlanePoint(List<double[]> supports, List<Double> weights, double bias, double ... setValues) { 062 if(supports.size() == 0) throw new RuntimeException("Can't estimate plane point without supports"); 063 064 double[] w = getDirection(supports, weights); 065 double[] x = new double[w.length]; 066 double resid = 0; 067 int index = 0; 068 for (int i = 0; i < w.length; i++) { 069 070 if(Double.isNaN(setValues[i])){ 071 index = i; 072 } else { 073 resid += (setValues[i] * w[i]); 074 x[i] = setValues[i]; 075 } 076 } 077 if(w[index] == 0) return new double[w.length]; 078 x[index] = (bias + resid)/ -w[index]; 079 return x; 080 } 081 082 /** 083 * @param supports 084 * @param weights 085 * @return the vectors defining the plane 086 */ 087 public static Vector[] getPlaneDirections(List<double[]> supports, List<Double> weights) { 088 double[] dir = getDirection(supports, weights); 089 int ind = 0; 090// for (int i = 0; i < weights.size(); i++) { 091// double[] ds = supports.get(i); 092// System.out.println("Support " + ind++ + ": " + weights.get(i) + " * " +Arrays.toString(ds) ); 093// } 094// System.out.println("Number of supports: " + supports.size() + " direction: " + Arrays.toString(dir)); 095 Vector[] all = GramSchmidtProcess.perform(dir); 096 Vector[] ret = new Vector[all.length-1]; 097 for (int i = 0; i < ret.length; i++) { 098 ret[i] = all[i+1]; 099 } 100 return ret; 101 } 102 103 104 public static double[] getDirection(List<double[]> supports, List<Double> weights) { 105 Vector ret = null; 106 for (int i = 0; i < supports.size(); i++) { 107 double[] sup = supports.get(i); 108 double weight = weights.get(i); 109 DenseVector scale = new DenseVector(sup).scale(weight); 110 if(ret == null){ 111 ret = scale; 112 } else{ 113 ret.add(scale); 114 } 115 } 116 double[] retdata = new DenseVector(ret).getData(); 117 return retdata; 118 } 119 120}