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}