Next: Rewrite Rules, Previous: Summations, Up: Algebra

The following commands and algebraic functions return true/false values,
where 1 represents “true” and 0 represents “false.” In cases where
a truth value is required (such as for the condition part of a rewrite
rule, or as the condition for a `Z [ Z ]` control structure), any
nonzero value is accepted to mean “true.” (Specifically, anything
for which `dnonzero`

returns 1 is “true,” and anything for
which `dnonzero`

returns 0 or cannot decide is assumed “false.”
Note that this means that `Z [ Z ]` will execute the “then”
portion if its condition is provably true, but it will execute the
“else” portion for any condition like ‘`a = b`’ that is not
provably true, even if it might be true. Algebraic functions that
have conditions as arguments, like `? :`

and `&&`

, remain
unevaluated if the condition is neither provably true nor provably
false. See Declarations.)

The `a =` (`calc-equal-to`

) command, or ‘`eq(a,b)`’ function
(which can also be written ‘`a = b`’ or ‘`a == b`’ in an algebraic
formula) is true if ‘`a`’ and ‘`b`’ are equal, either because they
are identical expressions, or because they are numbers which are
numerically equal. (Thus the integer 1 is considered equal to the float
1.0.) If the equality of ‘`a`’ and ‘`b`’ cannot be determined,
the comparison is left in symbolic form. Note that as a command, this
operation pops two values from the stack and pushes back either a 1 or
a 0, or a formula ‘`a = b`’ if the values' equality cannot be determined.

Many Calc commands use ‘`=`’ formulas to represent equations.
For example, the `a S` (`calc-solve-for`

) command rearranges
an equation to solve for a given variable. The `a M`
(`calc-map-equation`

) command can be used to apply any
function to both sides of an equation; for example, `2 a M *`
multiplies both sides of the equation by two. Note that just
`2 *` would not do the same thing; it would produce the formula
‘`2 (a = b)`’ which represents 2 if the equality is true or
zero if not.

The `eq`

function with more than two arguments (e.g., `C-u 3 a =`
or ‘`a = b = c`’) tests if all of its arguments are equal. In
algebraic notation, the ‘`=`’ operator is unusual in that it is
neither left- nor right-associative: ‘`a = b = c`’ is not the
same as ‘`(a = b) = c`’ or ‘`a = (b = c)`’ (which each compare
one variable with the 1 or 0 that results from comparing two other
variables).

The `a #` (`calc-not-equal-to`

) command, or ‘`neq(a,b)`’ or
‘`a != b`’ function, is true if ‘`a`’ and ‘`b`’ are not equal.
This also works with more than two arguments; ‘`a != b != c != d`’
tests that all four of ‘`a`’, ‘`b`’, ‘`c`’, and ‘`d`’ are
distinct numbers.

The `a <` (`calc-less-than`

) [‘`lt(a,b)`’ or ‘`a < b`’]
operation is true if ‘`a`’ is less than ‘`b`’. Similar functions
are `a >` (`calc-greater-than`

) [‘`gt(a,b)`’ or ‘`a > b`’],
`a [` (`calc-less-equal`

) [‘`leq(a,b)`’ or ‘`a <= b`’], and
`a ]` (`calc-greater-equal`

) [‘`geq(a,b)`’ or ‘`a >= b`’].

While the inequality functions like `lt`

do not accept more
than two arguments, the syntax ‘`a <= b < c`’ is translated to an
equivalent expression involving intervals: ‘`b in [a .. c)`’.
(See the description of `in`

below.) All four combinations
of ‘`<`’ and ‘`<=`’ are allowed, or any of the four combinations
of ‘`>`’ and ‘`>=`’. Four-argument constructions like
‘`a < b < c < d`’, and mixtures like ‘`a < b = c`’ that
involve both equations and inequalities, are not allowed.

The `a .` (`calc-remove-equal`

) [`rmeq`

] command extracts
the righthand side of the equation or inequality on the top of the
stack. It also works elementwise on vectors. For example, if
‘`[x = 2.34, y = z / 2]`’ is on the stack, then `a .` produces
‘`[2.34, z / 2]`’. As a special case, if the righthand side is a
variable and the lefthand side is a number (as in ‘`2.34 = x`’), then
Calc keeps the lefthand side instead. Finally, this command works with
assignments ‘`x := 2.34`’ as well as equations, always taking the
righthand side, and for ‘`=>`’ (evaluates-to) operators, always
taking the lefthand side.

