SPL includes a number of relational and logical operators and functions:
Operator |
Function |
Description |
< |
LESSER |
less than |
<= |
LESSEREQ |
less than or equal |
> |
GREATER |
greater than |
>= |
GREATEREQ |
greater than or equal |
== |
EQUAL |
Equal |
!= |
NOTEQ |
not equal |
&& |
AND |
logical and |
|| |
OR |
logical or |
! |
NOT |
logical not |
|
XOR |
exclusive or |
% |
MOD |
Modulo |
For example, the expression a != 10 is functionally equivalent to noteq(a, 10).
Relational and logical operators return a binary result (1 or 0) for scalar parameters. For example:
a = 1;
a < 10; returns: 1
a != 1; returns: 0
Here are two functions that determine whether a number is even or odd:
/* returns 1 if number is even, else 0 */
iseven(x)
{
return(2*(int(x/2)) == x);
}
/* returns 1 if number is odd, else 0 */
isodd(x)
{
return(not(iseven(x)));
}
The built-in int function returns the integer part of a number. The % operator could also be used to detect an even or odd number.
/* returns 1 if number is even, else 0 */
iseven(x)
{
return(x % 2 == 0);
}
/* returns 1 if number is odd, else 0 */
isodd(x)
{
return(x % 2 != 0);
}
A function that returns the sign of a number is quite straightforward:
/*
* returns the sign of a number,
* 1: positive, 0: zero, -1: negative
*/
sgn(n)
{
local sign;
sign = (n > 0) - (n < 0);
return(sign);
}
Relational and logical operators also work on entire series, returning a binary series (a series consisting of 1's or 0's) as the result.
s = {1, 2, 3, 4};
t = s >= 2;
The series t contains the values {0, 1, 1, 1}. This feature results in very powerful and compact SPL code. Consider the function:
/* replace series values based on logical condition */
replace(s, cond, val)
{
local result;
result = s * not(cond) + val * cond;
return(result);
}
Now replace(w1, w1 > 10, 11) replaces all the values in W1 that exceed 10.0 with the value 11.0. The expression replace(w1, w1 < w2, w2) creates a series that contains the larger of the values of W1 and W2 on a point by point basis. Notice again that traditional looping is not required.
As a related example, the following function returns the indices of the non-zero elements of a series or array.
/* return indices of non-zero elements of an array */
findnz(x)
The size function returns the number of rows and columns of an array. By exploiting the series processing feature of SPL, the series nz is 1 where the input is non-zero and 0 where the input is zero. Multiplying nv by a linear ramp of slope 1 and then removing the zero elements produces a series that contains the indices of the non-zero elements of the input. For example:
a = {1, 0, 5};
b = findnz(a);
c = findnz(a > 1);
d = a[b];
b == {1, 3}
c == {3}
d == {1, 5}
The built-in find function returns the indices of the non-zero elements of array as a single "unraveled" series. These indices can be used to address arrays.
a = {{1, 2, 3}, {4, 5, 2}, {2, 8, 9}};
b = find(a == 2);
c = a[b];
b == {3, 4, 8}
c == {2, 2, 2}