001/* 002 AUTOMATICALLY GENERATED BY jTemp FROM 003 /Users/jsh2/Work/openimaj/target/checkout/machine-learning/nearest-neighbour/src/main/jtemp/org/openimaj/lsh/sketch/#T#LSHSketcher.jtemp 004*/ 005/** 006 * Copyright (c) 2011, The University of Southampton and the individual contributors. 007 * All rights reserved. 008 * 009 * Redistribution and use in source and binary forms, with or without modification, 010 * are permitted provided that the following conditions are met: 011 * 012 * * Redistributions of source code must retain the above copyright notice, 013 * this list of conditions and the following disclaimer. 014 * 015 * * Redistributions in binary form must reproduce the above copyright notice, 016 * this list of conditions and the following disclaimer in the documentation 017 * and/or other materials provided with the distribution. 018 * 019 * * Neither the name of the University of Southampton nor the names of its 020 * contributors may be used to endorse or promote products derived from this 021 * software without specific prior written permission. 022 * 023 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND 024 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED 025 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE 026 * DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR 027 * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES 028 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; 029 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON 030 * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 031 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS 032 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 033 */ 034package org.openimaj.lsh.sketch; 035 036import java.util.ArrayList; 037import java.util.List; 038 039import org.openimaj.util.hash.HashFunction; 040import org.openimaj.util.hash.HashFunctionFactory; 041import org.openimaj.util.sketch.Sketcher; 042 043/** 044 * A {@link Sketcher} that produces bit-string sketches encoded as short arrays. 045 * Only the least-significant bit of each hash function will be appended to the 046 * final sketch. The length of the output array will be computed such that the 047 * bit from each hash function is contained. 048 * 049 * @author Jonathon Hare (jsh2@ecs.soton.ac.uk) 050 * 051 * @param <OBJECT> 052 * Type of object being sketched 053 */ 054public class ShortLSHSketcher<OBJECT> implements Sketcher<OBJECT, short[]> { 055 List<HashFunction<OBJECT>> hashFunctions; 056 057 /** 058 * Construct with the given functions. 059 * 060 * @param functions 061 * the underlying hash functions. 062 */ 063 public ShortLSHSketcher(List<HashFunction<OBJECT>> functions) { 064 this.hashFunctions = functions; 065 } 066 067 /** 068 * Construct with the given functions. 069 * 070 * @param first 071 * the first function 072 * @param remainder 073 * the remainder of the functions 074 */ 075 @SafeVarargs 076 public ShortLSHSketcher(HashFunction<OBJECT> first, HashFunction<OBJECT>... remainder) { 077 this.hashFunctions = new ArrayList<HashFunction<OBJECT>>(); 078 this.hashFunctions.add(first); 079 080 for (final HashFunction<OBJECT> r : remainder) 081 this.hashFunctions.add(r); 082 } 083 084 /** 085 * Construct with the factory which is used to produce the required number 086 * of functions. 087 * 088 * @param factory 089 * the factory to use to produce the underlying hash functions. 090 * @param nFuncs 091 * the number of functions to create for the composition 092 */ 093 public ShortLSHSketcher(HashFunctionFactory<OBJECT> factory, int nFuncs) { 094 this.hashFunctions = new ArrayList<HashFunction<OBJECT>>(); 095 096 for (int i = 0; i < nFuncs; i++) 097 hashFunctions.add(factory.create()); 098 } 099 100 @Override 101 public short[] createSketch(OBJECT input) { 102 final int nele = arrayLength(); 103 final short[] sketch = new short[nele]; 104 105 for (int i = 0, j = 0; i < nele; i++) { 106 for (int k = 0; k < Short.SIZE; k++) { 107 final int hash = hashFunctions.get(j++).computeHashCode(input); 108 109 sketch[i] = (short) (sketch[i] | ((short) hash << k)); 110 } 111 } 112 113 return sketch; 114 } 115 116 /** 117 * Get the length of the sketch in bits. 118 * 119 * @return the number of bits in the sketch 120 */ 121 public int bitLength() { 122 return hashFunctions.size(); 123 } 124 125 /** 126 * Get the length of the output short array of packed bits. 127 * 128 * @return the number of shorts that will be returned. 129 */ 130 public int arrayLength() { 131 return (int) Math.ceil((double) hashFunctions.size() / Short.SIZE); 132 } 133}