001/** A class defining quantization to a FixPoint number. 002 003 Copyright (c) 2002-2014 The Regents of the University of California. 004 All rights reserved. 005 Permission is hereby granted, without written agreement and without 006 license or royalty fees, to use, copy, modify, and distribute this 007 software and its documentation for any purpose, provided that the above 008 copyright notice and the following two paragraphs appear in all copies 009 of this software. 010 011 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 012 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 013 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 014 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 015 SUCH DAMAGE. 016 017 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 018 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 019 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 020 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 021 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 022 ENHANCEMENTS, OR MODIFICATIONS. 023 024 PT_COPYRIGHT_VERSION_2 025 COPYRIGHTENDKEY 026 027 028 */ 029package ptolemy.math; 030 031import java.math.BigInteger; 032 033/** 034 The Quantization class defines the mapping of numeric values with unlimited 035 precision to finite precision. 036 <p> 037 It comprises a 038 <ul> 039 <li> 040 <i>precision</i>: to define the accuracy of the finite precision numbers. 041 <li> 042 <b>Overflow</b>: to define the treatment of out-of-range numbers. 043 <li> 044 <b>Rounding</b>: to define the loss of precision for in-range numbers. 045 </ul> 046 The way in which <i>precision</i> is realised is a sub-class 047 responsibility. The standard fixed point binary functionality using a 048 Precision is provided by FixPointQuantization. 049 <p> 050 This abstract class is designed to support specification of required 051 numeric behavior through use of the yet-to-be-written FloatingQuantization 052 and FixedQuantization classes. Knowledge of the required numeric behavior, 053 rather than precise specification of an exact implementation, provides an 054 opportunity for code generation to select appropriate types supported by a 055 target architecture. 056 <p> 057 FixedQuantization provides for <i>modulo</i> equi-spaced values between 058 the inclusive <i>maximum</i> and <i>minimum</i> limits. <i>epsilon</i>, 059 the separation between values is given by 060 <i>(maximum - minimum) / (modulo - 1)</i>. Whether values beyond the 061 <i>maximum</i> and <i>minimum</i> wrap-around is determined by the overflow 062 strategy. FixedQuantization therefore describes the requirements of a 063 single fixed point range comprising just a mantissa. 064 <p> 065 FloatingQuantization adds an exponent to support multiple 066 floating point ranges; <i>maximum</i> defines the upper limit of the 067 coarsest scale and <i>tiny</i> defines the smallest representable non-zero 068 number on the finest scale. (<i>tiny</i> is the same as <i>epsilon</i> for 069 FixedQuantization.) 070 <p> 071 If <i>exactRounding</i> is specified, code generation must ensure that 072 arithmetic rounds to the specified <i>epsilon</i>. Otherwise, the code 073 generator may use arithmetic with higher precision. 074 <p> 075 If <i>exactOverflow</i> is specified, code generation must ensure that 076 arithmetic overflows saturate or wrap-around at the specified 077 <i>maximum</i> and <i>minimum</i>. Otherwise, the code generator may use 078 arithmetic with greater range. 079 <p> 080 The active class functionality is provided by the quantize method, which 081 is normally invoked from FixPoint.quantize or ScalarToken.quantize 082 to enforce quantization constraints upon the result of an unconstrained 083 computation. 084 <p> 085 An instance of the class is immutable, meaning 086 that its value is set in the constructor and cannot then be modified. 087 088 @author Ed Willink 089 @version $Id$ 090 @since Ptolemy II 2.1 091 @Pt.ProposedRating Red (Ed.Willink) 092 @Pt.AcceptedRating Red 093 @see ptolemy.math.FixPoint 094 @see ptolemy.math.FixPointQuantization 095 @see ptolemy.math.Precision 096 @see ptolemy.math.Overflow 097 @see ptolemy.math.Rounding 098 */ 099public abstract class Quantization implements Cloneable { 100 /** Construct a Quantization with the given precision, overflow 101 * strategy, and rounding strategy. 102 * 103 * @param overflow The Overflow object to use by this Quantization 104 * strategy. 105 * @param rounding The Rounding object to use by this Quantization 106 * strategy. 107 */ 108 public Quantization(Overflow overflow, Rounding rounding) { 109 _overflow = overflow; 110 _rounding = rounding; 111 } 112 113 /////////////////////////////////////////////////////////////////// 114 //// public methods //// 115 116 /** Return this, that is, return the reference to this object. 117 * @return This Quantization. 118 */ 119 @Override 120 public Object clone() { 121 return this; 122 } 123 124 /** Return true if the indicated object describes the same 125 * mapping to quantized values. 126 * 127 * @param object The Quantization object to use for equality 128 * checking. 129 * @return True if the quantizations are equal. 130 */ 131 @Override 132 public boolean equals(Object object) { 133 if (object instanceof Quantization) { 134 Quantization other = (Quantization) object; 135 136 if (_overflow.equals(other._overflow) 137 && _rounding.equals(other._rounding)) { 138 return true; 139 } 140 } 141 142 return false; 143 } 144 145 /** Return the separation between quantized values. 146 * @return The quantization interval. 147 */ 148 public double getEpsilonValue() { 149 double maxVal = getMaximumValue(); 150 double minVal = getMinimumValue(); 151 double modVal = getNumberOfLevels(); 152 return (maxVal - minVal) / (modVal - 1.0); 153 } 154 155 /** Return the overflow bit-truth. 156 * @return True if overflow must occur at the <i>maximum</i> and 157 * <i>minimum</i> values, false if greater range is acceptable. 158 */ 159 public boolean getExactOverflow() { 160 return false; 161 } 162 163 /** Return the rounding bit-truth. 164 * @return True if rounding must occur exactly at <i>epsilon</i>, 165 * false if finer resolution is acceptable. 166 */ 167 public boolean getExactRounding() { 168 return false; 169 } 170 171 /** Return the number of bits to represent the exponent. 172 * @return The length of the exponent. 173 */ 174 public int getExponentBitLength() { 175 return 0; 176 } 177 178 /** Return the number of bits representing the fractional part 179 * of the mantissa. 180 * @return The length of the fractional part of the mantissa. 181 */ 182 public int getFractionBitLength() { 183 return getMantissaPrecision().getFractionBitLength(); 184 } 185 186 /** Return the number of bits representing the integer part 187 * of the mantissa. 188 * @return The length of the integer part of the mantissa. 189 */ 190 public int getIntegerBitLength() { 191 return getMantissaPrecision().getIntegerBitLength(); 192 } 193 194 /** Return the number of bits to represent the mantissa. 195 * @return The length of the mantissa. 196 */ 197 public int getMantissaBitLength() { 198 return getIntegerBitLength() + getFractionBitLength(); 199 } 200 201 /** Return the precision fore the mantissa of a compliant 202 * 2's complement representation. 203 * 204 * @return The precision. 205 */ 206 public abstract Precision getMantissaPrecision(); 207 208 /** Return the maximum quantizable value after scaling so that 209 * quantization levels are represented by adjacent integers. 210 * @return The maximum inclusive value. 211 */ 212 public BigInteger getMaximumUnscaledValue() { 213 int numBits = getNumberOfBits(); 214 return BigInteger.ZERO.setBit(numBits - 1).subtract(BigInteger.ONE); 215 } 216 217 /** Return the maximum quantizable value. 218 * @return The maximum inclusive value. 219 */ 220 public double getMaximumValue() { 221 double maxVal = getMaximumUnscaledValue().doubleValue(); 222 return maxVal * Math.pow(0.5, getFractionBitLength()); 223 } 224 225 /** Return the minimum quantizable value after scaling so that 226 * quantization levels are represented by adjacent integers. 227 * @return The minimum inclusive value. 228 */ 229 public BigInteger getMinimumUnscaledValue() { 230 int numBits = getNumberOfBits(); 231 return BigInteger.ZERO.setBit(numBits - 1).negate(); 232 } 233 234 /** Return the minimum quantizable value. 235 * @return The minimum inclusive value. 236 */ 237 public double getMinimumValue() { 238 double minVal = getMinimumUnscaledValue().doubleValue(); 239 return minVal * Math.pow(0.5, getFractionBitLength()); 240 } 241 242 /** Return the modulo quantization range after scaling so that 243 * quantization levels are represented by adjacent integers. 244 * This is the same as the number of quantization levels in 245 * the mantissa.. 246 * @return The modulo value. 247 * @deprecated ? 248 */ 249 @Deprecated 250 public BigInteger getModuloUnscaledValue() { 251 int numBits = getNumberOfBits(); 252 return BigInteger.ZERO.setBit(numBits); 253 } 254 255 /** Return the number of bits to represent the value. 256 * @return The number of bits. 257 */ 258 public int getNumberOfBits() { 259 return getMantissaBitLength() + getExponentBitLength(); 260 } 261 262 /** Return the number of quantization levels in the mantissa. 263 * @return The number of levels. 264 */ 265 public double getNumberOfLevels() { 266 return Math.pow(2.0, getMantissaBitLength()); 267 } 268 269 /** Return the overflow strategy. 270 * @return The overflow strategy. 271 */ 272 public Overflow getOverflow() { 273 return _overflow; 274 } 275 276 /** Return the Precision. 277 * 278 * @return The Precision object. 279 */ 280 public abstract Precision getPrecision(); 281 282 /** Return the rounding strategy. 283 * @return The rounding strategy. 284 */ 285 public Rounding getRounding() { 286 return _rounding; 287 } 288 289 /** Return the quantizable value nearest to and above zero. 290 * @return The positive value nearest to zero. 291 */ 292 public double getTinyValue() { 293 return getEpsilonValue(); 294 } 295 296 /** Return a hash code value for this Quantization. This method returns the 297 * bitwise and of the hashcode of the overflow and the hashcode of 298 * the rounding. 299 * @return A hash code value for this Quantization. 300 */ 301 @Override 302 public int hashCode() { 303 return _overflow.hashCode() & _rounding.hashCode(); 304 } 305 306 /** Return a string representing this quantization. 307 * @return A string representing this quantization. 308 */ 309 @Override 310 public abstract String toString(); 311 312 /////////////////////////////////////////////////////////////////// 313 //// private variables //// 314 315 /** The overflow strategy. */ 316 protected Overflow _overflow = Overflow.GENERAL; 317 318 /** The rounding strategy. */ 319 protected Rounding _rounding = Rounding.GENERAL; 320}