001 package edu.nrao.sss.math; 002 003 004 /** 005 * A collection of numbers that can act like a map or a lookup table. 006 * This collection can be a discrete set of numbers, or a continuum stretching 007 * from a minimum to maximum number. 008 * <p> 009 * <b><u>Example Usage:</u></b><br/> 010 * Assume that you have an instrument that has a number of power levels, but 011 * that these levels must be an integral power of two. The lowest level is 012 * 1 unit and the highest is 1,024 units. Clients of this instrument would like 013 * to set the power level to any arbitrary non-negative number. Your instrument 014 * takes a request for a power level and returns the greatest power that it 015 * can provide that is not greater than the request. This is how you would 016 * implement such logic:</p> 017 * <pre> 018 * private int powerLevel = 0; 019 * ... 020 * private NumberSet validPowerLevels = 021 * NumberSet.factory.makeDiscreteSetMultiplicative( 022 * 1, 1024, 2, NumberSet.LookupMethod.LARGEST_LESS_THAN_OR_EQUAL); 023 * ... 024 * public Number setPowerLevel(Number newLevel) 025 * { 026 * //The actual level must be an integral power of two, 027 * //while the requested new level could be any number. 028 * 029 * Number actualLevel = validPowerLevels.getBestMatchFor(newLevel); 030 * 031 * if (actualLevel != null) 032 * powerLevel = actualLevel.intValue(); 033 * else 034 * powerLevel = 0; 035 * 036 * return powerLevel; 037 * } 038 * </pre> 039 * <p> 040 * <b>Version Info:</b> 041 * <table style="margin-left:2em"> 042 * <tr><td>$Revision: 558 $</td></tr> 043 * <tr><td>$Date: 2007-04-24 16:46:41 -0600 (Tue, 24 Apr 2007) $</td></tr> 044 * <tr><td>$Author: dharland $</td></tr> 045 * </table></p> 046 * 047 * @author David M. Harland 048 * @since 2007-03-01 049 */ 050 public interface NumberSet 051 { 052 /** 053 * Returns the number in this set that is the best match for 054 * {@code myNumber}. The returned number depends on the type 055 * of this set (continuous vs. discrete), the minimum and maximum 056 * values held by this set, and the {@code LookupMethod} used for 057 * finding a match. 058 * 059 * @param myNumber a number for which a best match is desired. 060 * 061 * @return the best match for {@code myNumber}, or <i>null</i> 062 * if there is no best match. A value of <i>null</i> is 063 * returned if: 064 * <ol> 065 * <li>The <tt>LookupMethod</tt> is <tt>EQUAL</tt> and 066 * <tt>myNumber</tt> is above the maximum or below 067 * the minimum.</li> 068 * <li>The <tt>LookupMethod</tt> is <tt>EQUAL</tt>, this 069 * set is discrete, <tt>myNumber</tt> is within the 070 * minimum and maximum bounds, but is not one of the 071 * discrete values held by this set.</li> 072 * <li>The <tt>LookupMethod</tt> is 073 * <tt>LARGEST_LESS_THAN_OR_EQUAL</tt> and 074 * <tt>myNumber</tt> is below the minimum.</li> 075 * <li>The <tt>LookupMethod</tt> is 076 * <tt>SMALLEST_GREATER_THAN_OR_EQUAL</tt> and 077 * <tt>myNumber</tt> is above the maximum.</li> 078 * </ol> 079 */ 080 public Number getBestMatchFor(Number myNumber); 081 082 //public Number getMinimum(); 083 084 //public Number getMaximum(); 085 086 //public boolean isContinuous(); 087 088 089 /** 090 * Returns a {@link NumberSetFactory factory} that produces number sets. 091 */ 092 public static final NumberSetFactory factory = NumberSetFactory.instance; 093 094 095 /** 096 * A set of instructions for number sets that helps the sets find values. 097 */ 098 public static enum LookupMethod 099 { 100 /** 101 * Tells a number set to return a value equal to the one given to 102 * {@link NumberSet#getBestMatchFor(Number)}. That method will return 103 * either the given number, or <i>null</i> if the given number is 104 * not in the set. 105 */ 106 EQUAL, 107 108 /** 109 * Tells a number set to return the largest value that is less than or 110 * equal to the one given to {@link NumberSet#getBestMatchFor(Number)}. 111 */ 112 LARGEST_LESS_THAN_OR_EQUAL, 113 114 /** 115 * Tells a number set to return the smallest value that is greater than or 116 * equal to the one given to {@link NumberSet#getBestMatchFor(Number)}. 117 */ 118 SMALLEST_GREATER_THAN_OR_EQUAL; 119 } 120 }