inttypes, and need no further explanation. To support the other two types, the Ptolemy kernel contains a
Complexclass and a
Fixclass, which are described in the rest of this section.
4.2.1 The Complex data type
Complex data type in Ptolemy contains real and imaginary components, each of which is specified as a double precision floating-point number. The notation used to represent a complex number is a two number pair: (real, imaginary)-for example, (1.3,-4.5) corresponds to the complex number 1.3 - 4.5j.
Complex implements a subset of the functionality of the complex number classes in the cfront and libg++ libraries, including most of the standard arithmetic operators and a few transcendental functions.
Create a complex number initialized to zero-that is, (0.0, 0.0). For example,
Complex(double real, double imag)
Create a complex number whose value is (real, imag). For example,
Complex(const Complex& arg)
Create a complex number with the same value as the argument (the copy constructor). For example,
The following list of arithmetic operators modify the value of the complex number. All functions return a reference to the modified complex number (
Complex& operator = (const Complex& arg)
Complex& operator += (const Complex& arg)
Complex& operator -= (const Complex& arg)
Complex& operator *= (const Complex& arg)
Complex& operator /= (const Complex& arg)
Complex& operator *= (double arg)
Complex& operator /= (double arg)
There are two operators to return the real and imaginary parts of the complex number:
double real() const
double imag() const
Non-member functions and operators:
The following one- and two-argument operators return a new complex number:
Complex operator + (const Complex& x, const Complex& y)
Complex operator - (const Complex& x, const Complex& y)
Complex operator * (const Complex& x, const Complex& y)
Complex operator * (double x, const Complex& y)
Complex operator * (const Complex& x, double y)
Complex operator / (const Complex& x, const Complex& y)
Complex operator / (const Complex& x, double y)
Complex operator - (const Complex& x)
Return the negative of the complex number.
Complex conj (const Complex& x)
Return the complex conjugate of the number.
Complex sin(const Complex& x)
Complex cos(const Complex& x)
Complex exp(const Complex& x)
Complex log(const Complex& x)
Complex sqrt(const Complex& x)
Complex pow(double base, const Complex& expon)
Complex pow(const Complex& base, const Complex& expon)
Other general operators:
double abs(const Complex& x)
Return the absolute value, defined to be the square root of the norm.
double arg(const Complex& x)
Return the value arctan(x.imag()/x.real()).
double norm(const Complex& x)
Return the value x.real() * x.real() + x.imag() * x.imag().
double real(const Complex& x)
Return the real part of the complex number.
double imag(const Complex& x)
Return the imaginary part of the complex number.
int operator != (const Complex& x, const Complex& y)
int operator == (const Complex& x, const Complex& y)
fixed-point data type
The fixed-point data type is implemented in Ptolemy by the
Fix class. This class supports a two's complement representation of a finite precision number. In fixed-point notation, the partition between the integer part and the fractional part-the binary point-lies at a fixed position in the bit pattern. Its position represents a trade-off between precision and range. If the binary point lies to the right of all bits, then there is no fractional part.
Constructing Fixed-point variables
Variables of type
Fix are defined by specifying the word length and the position of the binary point. At the user-interface level, precision is specified either by setting a fixed-point parameter to a "(value, precision)" pair, or by setting a
precision parameter. The former gives the value and precision of some fixed-point value, while the latter is typically used to specify the internal precision of computations in a star.
Fix objects either have the precision passed as an "x.y" or "m/n" string, or as two C++ integers that specify the total number of bits and the number of integer bits including the sign bit (that is, n and x). For example, suppose you have a star with a precision parameter named precision. Consider the following code:
Error::abortRun(*this, "Invalid precision");
Fix class. The error check verifies that the precision was valid.
Fix object which is specified by the constant
FIX_MAX_LENGTH in the file
$PTOLEMY/src/kernel/Fix.h. The current value is 64 bits. Numbers in the
Fix class are represented using two's complement notation, with the sign bit stored in the bits to the left of the binary point. There must always be at least one bit to the left of the binary point to store the sign.
Fix object contains information about its precision and error codes indicating overflow, divide-by-zero, or bad format parameters. The error codes are set when errors occur in constructors or arithmetic operators. There are also fields to specify
Fixvalues are assigned to it-truncation is the default
Fixtype is still experimental.
FixArray. The precision is specified by an associated precision state using either of two syntaxes:
Fixwith precision 3.5.
Fixtypes are available in Ptolemy as a type of
Particle. The conversion from an
Fixtakes place using the
Fix::Fix(double)constructor which makes a
Fixobject with the default word length of 24 bits and the number of integer bits as needed required by the value. For instance, the
double10.3 will be converted to a
Fixwith precision 5.19, since 5 is the minimum number of bits needed to represent the integer part, 10, including its sign bit.
To use the
Fixtype in a star, the type of the portholes must be declared as "
fix". Stars that receive or transmit fixed-point data have parameters that specify the precision of the input and output in bits, as well as the overflow behavior. Here is a simplified version of
SDFAddFixstar, configured for two inputs:
AddFixstar supports any number of inputs.) By default, the precision used by this star during the addition will have 2 bits to the left of the binary point and 14 bits to the right. Not shown here is the state OverflowHandler, which is inherited from the SDFFix star and which defaults to
saturate-that is, if the addition overflows, then the result saturates, pegging it to either the largest positive or negative number representable. The result value, sum, is initialized by the following code:
gomethod, we use sum to calculate the result value, thus guaranteeing that the desired precision and overflow handling are enforced. For example,
Fixobject until the begin method runs. In the begin method, it is given the precision specified by OutputPrecision. The go method initializes it to zero. If the go method had instead assigned it a value specified by another
Fixobject, then it would acquire the precision of that other object-at that point, it would be initialized.
Fixobject has been initialized, its precision does not change as long as the object exists. The assignment operator is overloaded so that it checks whether the value of the object to the right of the assignment fits into the precision of the left object. If not, then it takes the appropriate overflow response is taken and set the overflow error bit.
Fixobject is created using the constructor that takes no arguments, as in the
protecteddeclaration above, then that object is an uninitialized
Fix; it can accept any assignment, acquiring not only its value, but also its precision and overflow handler.
The behavior of a
Fixobject on an overflow depends on the specifications and the behavior of the object itself. Each object has a private data field that is initialized by the constructor; when there is an overflow, the
overflow_handlerlooks at this field and uses the specified method to handle the overflow. This data field is set to
saturateby default, and can be set explicitly to any other desired overflow handling method using a function called
set_ovflow(<keyword>). The keywords for overflow handling methods are:
saturatereplaces the original value is replaced by the maximum (for overflow) or minimum (for underflow) value representable given the precision of the
zero_saturatesets the value to zero.
gomethod assigned the input to the protected member
sum, which has the side-effect of quantizing the input to the precision of
sum. We could have alternatively written the
gomethod as follows:
Some stars allow the user to select between these two different behaviors with a parameter called ArrivingPrecision. If set to
YES, the input particles are not explicitly cast; they are used as they are; if set to
NO, the input particles are cast to an internal precision, which is usually specified by another parameter.
Here is the (abbreviated) source of the
SDFGainFixstar, which demonstrates this point:
SDFGainFixstar and many of the
Fixstars are derived from the star
SDFFiximplements commonly used methods and defines two states: OverflowHandler selects one of four overflow handlers to be called each time an overflow occurs; and ReportOverflow, which, if true, causes the number and percentage of overflows that occurred for that star during a simulation run to be reported in the wrapup method.
Fixnumber with unspecified precision and value zero.
Fix(int length, int intbits)
Fixnumber with total word length of
intbitsbits to the left of the binary point. The value is set to zero. If the precision parameters are not valid, then an error bit is internally set so that the
invalidmethod will return
Fix(const char* precisionString)
Fixnumber whose precision is determined by
precisionString, which has the syntax "leftbits.rightbits", where leftbits is the number of bits to the left of the binary point and rightbits is the number of bits to the right of the binary point, or "rightbits/totalbits", where totalbits is the total number of bits. The value is set to zero. If the
precisionStringis not in the proper format, an error bit is internally set so that the
invalidmethod will return
Fixwith the default precision of 24 total bits for the word length and set the number of integer bits to the minimum needed to represent the integer part of the number value. If the value given needs more than 24 bits to represent, the value will be clipped and the number stored will be the largest possible under the default precision (i.e. saturation occurs). In this case an internal error bit is set so that the
ovf_occurredmethod will return
Fix(int length, int intbits, double value)
Fixwith the specified precision and set its value to the given
value. The number is rounded to the closest representable number given the precision. If the precision parameters are not valid, then an error bit is internally set so that the
invalidmethod will return
Fix(const char* precisionString, double value)
precisionStringinstead of as two integer arguments. If the precision parameters are not valid, then an error bit is internally set so that the
invalid()method will return true when called on the object.
Fix(const char* precisionString, uint16* bits)
Fixwith the specified precision and set the bits precisely to the ones in the given
bits. The first word pointed to by
bitscontains the most significant 16 bits of the representation. Only as many words as are necessary to fetch the bits will be referenced from the
bitsargument. For example:
Fix("2.14",bits)will only reference
Fix(const Fix& arg)
Fix(int length, int intbits, const Fix& arg)
Fixargument and set to a new precision. If the precision parameters are not valid, then an error bit is internally set so that the
invalidmethod will return true when called on the object. If the value from the source will not fit, an error bit is set so that the
ovf_occurredmethod will return
int len() const
int intb() const
int precision() const
int overflow() const
Fixnumber. The possible codes are:
int roundMode() const
int signBit() const
TRUEif the value of the
Fixnumber is negative,
FALSEif it is positive or zero.
TRUEif the value of the
Fixnumber is zero.
Fixnumber as a double.
Fixnumber to zero.
void set_overflow(int value)
void set_rounding(int value)
Fixnumber to zero.
void set_ovflow(const char*)
void Set_MASK(int value)
int compare (const Fix& a, const Fix& b)
Fixnumbers. Return -1 if a < b, 0 if a = b, 1 if a > b.
TRUEif an overflow has occurred as the result of some operation like addition or assignment.
TRUEif the current value of the
Fixnumber is invalid due to it having an improper precision format, or if some operation caused a divide by zero.
TRUEif a divide by zero error occurred.
Fix& operator = (const Fix& arg)
*thisdoes not have its precision format set (i.e. it is uninitialized), the source
Fixis copied. Otherwise, the source
Fixvalue is converted to the existing precision. Either truncation or rounding takes place, based on the value of the rounding bit of the current object. Overflow results either in saturation, "zero saturation" (replacing the result with zero), or a warning error message, depending on the overflow field of the object. In these cases,
TRUEon the result.
Fix& operator = (double arg)
Fixnumber and then assigned to
Fix& operator += (const Fix&)
Fix& operator -= (const Fix&)
Fix& operator *= (const Fix&)
Fix& operator *= (int)
Fix& operator /= (const Fix&)
Fix operator + (const Fix&, const Fix&)
Fix operator - (const Fix&, const Fix&)
Fix operator * (const Fix&, const Fix&)
Fix operator * (const Fix&, int)
Fix operator * (int, const Fix&)
Fix operator / (const Fix&, const Fix&)
Fix operator - (const Fix&) // unary minus
int operator == (const Fix& a, const Fix& b)
int operator != (const Fix& a, const Fix& b)
int operator >= (const Fix& a, const Fix& b)
int operator <= (const Fix& a, const Fix& b)
int operator > (const Fix& a, const Fix& b)
int operator < (const Fix& a, const Fix& b)
Fixwith all 64 bits before the binary point.
int compare(const Fix& a, const Fix& b)This functions returns -1 if a < b, 0 if a = b, and 1 if a > b. The comparison is exact (every bit is checked) if the two values have the same precision format. If the precisions are different, the arguments are converted to doubles and compared. Since
doublevalues only have an accuracy of about 53 bits on most machines, this may cause false equality reports for
Fixvalues with many bits.
operator int() const
Fixnumber as an integer, truncating towards zero.
operator float() const
operator double() const
Fixclass defines the following enumerated values for overflow handling:
set_overflowmethod, as in the following example:
overflow_typeargument may be one of
The rounding behavior of a
Fixvalue may be set by calling
Fix::mask_truncate, truncation will occur. If the argument is nonzero (for example, if it has the value
Fix::mask_truncate_round, rounding will occur. The older name
Set_MASKis a synonym for
The following functions access the error bits of a
TRUEif there have been any overflows in computing the value. The second returns
TRUEif the value is invalid, because of invalid precision parameters or a divide by zero. The third returns
TRUEonly for divide by zero.