The `a &` (`calc-logical-and`

) [‘`land(a,b)`’ or ‘`a && b`’]
function is true if both of its arguments are true, i.e., are
non-zero numbers. In this case, the result will be either ‘`a`’ or
‘`b`’, chosen arbitrarily. If either argument is zero, the result is
zero. Otherwise, the formula is left in symbolic form.

The `a |` (`calc-logical-or`

) [‘`lor(a,b)`’ or ‘`a || b`’]
function is true if either or both of its arguments are true (nonzero).
The result is whichever argument was nonzero, choosing arbitrarily if both
are nonzero. If both ‘`a`’ and ‘`b`’ are zero, the result is
zero.

The `a !` (`calc-logical-not`

) [‘`lnot(a)`’ or ‘`! a`’]
function is true if ‘`a`’ is false (zero), or false if ‘`a`’ is
true (nonzero). It is left in symbolic form if ‘`a`’ is not a
number.

The `a :` (`calc-logical-if`

) [‘`if(a,b,c)`’ or ‘`a ? b : c`’]
function is equal to either ‘`b`’ or ‘`c`’ if ‘`a`’ is a nonzero
number or zero, respectively. If ‘`a`’ is not a number, the test is
left in symbolic form and neither ‘`b`’ nor ‘`c`’ is evaluated in
any way. In algebraic formulas, this is one of the few Calc functions
whose arguments are not automatically evaluated when the function itself
is evaluated. The others are `lambda`

, `quote`

, and
`condition`

.

One minor surprise to watch out for is that the formula ‘`a?3:4`’
will not work because the ‘`3:4`’ is parsed as a fraction instead of
as three separate symbols. Type something like ‘`a ? 3 : 4`’ or
‘`a?(3):4`’ instead.

As a special case, if ‘`a`’ evaluates to a vector, then both ‘`b`’
and ‘`c`’ are evaluated; the result is a vector of the same length
as ‘`a`’ whose elements are chosen from corresponding elements of
‘`b`’ and ‘`c`’ according to whether each element of ‘`a`’
is zero or nonzero. Each of ‘`b`’ and ‘`c`’ must be either a
vector of the same length as ‘`a`’, or a non-vector which is matched
with all elements of ‘`a`’.

The `a {` (`calc-in-set`

) [‘`in(a,b)`’] function is true if
the number ‘`a`’ is in the set of numbers represented by ‘`b`’.
If ‘`b`’ is an interval form, ‘`a`’ must be one of the values
encompassed by the interval. If ‘`b`’ is a vector, ‘`a`’ must be
equal to one of the elements of the vector. (If any vector elements are
intervals, ‘`a`’ must be in any of the intervals.) If ‘`b`’ is a
plain number, ‘`a`’ must be numerically equal to ‘`b`’.
See Set Operations, for a group of commands that manipulate sets
of this sort.

The ‘`typeof(a)`’ function produces an integer or variable which
characterizes ‘`a`’. If ‘`a`’ is a number, vector, or variable,
the result will be one of the following numbers:

1 Integer 2 Fraction 3 Floating-point number 4 HMS form 5 Rectangular complex number 6 Polar complex number 7 Error form 8 Interval form 9 Modulo form 10 Date-only form 11 Date/time form 12 Infinity (inf, uinf, or nan) 100 Variable 101 Vector (but not a matrix) 102 Matrix

Otherwise, ‘`a`’ is a formula, and the result is a variable which
represents the name of the top-level function call.

The ‘`integer(a)`’ function returns true if ‘`a`’ is an integer.
The ‘`real(a)`’ function
is true if ‘`a`’ is a real number, either integer, fraction, or
float. The ‘`constant(a)`’ function returns true if ‘`a`’ is
any of the objects for which `typeof`

would produce an integer
code result except for variables, and provided that the components of
an object like a vector or error form are themselves constant.
Note that infinities do not satisfy any of these tests, nor do
special constants like `pi`

and `e`

.

See Declarations, for a set of similar functions that recognize
formulas as well as actual numbers. For example, ‘`dint(floor(x))`’
is true because ‘`floor(x)`’ is provably integer-valued, but
‘`integer(floor(x))`’ does not because ‘`floor(x)`’ is not
literally an integer constant.

