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}
Short‑circuit (minimal) evaluation is the
default behavior of the conditional operators || (logical
OR) and && (logical AND). Consider the expressions:
c = a || b;
f = d && e;
The second argument is evaluated only when the result of the conditional cannot be determined from the first argument alone.
In the first expression, if a
is nonzero, the overall result is true, so b is not evaluated.
In the second expression, if d
is zero, the overall result is false, so e is not evaluated.
Short‑circuit evaluation is useful for avoiding unnecessary computation. For example:
c = (max(w1) > 0) || (max(gnorm(1000000000, 1)) > 0)
If W1 contains only positive
values, the first condition is true and the expensive random‑number computation
in the second argument is skipped. This behavior is equivalent to:
if (max(w1) > 0)
{
c = 1;
}
else
{
c = max(gnorm(1000000000, 1)) > 0;
}
The SOR(a, b) and SAND(a,
b) functions also perform short‑circuit conditional evaluation.
In contrast, OR(a, b) and AND(a, b) use eager
evaluation, where both arguments are always evaluated.
If the configuration parameter SPL_SHORT_CIRCUIT
is set to 0, the operators ||, &&,
SOR, and sand revert to eager evaluation.