001/* A token that contains a petite number. 002 Copyright (c) 2006-2014 The Regents of the University of California. 003 All rights reserved. 004 Permission is hereby granted, without written agreement and without 005 license or royalty fees, to use, copy, modify, and distribute this 006 software and its documentation for any purpose, provided that the above 007 copyright notice and the following two paragraphs appear in all copies 008 of this software. 009 010 IN NO EVENT SHALL THE UNIVERSITY OF CALIFORNIA BE LIABLE TO ANY PARTY 011 FOR DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 012 ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF 013 THE UNIVERSITY OF CALIFORNIA HAS BEEN ADVISED OF THE POSSIBILITY OF 014 SUCH DAMAGE. 015 016 THE UNIVERSITY OF CALIFORNIA SPECIFICALLY DISCLAIMS ANY WARRANTIES, 017 INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF 018 MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE 019 PROVIDED HEREUNDER IS ON AN "AS IS" BASIS, AND THE UNIVERSITY OF 020 CALIFORNIA HAS NO OBLIGATION TO PROVIDE MAINTENANCE, SUPPORT, UPDATES, 021 ENHANCEMENTS, OR MODIFICATIONS. 022 023 PT_COPYRIGHT_VERSION_2 024 COPYRIGHTENDKEY 025 026 */ 027package ptolemy.data; 028 029import ptolemy.data.type.BaseType; 030import ptolemy.data.type.Type; 031import ptolemy.kernel.util.IllegalActionException; 032 033/////////////////////////////////////////////////////////////////// 034//// PetiteToken 035 036/** 037 A token that contains a number which is essentially a 038 simulation equivalent for fixed point numbers in embedded processors. 039 By definition it is between -1 (inclusive) and 1 (exclusive). It is 040 a extension of the Double Token and maintains the same precision as 041 Double Token. 042 @see ptolemy.data.Token 043 @author Shamik Bandyopadhyay 044 @version $Id$ 045 @since Ptolemy II 5.2 046 @Pt.ProposedRating Green (neuendor) 047 @Pt.AcceptedRating Green (cxh) 048 */ 049public class PetiteToken extends ScalarToken { 050 /** Construct a PetiteToken with value 0.0. 051 */ 052 public PetiteToken() { 053 _value = 0.0; 054 } 055 056 /** Construct a PetiteToken with the specified value. 057 * Ensure that the value is adjusted within limits [-1,1). 058 * @param value The specified value. 059 */ 060 public PetiteToken(double value) { 061 _value = _adjust(value); 062 } 063 064 /** Construct a PetiteToken from the specified string.Ensure 065 * the value is adjusted within the range of a PetiteToken. 066 * @param init The specified string, for example <code>1.0p</code> 067 * @exception IllegalActionException If the Token could not 068 * be created with the given String. 069 */ 070 public PetiteToken(String init) throws IllegalActionException { 071 try { 072 _value = _adjust(Double.parseDouble(init)); 073 } catch (NumberFormatException e) { 074 throw new IllegalActionException(e.getMessage()); 075 } 076 } 077 078 /////////////////////////////////////////////////////////////////// 079 //// public methods //// 080 081 /** Convert the specified token into an instance of PetiteToken. 082 * This method does lossless conversion. The units of the returned 083 * token will be the same as the units of the given token. 084 * If the argument is already an instance of PetiteToken, 085 * it is returned without any change. Since the PetiteToken is cannot be 086 * losslessly converted to any other token an exception is thrown, in all 087 * other cases. 088 * @param token The token to be converted to a PetiteToken. 089 * @return A PetiteToken. 090 * @exception IllegalActionException If the conversion 091 * cannot be carried out. 092 */ 093 public static PetiteToken convert(Token token) 094 throws IllegalActionException { 095 if (token instanceof PetiteToken) { 096 return (PetiteToken) token; 097 } else { 098 if (token instanceof DoubleToken) { 099 // Need to get the value of the DoubleToken and _adjust it 100 return new PetiteToken(((DoubleToken) token).doubleValue()); 101 } else { 102 throw new IllegalActionException( 103 notSupportedConversionMessage(token, "petite")); 104 } 105 } 106 } 107 108 /** Return the value in the token as a double. 109 * @return The value contained in this token as a double. 110 */ 111 @Override 112 public double doubleValue() { 113 return _value; 114 } 115 116 /** Return the value in the token. 117 * @return The value contained in this token. 118 */ 119 public double petiteValue() { 120 return _value; 121 } 122 123 /** Return true if the argument's class is PetiteToken and it has the 124 * same values as this token. 125 * @param object An instance of Object. 126 * @return True if the argument is a PetiteToken with the 127 * same value. 128 */ 129 @Override 130 public boolean equals(Object object) { 131 if (object == null) { 132 return false; 133 } 134 // This test rules out subclasses. 135 if (object.getClass() != getClass()) { 136 return false; 137 } 138 139 if (((PetiteToken) object).petiteValue() == _value) { 140 return true; 141 } 142 143 return false; 144 } 145 146 /** Return the type of this token. 147 * @return BaseType.PETITE 148 */ 149 @Override 150 public Type getType() { 151 return BaseType.PETITE; 152 } 153 154 /** Return a hash code value for this token. This method returns the 155 * hash code of the contained double. 156 * @return A hash code value for this token. 157 */ 158 @Override 159 public int hashCode() { 160 return Double.valueOf(_value).hashCode(); 161 } 162 163 /** Returns a PetiteToken with value nearest 1.0....... 164 * @return A PetiteToken with value nearest 1.0. 165 */ 166 @Override 167 public Token one() { 168 return ONE; 169 } 170 171 /** Return the value of this token as a string that can be parsed 172 * by the expression language to recover a token with the same value. 173 * The exact form of the number depends on its value, and may be either 174 * decimal or exponential. In general, exponential is used for numbers 175 * whose magnitudes are very large or very small, except for zero which 176 * is always represented as 0.0. The behavior is roughly the same as 177 * Double.toString(), except that we limit the precision to seven 178 * fractional digits. If you really must have better precision, 179 * then use <code>Double.toString(token.doubleValue())</code>. 180 * If this token has a unit, the return string also includes a unit 181 * string produced by the unitsString() method in the super class. 182 * @return A String representing the double value and the units (if 183 * any) of this token. 184 * @see ptolemy.data.ScalarToken#unitsString 185 */ 186 @Override 187 public String toString() { 188 String unitString = ""; 189 190 if (!_isUnitless()) { 191 unitString = " * " + unitsString(); 192 } 193 return TokenUtilities.regularFormat.format(_value) + "p" + unitString; 194 } 195 196 /** Returns a PetiteToken with value 0.0. 197 * @return A PetiteToken with value 0.0. 198 */ 199 @Override 200 public Token zero() { 201 return ZERO; 202 } 203 204 /////////////////////////////////////////////////////////////////// 205 //// public variablesds //// 206 207 /** A PetiteToken with the value 1.0. */ 208 public static final PetiteToken ONE = new PetiteToken(1.0); 209 210 /** A PetiteToken with the value 0.0. */ 211 public static final PetiteToken ZERO = new PetiteToken(0.0); 212 213 /////////////////////////////////////////////////////////////////// 214 //// protected methods //// 215 216 /** Return a ScalarToken containing the absolute value of the 217 * value of this token. If this token contains a non-negative 218 * number, it is returned directly; otherwise, a new token is is 219 * return. Note that it is explicitly allowable to return this 220 * token, since the units are the same. The call to the constructor 221 * ensures the value is within the range defined by a PetiteToken. 222 * It thus automatically converts -1 to (1 - Double.MIN_VALUE). 223 * @return An PetiteToken. 224 */ 225 @Override 226 protected ScalarToken _absolute() { 227 PetiteToken result; 228 229 if (_value >= 0.0) { 230 result = this; 231 } else { 232 result = new PetiteToken(-_value); 233 } 234 235 return result; 236 } 237 238 /** Return a new token whose value is the value of the argument 239 * Token added to the value of this Token. It is assumed that 240 * the type of the argument is an PetiteToken.The token to add is 241 * first adjusted to the range defined by a petite token. After 242 * division, the result is adjusted again to maintain the range 243 * of a PetiteToken. The final adjustment happens automatically 244 * given the call to _adjust in the PetiteToken constructor. 245 * @param rightArgument The token to add to this token. 246 * @return A new PetiteToken containing the result. 247 */ 248 @Override 249 protected ScalarToken _add(ScalarToken rightArgument) { 250 double sum = _value + ((PetiteToken) rightArgument).doubleValue(); 251 return new PetiteToken(sum); 252 } 253 254 /** Returns a token representing the bitwise AND of this token and 255 * the given token. 256 * @param rightArgument The PetiteToken to bitwise AND with this one. 257 * @return The bitwise AND. 258 * @exception IllegalActionException Always thrown by this base class. 259 */ 260 @Override 261 protected ScalarToken _bitwiseAnd(ScalarToken rightArgument) 262 throws IllegalActionException { 263 throw new IllegalActionException( 264 notSupportedMessage("bitwiseAnd", this, rightArgument)); 265 } 266 267 /** Returns a token representing the bitwise NOT of this token. 268 * @return The bitwise NOT of this token. 269 * @exception IllegalActionException Always thrown by this base class. 270 */ 271 @Override 272 protected ScalarToken _bitwiseNot() throws IllegalActionException { 273 throw new IllegalActionException( 274 notSupportedMessage("bitwiseNot", this, this)); 275 } 276 277 /** Returns a token representing the bitwise OR of this token and 278 * the given token. 279 * @param rightArgument The PetiteToken to bitwise OR with this one. 280 * @return The bitwise OR. 281 * @exception IllegalActionException Always thrown by this base class. 282 */ 283 @Override 284 protected ScalarToken _bitwiseOr(ScalarToken rightArgument) 285 throws IllegalActionException { 286 throw new IllegalActionException( 287 notSupportedMessage("bitwiseOr", this, rightArgument)); 288 } 289 290 /** Returns a token representing the bitwise XOR of this token and 291 * the given token. 292 * @param rightArgument The PetiteToken to bitwise XOR with this one. 293 * @return The bitwise XOR. 294 * @exception IllegalActionException Always thrown by this base class. 295 */ 296 @Override 297 protected ScalarToken _bitwiseXor(ScalarToken rightArgument) 298 throws IllegalActionException { 299 throw new IllegalActionException( 300 notSupportedMessage("bitwiseXor", this, rightArgument)); 301 } 302 303 /** Return a new token whose value is the value of this token 304 * divided by the value of the argument token. It is assumed that 305 * the type of the argument is an PetiteToken. The token to 306 * divide by is first adjusted to the range defined by a petite 307 * token. After division, the result is adjusted again to 308 * maintain the range of a PetiteToken. The final adjustment 309 * happens automatically given the call to _adjust in the 310 * PetiteToken constructor. 311 * @param divisor The token to divide this token by. 312 * @return A new PetiteToken containing the result. 313 */ 314 @Override 315 protected ScalarToken _divide(ScalarToken divisor) { 316 double quotient = _value / ((PetiteToken) divisor).doubleValue(); 317 return new PetiteToken(quotient); 318 } 319 320 /** Test that the value of this token is close to the first argument, 321 * where "close" means that the distance between their values is less than 322 * or equal to the second argument. It is assumed that the type of 323 * the first argument is PetiteToken. The right argument is adjusted to 324 * be in the range of a PetiteToken. The second argument is also adjusted 325 * likewise. 326 * @param rightArgument The token to compare to this token. 327 * @param epsilon The distance. 328 * @return A token containing true if the value of this token is close 329 * to that of the argument. 330 */ 331 @Override 332 protected BooleanToken _isCloseTo(ScalarToken rightArgument, 333 double epsilon) { 334 // NOTE: This code is duplicated in 335 // ptolemy.math.DoubleMatrixMath.within(); if this 336 // implementation changes, also change the corresponding 337 // implementation there. 338 // NOTE: Used to compare against epsilon the following expression: 339 // Math.abs(doubleValue() - ((PetiteToken)rightArgument).doubleValue())) 340 // However, because of quantization errors, this did not work well. 341 double right = ((PetiteToken) rightArgument).doubleValue(); 342 double left = petiteValue(); 343 344 if (right > left + epsilon || right < left - epsilon) { 345 return BooleanToken.FALSE; 346 } else { 347 return BooleanToken.TRUE; 348 } 349 } 350 351 /** Test for ordering of the values of this Token and the argument 352 * Token. It is assumed that the type of the argument is PetiteToken. 353 * The argument token is then adjusted to the range of a PetiteToken. 354 * @param rightArgument The token to compare this token with. 355 * @exception IllegalActionException If this method is not 356 * supported by the derived class. 357 * @return A new Token containing the result. 358 */ 359 @Override 360 protected BooleanToken _isLessThan(ScalarToken rightArgument) 361 throws IllegalActionException { 362 PetiteToken convertedArgument = (PetiteToken) rightArgument; 363 return BooleanToken 364 .getInstance(_value < convertedArgument.doubleValue()); 365 } 366 367 /** Return a new token whose value is the value of this token 368 * modulo the value of the argument token. It is assumed that 369 * the type of the argument is an PetiteToken.The token to take 370 * modulo by is first adjusted to the range defined by a petite 371 * token. After the modulo operation, the result is adjusted again to 372 * maintain the range of a PetiteToken. The final adjustment happens 373 * automatically given the call to _adjust in the PetiteToken constructor 374 * @param rightArgument The token to modulo this token by. 375 * @return A new PetiteToken containing the result. 376 */ 377 @Override 378 protected ScalarToken _modulo(ScalarToken rightArgument) { 379 double remainder = _value % ((PetiteToken) rightArgument).doubleValue(); 380 return new PetiteToken(remainder); 381 } 382 383 /** Return a new token whose value is the value of this token 384 * multiplied by the value of the argument token. It is assumed that 385 * the type of the argument is an PetiteToken.The token to multiply 386 * is first adjusted to the range defined by a petite token. After 387 * multiplication, the result is adjusted again to 388 * maintain the range of a PetiteToken. The final adjustment happens 389 * automatically given the call to _adjust in the PetiteToken constructor 390 * @param rightArgument The token to multiply this token by. 391 * @return A new PetiteToken containing the result. 392 */ 393 @Override 394 protected ScalarToken _multiply(ScalarToken rightArgument) { 395 double product = _value * ((PetiteToken) rightArgument).doubleValue(); 396 return new PetiteToken(product); 397 } 398 399 /** Return a new token whose value is the value of the argument token 400 * subtracted from the value of this token. It is assumed that 401 * the type of the argument is an PetiteToken. The token to subtract 402 * is first adjusted to the range defined by a petite token. After 403 * subtraction from this token, the result is adjusted again to 404 * maintain the range of a PetiteToken. The final adjustment happens 405 * automatically given the call to _adjust in the PetiteToken constructor 406 * @param rightArgument The token to subtract from this token. 407 * @return A new PetiteToken containing the result. 408 */ 409 @Override 410 protected ScalarToken _subtract(ScalarToken rightArgument) { 411 double difference = _value 412 - ((PetiteToken) rightArgument).doubleValue(); 413 return new PetiteToken(difference); 414 } 415 416 /** 417 * Adjust the value of the PetiteToken to limit it to the range 418 * [-1,1) while maintaining the precision of PetiteToken. 419 * @param number The value to be adjusted. 420 * @return The adjusted value. 421 */ 422 protected static double _adjust(double number) { 423 if (number >= 1.0) { 424 return 1.0 - Double.MIN_VALUE; 425 } else { 426 if (number < -1.0) { 427 return -1.0; 428 } 429 } 430 return number; 431 } 432 433 /////////////////////////////////////////////////////////////////// 434 //// private variables //// 435 private double _value; 436}