The ‘`refers(a,b)`’ function is true if the variable (or sub-expression)
‘`b`’ appears in ‘`a`’, or false otherwise. Unlike the other
tests described here, this function returns a definite “no” answer
even if its arguments are still in symbolic form. The only case where
`refers`

will be left unevaluated is if ‘`a`’ is a plain
variable (different from ‘`b`’).

The ‘`negative(a)`’ function returns true if ‘`a`’ “looks” negative,
because it is a negative number, because it is of the form ‘`-x`’,
or because it is a product or quotient with a term that looks negative.
This is most useful in rewrite rules. Beware that ‘`negative(a)`’
evaluates to 1 or 0 for *any* argument ‘`a`’, so it can only
be stored in a formula if the default simplifications are turned off
first with `m O` (or if it appears in an unevaluated context such
as a rewrite rule condition).

The ‘`variable(a)`’ function is true if ‘`a`’ is a variable,
or false if not. If ‘`a`’ is a function call, this test is left
in symbolic form. Built-in variables like `pi`

and `inf`

are considered variables like any others by this test.

The ‘`nonvar(a)`’ function is true if ‘`a`’ is a non-variable.
If its argument is a variable it is left unsimplified; it never
actually returns zero. However, since Calc's condition-testing
commands consider “false” anything not provably true, this is
often good enough.

The functions `lin`

, `linnt`

, `islin`

, and `islinnt`

check if an expression is “linear,” i.e., can be written in the form
‘`a + b x`’ for some constants ‘`a`’ and ‘`b`’, and some
variable or subformula ‘`x`’. The function ‘`islin(f,x)`’ checks
if formula ‘`f`’ is linear in ‘`x`’, returning 1 if so. For
example, ‘`islin(x,x)`’, ‘`islin(-x,x)`’, ‘`islin(3,x)`’, and
‘`islin(x y / 3 - 2, x)`’ all return 1. The ‘`lin(f,x)`’ function
is similar, except that instead of returning 1 it returns the vector
‘`[a, b, x]`’. For the above examples, this vector would be
‘`[0, 1, x]`’, ‘`[0, -1, x]`’, ‘`[3, 0, x]`’, and
‘`[-2, y/3, x]`’, respectively. Both `lin`

and `islin`

generally remain unevaluated for expressions which are not linear,
e.g., ‘`lin(2 x^2, x)`’ and ‘`lin(sin(x), x)`’. The second
argument can also be a formula; ‘`islin(2 + 3 sin(x), sin(x))`’
returns true.

The `linnt`

and `islinnt`

functions perform a similar check,
but require a “non-trivial” linear form, which means that the
‘`b`’ coefficient must be non-zero. For example, ‘`lin(2,x)`’
returns ‘`[2, 0, x]`’ and ‘`lin(y,x)`’ returns ‘`[y, 0, x]`’,
but ‘`linnt(2,x)`’ and ‘`linnt(y,x)`’ are left unevaluated
(in other words, these formulas are considered to be only “trivially”
linear in ‘`x`’).

All four linearity-testing functions allow you to omit the second
argument, in which case the input may be linear in any non-constant
formula. Here, the ‘`a=0`’, ‘`b=1`’ case is also considered
trivial, and only constant values for ‘`a`’ and ‘`b`’ are
recognized. Thus, ‘`lin(2 x y)`’ returns ‘`[0, 2, x y]`’,
‘`lin(2 - x y)`’ returns ‘`[2, -1, x y]`’, and ‘`lin(x y)`’
returns ‘`[0, 1, x y]`’. The `linnt`

function would allow the
first two cases but not the third. Also, neither `lin`

nor
`linnt`

accept plain constants as linear in the one-argument
case: ‘`islin(2,x)`’ is true, but ‘`islin(2)`’ is false.

The ‘`istrue(a)`’ function returns 1 if ‘`a`’ is a nonzero
number or provably nonzero formula, or 0 if ‘`a`’ is anything else.
Calls to `istrue`

can only be manipulated if `m O` mode is
used to make sure they are not evaluated prematurely. (Note that
declarations are used when deciding whether a formula is true;
`istrue`

returns 1 when `dnonzero`

would return 1, and
it returns 0 when `dnonzero`

would return 0 or leave itself
in symbolic form.)