Next: Rewrite Rules, Previous: Summations, Up: Algebra [Contents][Index]
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 using Vectors, 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.)
Next: Rewrite Rules, Previous: Summations, Up: Algebra [Contents][Index]