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    }