Option hfloat in Procedures
|
Calling Sequence
|
|
option hfloat or options hfloat
|
|
Description
|
|
•
|
The hfloat option to a procedure forces all floating-point operations in a procedure to be performed using hardware floating-point values. Depending on the operations performed, this can significantly speed up execution of the procedure, at the cost of floating-point accuracy. Procedures that perform many floating-point operations or manipulate the contents of Arrays, Matrices, or Vectors of hardware floating-point values will benefit the most from this option.
|
•
|
Specifically, the hfloat option causes the following differences in the procedure's definition and execution:
|
–
|
Any floating-point constants appearing in the procedure body are converted into hardware floating-point values when the procedure is first created.
|
–
|
Numeric arguments passed to the procedure are converted into hardware floating-point values when the procedure is invoked.
|
–
|
Extracting values from hardware floating-point Arrays, Matrices, and Vectors will not incur a conversion to arbitrary precision floating-point form. Instead, the hardware floating-point values will be used directly.
|
–
|
Calls to evalhf made from within the procedure will return a hardware floating-point value, and thus will not incur a conversion to arbitrary precision floating-point form.
|
•
|
The differences, together with the rules for contagion of hardware floating-point values in expressions (see HFloat), will usually cause arithmetic operations in the procedure to be performed using hardware floating-point arithmetic.
|
•
|
The use of the hfloat option differs from using evalhf in a few ways:
|
–
|
When a procedure is executed within the evalhf environment, everything is performed using hardware floats, and the operations available are restricted to those that can be done using hardware floats. No other basic data types, such as integers or strings, are available.
|
–
|
The only data structures available within the evalhf environment are Arrays.
|
•
|
Performance of a procedure having option hfloat will generally be better than one operating with arbitrary precision floats, but usually not as good as a procedure operating within evalhf. But, a procedure with option hfloat has the full power of Maple available to it. All Maple operations, data types (except arbitrary precision software floating point), and data structures can be used in such a procedure.
|
•
|
The hfloat option cannot be used in conjunction with any of these other options: autocompile, builtin, call_external, and inline.
|
|
|
Examples
|
|
Create two vectors of hardware floating-point values, and another in which to store a result.
>
|
|
>
|
|
>
|
|
>
|
|
Define a procedure to compute for each corresponding pair of elements of two vectors.
>
|
hypot_elements := proc( v1::Vector, v2::Vector, r::Vector, size::integer )
local i;
for i to size do r[i] := sqrt(v1[i]^2 + v2[i]^2) od
end:
|
>
|
|
| (1) |
Redefine procedure to use option hfloat and time it again.
>
|
hypot_elements := proc( v1::Vector, v2::Vector, r::Vector, size::integer )
option hfloat;
local i;
for i to size do r[i] := sqrt(v1[i]^2 + v2[i]^2) od
end:
|
>
|
|
| (2) |
For this simple example, using the evalhf environment also works, and is faster still.
>
|
|
| (3) |
Define a procedure to perform low-pass audio filtering, and time it for a 5 second sample.
>
|
LowPassFilter := proc( x :: Array, y :: Array, cutoff :: numeric := 500.0 )
local len, dt, rc, alpha, i;
len := rhs([rtable_dims(x)][1]);
dt := AudioTools:-Duration(x) / len;
rc := 1 / (evalhf(Pi) * cutoff);
alpha := evalhf(dt / (rc + dt));
y[1] := x[1];
for i from 2 to len do y[i] := y[i-1] + alpha * (x[i] - y[i-1]) od;
end:
|
>
|
|
>
|
|
>
|
|
| (4) |
Redefine the procedure to use option hfloat and time it again.
>
|
LowPassFilter := proc( x :: Array, y :: Array, cutoff :: numeric := 500.0 )
option hfloat;
local len, dt, rc, alpha, i;
len := rhs([rtable_dims(x)][1]);
dt := AudioTools:-Duration(x) / len;
rc := 1 / (evalhf(Pi) * cutoff);
alpha := evalhf(dt / (rc + dt));
y[1] := x[1];
for i from 2 to len do y[i] := y[i-1] + alpha * (x[i] - y[i-1]) od;
end:
|
>
|
|
| (5) |
The above procedure would require extensive changes to work within the limitations of evalhf: len would have to be passed as an argument because neither lists nor rhs are supported within evalhf, and duration would have to be passed in because the :- operator isn't supported.
|
|