This is maxima.info, produced by makeinfo version 4.0 from maxima.texi. This is a Texinfo Maxima Manual Copyright 1994,2001 William F. Schelter START-INFO-DIR-ENTRY * Maxima: (maxima). A computer algebra system. END-INFO-DIR-ENTRY  File: maxima.info, Node: Definitions for Miscellaneous Options, Prev: SHARE, Up: Miscellaneous Options Definitions for Miscellaneous Options ===================================== - Variable: ALIASES default: [] atoms which have a user defined alias (set up by the ALIAS, ORDERGREAT, ORDERLESS functions or by DECLAREing the atom a NOUN). - Variable: ALLSYM default: [TRUE] - If TRUE then all indexed objects are assumed symmetric in all of their covariant and contravariant indices. If FALSE then no symmetries of any kind are assumed in these indices. Derivative indices are always taken to be symmetric. - declaration: ALPHABETIC Adds to MACSYMA's alphabet which initially contains the letters A-Z, % and _. Thus, DECLARE("~",ALPHABETIC) enables NEW~VALUE to be used as a name. - Function: APROPOS (string) takes a character string as argument and looks at all the MACSYMA names for ones with that string appearing anywhere within them. Thus, APROPOS(EXP); will return a long list of all the flags and functions which have EXP as part of their names, such as EXPAND, EXP, EXPONENTIALIZE. Thus if you can only remember part of the name of something you can use this command to find the rest of the name. Similarily, you could say APROPOS(TR_); to find a list of many of the switches relating to the TRANSLATOR (most of which begin with TR_). - Function: ARGS (exp) returns a list of the args of exp. I.e. it is essentially equivalent to SUBSTPART("[",exp,0) Both ARGS and SUBSTPART depend on the setting of INFLAG. - Function: DUMMY (i1,i2,...) will set each index i1,i2,... to name of the form !n where n is a positive integer. This guarantees that dummy indices which are needed in forming expressions will not conflict with indices already in use. COUNTER[default 1] determines the numerical suffix to be used in generating the next dummy index. The prefix is determined by the option DUMMYX[!]. - Variable: GENINDEX default: [I] is the alphabetic prefix used to generate the next variable of summation when necessary. - Variable: GENSUMNUM [0] is the numeric suffix used to generate the next variable of summation. If it is set to FALSE then the index will consist only of GENINDEX with no numeric suffix. - Variable: INF - real positive infinity. - Variable: INFINITY - complex infinity, an infinite magnitude of arbitrary phase angle. (See also INF and MINF.) - Variable: INFOLISTS default: [] a list of the names of all of the information lists in MACSYMA. These are: LABELS - all bound C,D, and E labels. VALUES - all bound atoms, i.e. user variables, not MACSYMA Options or Switches, (set up by : , :: , or functional binding). FUNCTIONS - all user defined functions (set up by f(x):=...). ARRAYS - declared and undeclared arrays (set up by : , :: , or :=...) MACROS - any Macros defined by the user. MYOPTIONS - all options ever reset by the user (whether or not they get reset to their default value). RULES - user defined pattern matching and simplification rules (set up by TELLSIMP, TELLSIMPAFTER, DEFMATCH, or, DEFRULE.) ALIASES - atoms which have a user defined alias (set up by the ALIAS, ORDERGREAT, ORDERLESS functions or by DECLAREing the atom a NOUN). DEPENDENCIES - atoms which have functional dependencies (set up by the DEPENDS or GRADEF functions). GRADEFS - functions which have user defined derivatives (set up by the GRADEF function). PROPS - atoms which have any property other than those mentioned above, such as atvalues, matchdeclares, etc. as well as properties specified in the DECLARE function. LET_RULE_PACKAGES - a list of all the user-defined let rule packages plus the special package DEFAULT_LET_RULE_PACKAGE. (DEFAULT_LET_RULE_PACKAGE is the name of the rule package used when one is not explicitly set by the user.) - Function: INTEGERP (exp) is TRUE if exp is an integer else FALSE. - Variable: M1PBRANCH default: [FALSE] - "principal branch for -1 to a power". Quantities such as (-1)^(1/3) [i.e. "odd" rational exponent] and (-1)^(1/4) [i.e. "even" rational exponent] are now handled as indicated in the following chart: DOMAIN:REAL(default) (-1)^(1/3): -1 (-1)^(1/4): (-1)^(1/4) DOMAIN:COMPLEX M1PBRANCH:FALSE(default) M1PBRANCH:TRUE (-1)^(1/3) 1/2+%i*sqrt(3)/2 (-1)^(1/4) sqrt(2)/2+%i*sqrt(2)/2 - Function: NUMBERP (exp) is TRUE if exp is an integer, a rational number, a floating point number or a bigfloat else FALSE. - Function: PROPERTIES (a) will yield a list showing the names of all the properties associated with the atom a. - special symbol: PROPS - atoms which have any property other than those explicitly mentioned in INFOLISTS, such as atvalues, matchdeclares, etc. as well as properties specified in the DECLARE function. - Function: PROPVARS (prop) yields a list of those atoms on the PROPS list which have the property indicated by prop. Thus PROPVARS(ATVALUE) will yield a list of atoms which have atvalues. - Function: PUT (a, p, i) associates with the atom a the property p with the indicator i. This enables the user to give an atom any arbitrary property. - Function: QPUT (a, p, i) is similar to PUT but it doesn't have its arguments evaluated. - Function: REM (a, i) removes the property indicated by i from the atom a. - Function: REMOVE (args) will remove some or all of the properties associated with variables or functions. REMOVE(a1, p1, a2, p2, ...) removes the property pi from the atom ai. Ai and pi may also be lists as with DECLARE. Pi may be any property e.g. FUNCTION, MODE_DECLARE, etc. It may also be TRANSFUN implying that the translated LISP version of the function is to be removed. This is useful if one wishes to have the MACSYMA version of the function executed rather than the translated version. Pi may also be OP or OPERATOR to remove a syntax extension given to ai (see Appendix II). If ai is "ALL" then the property indicated by pi is removed from all atoms which have it. Unlike the more specific remove functions (REMVALUE, REMARRAY, REMFUNCTION, and REMRULE) REMOVE does not indicate when a given property is non-existent; it always returns "DONE". - Function: REMVALUE (name1, name2, ...) removes the values of user variables (which can be subscripted) from the system. If name is ALL then the values of all user variables are removed. Values are those items given names by the user as opposed to those which are automatically labeled by MACSYMA as Ci, Di, or Ei. - Function: RENAME (exp) returns an expression equivalent to exp but with the dummy indices in each term chosen from the set [!1,!2,...]. Each dummy index in a product will be different; for a sum RENAME will try to make each dummy index in a sum the same. In addition, the indices will be sorted alphanumerically. - Function: RNCOMBINE (exp) transforms exp by combining all terms of exp that have identical denominators or denominators that differ from each other by numerical factors only. This is slightly different from the behavior of COMBINE, which collects terms that have identical denominators. Setting PFEFORMAT:TRUE and using COMBINE will achieve results similar to those that can be obtained with RNCOMBINE, but RNCOMBINE takes the additional step of cross-multiplying numerical denominator factors. This results in neater forms, and the possiblity of recognizing some cancellations. Bugs to ASB. - Function: SCALARP (exp) is TRUE if exp is a number, constant, or variable DECLAREd SCALAR, or composed entirely of numbers, constants, and such variables, but not containing matrices or lists. - Function: SCALEFACTORS (coordinatetransform) Here coordinatetransform evaluates to the form [[expression1, expression2, ...], indeterminate1, indeterminat2, ...], where indeterminate1, indeterminate2, etc. are the curvilinear coordinate variables and where a set of rectangular Cartesian components is given in terms of the curvilinear coordinates by [expression1, expression2, ...]. COORDINATES is set to the vector [indeterminate1, indeterminate2,...], and DIMENSION is set to the length of this vector. SF[1], SF[2], ..., SF[DIMENSION] are set to the coordinate scale factors, and SFPROD is set to the product of these scale factors. Initially, COORDINATES is [X, Y, Z], DIMENSION is 3, and SF[1]=SF[2]=SF[3]=SFPROD=1, corresponding to 3-dimensional rectangular Cartesian coordinates. To expand an expression into physical components in the current coordinate system, there is a function with usage of the form - Function: SETUP_AUTOLOAD (file,func1,...,funcN) which takes two or more arguments: a file specification, and one or more function names, "funcI", and which indicates that if a call to "funcI" is made and "funcI" is not defined, that the file specified by "file" is to be automatically loaded in via LOAD, which file should contain a definition for "funcI". (This is the process by which calling e.g. INTEGRATE in a fresh MACSYMA causes various files to be loaded in.) As with the other file-handling commands in MACSYMA, the arguments to SETUP_AUTOLOAD are not evaluated. Example: SETUP_AUTOLOAD("bessel")$ J1(0.0); . Note: SETUP_AUTOLOAD does not work for array functions.  File: maxima.info, Node: Rules and Patterns, Next: Lists, Prev: Miscellaneous Options, Up: Top Rules and Patterns ****************** * Menu: * Introduction to Rules and Patterns:: * Definitions for Rules and Patterns::  File: maxima.info, Node: Introduction to Rules and Patterns, Next: Definitions for Rules and Patterns, Prev: Rules and Patterns, Up: Rules and Patterns Introduction to Rules and Patterns ================================== This section discusses user defined pattern matching and simplification rules (set up by TELLSIMP, TELLSIMPAFTER, DEFMATCH, or, DEFRULE.) You may affect the main simplification procedures, or else have your rules applied explicityly using APPLY1 and APPLY2. There are additional mechanisms for polynomials rules under TELLRAT, and for commutative and non commutative algebra in chapter on AFFINE.  File: maxima.info, Node: Definitions for Rules and Patterns, Prev: Introduction to Rules and Patterns, Up: Rules and Patterns Definitions for Rules and Patterns ================================== - Function: APPLY1 (exp, rule1, ..., rulen) repeatedly applies the first rule to exp until it fails, then repeatedly applies the same rule to all subexpressions of exp, left-to-right, until the first rule has failed on all subexpressions. Call the result of transforming exp in this manner exp'. Then the second rule is applied in the same fashion starting at the top of exp'. When the final rule fails on the final subexpression, the application is finished. - Function: APPLY2 (exp, rule1, ..., rulen) differs from APPLY1 in that if the first rule fails on a given subexpression, then the second rule is repeatedly applied, etc. Only if they all fail on a given subexpression is the whole set of rules repeatedly applied to the next subexpression. If one of the rules succeeds, then the same subexpression is reprocessed, starting with the first rule. MAXAPPLYDEPTH[10000] is the maximum depth to which APPLY1 and APPLY2 will delve. - Function: APPLYB1 (exp, rule1, ..., rulen) is similar to APPLY1 but works from the "bottom up" instead of from the "top down". That is, it processes the smallest subexpression of exp, then the next smallest, etc. MAXAPPLYHEIGHT[10000] - is the maximum height to which APPLYB1 will reach before giving up. - Variable: CURRENT_LET_RULE_PACKAGE default:[DEFAULT_LET_RULE_PACKAGE] - the name of the rule package that is presently being used. The user may reset this variable to the name of any rule package previously defined via the LET command. Whenever any of the functions comprising the let package are called with no package name the value of CURRENT_LET_RULE_PACKAGE is used. If a call such as LETSIMP(expr,rule_pkg_name); is made, the rule package rule_pkg_name is used for that LETSIMP command only, i.e. the value of CURRENT_LET_RULE_PACKAGE is not changed. - Variable: DEFAULT_LET_RULE_PACKAGE - the name of the rule package used when one is not explicitly set by the user with LET or by changing the value of CURRENT_LET_RULE_PACKAGE. - Function: DEFMATCH (progname, pattern, parm1, ..., parmn) creates a function of n+1 arguments with the name progname which tests an expression to see if it can match a particular pattern. The pattern is some expression containing pattern variables and parameters. The parms are given explicitly as arguments to DEFMATCH while the pattern variables (if supplied) were given implicitly in a previous MATCHDECLARE function. The first argument to the created function progname, is an expression to be matched against the "pattern" and the other n arguments are the actual variables occurring in the expression which are to take the place of dummy variables occurring in the "pattern". Thus the parms in the DEFMATCH are like the dummy arguments to the SUBROUTINE statement in FORTRAN. When the function is "called" the actual arguments are substituted. For example: (C1) NONZEROANDFREEOF(X,E):= IF E#0 AND FREEOF(X,E) THEN TRUE ELSE FALSE$ (IS(E#0 AND FREEOF(X,E)) is an equivalent function definition) (C2) MATCHDECLARE(A,NONZEROANDFREEOF(X),B,FREEOF(X))$ (C3) DEFMATCH(LINEAR,A*X+B,X)$ This has caused the function LINEAR(exp,var1) to be defined. It tests exp to see if it is of the form A*var1+B where A and B do not contain var1 and A is not zero. DEFMATCHed functions return (if the match is successful) a list of equations whose left sides are the pattern variables and parms and whose right sides are the expressions which the pattern variables and parameters matched. The pattern variables, but not the parameters, are set to the matched expressions. If the match fails, the function returns FALSE. Thus LINEAR(3*Z+(Y+1)*Z+Y**2,Z) would return [B=Y**2, A=Y+4, X=Z]. Any variables not declared as pattern variables in MATCHDECLARE or as parameters in DEFMATCH which occur in pattern will match only themselves so that if the third argument to the DEFMATCH in (C4) had been omitted, then LINEAR would only match expressions linear in X, not in any other variable. A pattern which contains no parameters or pattern variables returns TRUE if the match succeeds. Do EXAMPLE(DEFMATCH); for more examples. - Function: DEFRULE (rulename, pattern, replacement) defines and names a replacement rule for the given pattern. If the rule named rulename is applied to an expression (by one of the APPLY functions below), every subexpression matching the pattern will be replaced by the replacement. All variables in the replacement which have been assigned values by the pattern match are assigned those values in the replacement which is then simplified. The rules themselves can be treated as functions which will transform an expression by one operation of the pattern match and replacement. If the pattern fails, the original expression is returned. - Function: DISPRULE (rulename1, rulename2, ...) will display rules with the names rulename1, rulename2, as were given by DEFRULE, TELLSIMP, or TELLSIMPAFTER or a pattern defined by DEFMATCH. For example, the first rule modifying SIN will be called SINRULE1. DISPRULE(ALL); will display all rules. - Function: LET (prod, repl, predname, arg1, arg2, ..., argn) defines a substitution rule for LETSIMP such that prod gets replaced by repl. prod is a product of positive or negative powers of the following types of terms: * (1) Atoms which LETSIMP will search for literally unless previous to calling LETSIMP the MATCHDECLARE function is used to associate a predicate with the atom. In this case LETSIMP will match the atom to any term of a product satisfying the predicate. * (2) Kernels such as SIN(X), N!, F(X,Y), etc. As with atoms above LETSIMP will look for a literal match unless MATCHDECLARE is used to associate a predicate with the argument of the kernel. A term to a positive power will only match a term having at least that power in the expression being LETSIMPed. A term to a negative power on the other hand will only match a term with a power at least as negative. In the case of negative powers in "product" the switch LETRAT must be set to TRUE (see below). If a predicate is included in the LET function followed by a list of arguments, a tentative match (i.e. one that would be accepted if the predicate were omitted) will be accepted only if predname(arg1',...,argn') evaluates to TRUE where argi' is the value matched to argi. The argi may be the name of any atom or the argument of any kernel appearing in prod. repl may be any rational expression. If any of the atoms or arguments from prod appear in repl the appropriate substitutions will be made. LETRAT[FALSE] when FALSE, LETSIMP will simplify the numerator and denominator of expr independently and return the result. Substitutions such as N!/N goes to (N-1)! will fail. To handle such situations LETRAT should be set to TRUE, then the numerator, denominator, and their quotient will be simplified in that order. These substitution functions allow you to work with several rulepackages at once. Each rulepackage can contain any number of LETed rules and is referred to by a user supplied name. To insert a rule into the rulepackage name, do LET([prod,repl,pred,arg1,...],name). To apply the rules in rulepackage name, do LETSIMP(expr, name). The function LETSIMP(expr,name1,name2,...) is equivalent to doing LETSIMP(expr,name1) followed by LETSIMP(%,name2) etc. CURRENT_LET_RULE_PACKAGE is the name of the rule package that is presently being used. The user may reset this variable to the name of any rule package previously defined via the LET command. Whenever any of the functions comprising the let package are called with no package name the value of CURRENT_LET_RULE_PACKAGE is used. If a call such as LETSIMP(expr,rule_pkg_name); is made, the rule package rule_pkg_name is used for that LETSIMP command only, i.e. the value of CURRENT_LET_RULE_PACKAGE is not changed. There is a DEFAULT_LET_RULE_PACKAGE which is assumed when no other name is supplied to any of the functions. Whenever a LET includes a rulepackage name that is used as the CURRENT_LET_RULE_PACKAGE. - Variable: LETRAT default: [FALSE] - when FALSE, LETSIMP will simplify the numerator and denominator of expr independently and return the result. Substitutions such as N!/N goes to (N-1)! will fail. To handle such situations LETRAT should be set to TRUE, then the numerator, denominator, and their quotient will be simplified in that order. - Function: LETRULES () displays the rules in the current rulepackage. LETRULES(name) displays the rules in the named rulepackage. The current rulepackage is the value of CURRENT_LET_RULE_PACKAGE The initial value of the rules is DEFAULT_LET_RULE_PACKAGE - Function: LETSIMP (exp) will continually apply the substitution rules previously defined by the function LET until no further change is made to exp. LETSIMP(expr,rule_pkg_name); will cause the rule package rule_pkg_name to be used for that LETSIMP command only, i.e. the value of CURRENT_LET_RULE_PACKAGE is not changed. - Variable: LET_RULE_PACKAGES default:[DEFAULT_LET_RULE_PACKAGE] - The value of LET_RULE_PACKAGES is a list of all the user-defined let rule packages plus the special package DEFAULT_LET_RULE_PACKAGE This is the name of the rule package used when one is not explicitly set by the user. - Function: MATCHDECLARE (patternvar, predicate, ...) associates a predicate with a pattern variable so that the variable will only match expressions for which the predicate is not FALSE. (The matching is accomplished by one of the functions described below). For example after MATCHDECLARE(Q,FREEOF(X,%E)) is executed, Q will match any expression not containing X or %E. If the match succeeds then the variable is set to the matched expression. The predicate (in this case FREEOF) is written without the last argument which should be the one against which the pattern variable is to be tested. Note that the patternvar and the arguments to the predicate are evaluated at the time the match is performed. The odd numbered argument may also be a list of pattern variables all of which are to have the associated predicate. Any even number of arguments may be given. For pattern matching, predicates refer to functions which are either FALSE or not FALSE (any non FALSE value acts like TRUE). MATCHDECLARE(var,TRUE) will permit var to match any expression. - Function: MATCHFIX - MATCHFIX operators are used to denote functions of any number of arguments which are passed to the function as a list. The arguments occur between the main operator and its "matching" delimiter. The MATCHFIX("x",...) function is a syntax extension function which declares x to be a MATCHFIX operator. The default binding power is 180, and the ARGS inside may be anything. (C1) matchfix("|","|"); (D1) "|" (C2) |a|+b; (D2) b + (|a|) (C3) |(a,b)|; (D3) |b| (C4) |[a,b]|; (D4) |[a, b]| (C9) |x|:=IF NUMBERP(x) THEN ABS(x) ELSE (IF LISTP(x) AND APPLY("and",MAP(NUMBERP,x)) THEN SUM(x[i]^2,i,1,LENGTH(x))^0.5 ELSE BUILDQ([u:x],|u|))$ (C10) |[1,2,3]|; (D10) 3.741657386773941 (C18) |-7|; (D18) 7 (C19) |[a,b]|; (D19) |[a, b]| - Function: REMLET (prod, name) deletes the substitution rule, prod -> repl, most recently defined by the LET function. If name is supplied the rule is deleted from the rule package name. REMLET() and REMLET(ALL) delete all substitution rules from the current rulepackage. If the name of a rulepackage is supplied, e.g. REMLET(ALL,name), the rulepackage, name, is also deleted. If a substitution is to be changed using the same product, REMLET need not be called, just redefine the substitution using the same product (literally) with the LET function and the new replacement and/or predicate name. Should REMLET(product) now be called the original substitution rule will be revived. - Function: REMRULE (function, rulename) will remove a rule with the name rulename from the function which was placed there by DEFRULE, DEFMATCH, TELLSIMP, or TELLSIMPAFTER. If rule-name is ALL, then all rules will be removed. - Function: TELLSIMP (pattern, replacement) is similar to TELLSIMPAFTER but places new information before old so that it is applied before the built-in simplification rules. TELLSIMP is used when it is important to modify the expression before the simplifier works on it, for instance if the simplifier "knows" something about the expression, but what it returns is not to your liking. If the simplifier "knows" something about the main operator of the expression, but is simply not doing enough for you, you probably want to use TELLSIMPAFTER. The pattern may not be a sum, product, single variable, or number. RULES is a list of names having simplification rules added to them by DEFRULE, DEFMATCH, TELLSIMP, or TELLSIMPAFTER. Do EXAMPLE(TELLSIMP); for examples. - Function: TELLSIMPAFTER (pattern, replacement) defines a replacement for pattern which the MACSYMA simplifier uses after it applies the built-in simplification rules. The pattern may be anything but a single variable or a number.  File: maxima.info, Node: Lists, Next: Function Definition, Prev: Rules and Patterns, Up: Top Lists ***** * Menu: * Introduction to Lists:: * Definitions for Lists::  File: maxima.info, Node: Introduction to Lists, Next: Definitions for Lists, Prev: Lists, Up: Lists Introduction to Lists ===================== Lists are the basic building block for maxima and lisp. All data types other than arrays, hash tables, numbers are represented as lisp lists, These lisp lists have the form ((mplus) $A 2) to indicate an expression `A+2'. At maxima level one would see the infix notation `A+2'. Maxima also has lists which are printed as [1, 2, 7, x+y] for a list with 4 elements. Internally this corresponds to a lisp list of the form ((mlist) 1 2 7 ((mplus) $X $Y )) The flag which denotes the type field of the maxima expression is a list itself, since after it has been through the simplifier the list would become ((mlist simp) 1 2 7 ((mplus simp) $X $Y))  File: maxima.info, Node: Definitions for Lists, Prev: Introduction to Lists, Up: Lists Definitions for Lists ===================== - Function: APPEND (list1, list2, ...) returns a single list of the elements of list1 followed by the elements of list2,... APPEND also works on general expressions, e.g. APPEND(F(A,B), F(C,D,E)); -> F(A,B,C,D,E). Do EXAMPLE(APPEND); for an example. - Function: ATOM (exp) is TRUE if exp is atomic (i.e. a number or name) else FALSE. Thus ATOM(5) is TRUE while ATOM(A[1]) and ATOM(SIN(X)) are FALSE. (Assuming A[1] and X are unbound.) - Function: CONS (exp, list) returns a new list constructed of the element exp as its first element, followed by the elements of list. CONS also works on other expressions, e.g. CONS(X, F(A,B,C)); -> F(X,A,B,C). - Function: COPYLIST (L) creates a copy of the list L. - Function: DELETE (exp1, exp2) removes all occurrences of exp1 from exp2. Exp1 may be a term of exp2 (if it is a sum) or a factor of exp2 (if it is a product). (C1) DELETE(SIN(X),X+SIN(X)+Y); (D1) Y + X DELETE(exp1, exp2, integer) removes the first integer occurrences of exp1 from exp2. Of course, if there are fewer than integer occurrences of exp1 in exp2 then all occurrences will be deleted. - Function: ENDCONS (exp, list) returns a new list consisting of the elements of list followed by exp. ENDCONS also works on general expressions, e.g. ENDCONS(X, F(A,B,C)); -> F(A,B,C,X). - Function: FIRST (exp) yields the first part of exp which may result in the first element of a list, the first row of a matrix, the first term of a sum, etc. Note that FIRST and its related functions, REST and LAST, work on the form of exp which is displayed not the form which is typed on input. If the variable INFLAG [FALSE] is set to TRUE however, these functions will look at the internal form of exp. Note that the simplifier re-orders expressions. Thus FIRST(X+Y) will be X if INFLAG is TRUE and Y if INFLAG is FALSE. (FIRST(Y+X) gives the same results). - Function: GET (a, i) retrieves the user property indicated by i associated with atom a or returns FALSE if a doesn't have property i. (C1) PUT(%E,'TRANSCENDENTAL,'TYPE); (D1) TRANSCENDENTAL (C2) PUT(%PI,'TRANSCENDENTAL,'TYPE)$ (C3) PUT(%I,'ALGEBRAIC,'TYPE)$ (C4) TYPEOF(EXP) := BLOCK([Q], IF NUMBERP(EXP) THEN RETURN('ALGEBRAIC), IF NOT ATOM(EXP) THEN RETURN(MAPLIST('TYPEOF, EXP)), Q : GET(EXP, 'TYPE), IF Q=FALSE THEN ERRCATCH(ERROR(EXP,"is not numeric.")) ELSE Q)$ (C5) TYPEOF(2*%E+X*%PI); X is not numeric. (D5) [[TRANSCENDENTAL, []], [ALGEBRAIC, TRANSCENDENTAL]] (C6) TYPEOF(2*%E+%PI); (D6) [TRANSCENDENTAL, [ALGEBRAIC, TRANSCENDENTAL]] - Function: LAST (exp) yields the last part (term, row, element, etc.) of the exp. - Function: LENGTH (exp) gives (by default) the number of parts in the external (displayed) form of exp. For lists this is the number of elements, for matrices it is the number of rows, and for sums it is the number of terms. (See DISPFORM). The LENGTH command is affected by the INFLAG switch [default FALSE]. So, e.g. LENGTH(A/(B*C)); gives 2 if INFLAG is FALSE (Assuming EXPTDISPFLAG is TRUE), but 3 if INFLAG is TRUE (the internal representation is essentially A*B^-1*C^-1). - Variable: LISTARITH default: [TRUE] - if FALSE causes any arithmetic operations with lists to be suppressed; when TRUE, list-matrix operations are contagious causing lists to be converted to matrices yielding a result which is always a matrix. However, list-list operations should return lists. - Function: LISTP (exp) is TRUE if exp is a list else FALSE. - Function: MAKELIST (exp,var,lo,hi) returns a list as value. MAKELIST may be called as MAKELIST(exp,var,lo,hi) ["lo" and "hi" must be integers], or as MAKELIST(exp,var,list). In the first case MAKELIST is analogous to SUM, whereas in the second case MAKELIST is similar to MAP. Examples: MAKELIST(CONCAT(X,I),I,1,6) yields [X1,X2,X3,X4,X5,X6] MAKELIST(X=Y,Y,[A,B,C]) yields [X=A,X=B,X=C] - Function: MEMBER (exp, list) returns TRUE if exp occurs as a member of list (not within a member). Otherwise FALSE is returned. Member also works on non-list expressions, e.g. MEMBER(B, F(A,B,C)); -> TRUE. - Function: REST (exp, n) yields exp with its first n elements removed if n is positive and its last -n elements removed if n is negative. If n is 1 it may be omitted. Exp may be a list, matrix, or other expression. - Function: REVERSE (list) reverses the order of the members of the list (not the members themselves). REVERSE also works on general expressions, e.g. REVERSE(A=B); gives B=A. REVERSE default: [FALSE] - in the Plotting functions, if TRUE cause a left-handed coordinate system to be assumed.  File: maxima.info, Node: Function Definition, Next: Program Flow, Prev: Lists, Up: Top Function Definition ******************* * Menu: * Introduction to Function Definition:: * FUNCTION:: * MACROS:: * OPTIMIZATION:: * Definitions for Function Definition::  File: maxima.info, Node: Introduction to Function Definition, Next: FUNCTION, Prev: Function Definition, Up: Function Definition Introduction to Function Definition ===================================  File: maxima.info, Node: FUNCTION, Next: MACROS, Prev: Introduction to Function Definition, Up: Function Definition FUNCTION ======== - To define a function in MACSYMA you use the := operator. E.g. F(X):=SIN(X) defines a function F. Anonmyous functions may also be created using LAMBDA. For example lambda([i,j], ... ) can be used instead of F where F(I,J):=BLOCK([], ... ); MAP(LAMBDA([I],I+1),L) would return a list with 1 added to each term. You may also define a function with a variable number of arguments, by having a final argument which is assigned to a list of the extra arguments: (C8) f([u]):=u; (C9) f(1,2,3,4); (D9) [1, 2, 3, 4] (C11) f(a,b,[u]):=[a,b,u]; (C12) f(1,2,3,4,5,6); (D12) [1, 2, [3, 4, 5, 6]] The right hand side of a function is an expression. Thus if you want a sequence of expressions, you do f(x):=(expr1,expr2,....,exprn); and the value of exprn is what is returned by the function. If you wish to make a `return' from some expression inside the function then you must use `block' and `return'. block([],expr1,...,if(a>10) then return(a),...exprn) is itelf an expression, and so could take the place of the right hand side of a function definition. Here it may happen that the return happens earlier than the last expression. The first `[]' in the block, may contain a list of variables and variable assignments, such as `[a:3,b,c:[]]', which would cause the three variables `a',`b',and `c' to not refer to their global values, but rather have these special values for as long as the code executes inside the `block', or inside functions called from inside the `block'. This is called dynamic binding, since the variables last from the start of the block to the time it exits. Once you return from the `block', or throw out of it, the old values (if any) of the variables will be restored. It is certainly a good idea to protect your variables in this way. Note that the assignments in the block variables, are done in parallel. This means, that if you had used `c:a' in the above, the value of `c' would have been the value of `a' at the time you just entered the block, but before `a' was bound. Thus doing something like block([a:a],expr1,... a:a+3,...exprn) will protect the external value of `a' from being altered, but would let you access what that value was. Thus the right hand side of the assignments, is evaluated in the entering context, before any binding occurs. Using just `block([x],..' would cause the x to have itself as value, just as if it would have if you entered a fresh MAXIMA session. The actual arguments to a function are treated in exactly same way as the variables in a block. Thus in f(x):=(expr1,...exprn); and f(1); we would have a similar context for evaluation of the expressions as if we had done block([x:1],expr1,...exprn) Inside functions, when the right hand side of a definition, may be computed at runtime, it is useful to use `define' and possibly `buildq'.  File: maxima.info, Node: MACROS, Next: OPTIMIZATION, Prev: FUNCTION, Up: Function Definition MACROS ====== - Function: BUILDQ([varlist],expression); EXPRESSION is any single MAXIMA expression and VARLIST is a list of elements of the form `' or `:' Semantics --------- The s in the are evaluated left to right (the syntax is equivalent to :). then these values are substituted into in parallel. If any appears as a single argument to the special form SPLICE (i.e. SPLICE() ) inside , then the value associated with that must be a macsyma list, and it is spliced into instead of substituted. SIMPLIFICATION -------------- The arguments to BUILDQ need to be protected from simplification until the substitutions have been carried out. This code should affect that by using `''. `buildq' can be useful for building functions on the fly. One of the powerful things about MAXIMA is that you can have your functions define other functions to help solve the problem. Further below we discuss building a recursive function, for a series solution. This defining of functions inside functions usually uses `define', which evaluates its arguments. A number of examples are included under `splice'. - Function: SPLICE (atom) This is used with buildq to construct a list. This is handy for making argument lists, in conjunction with BUILDQ MPRINT([X]) ::= BUILDQ([U : x], if (debuglevel > 3) print(splice(u))); Including a call like MPRINT("matrix is ",MAT,"with length",LENGTH(MAT)) is equivalent to putting in the line IF DEBUGLEVEL > 3 THEN PRINT("matrix is ",MAT,"with length", LENGTH(MAT)) A more non trivial example would try to display the variable values AND their names. MSHOW(A,B,C) should become PRINT('A,"=",A,",",'B,"=",B,", and",'C,"=",C) so that if it occurs as a line in a program we can print values. (C101) foo(x,y,z):=mshow(x,y,z); (C102) foo(1,2,3); X = 1 , Y = 2 , and Z = 3 The actual definition of mshow is the following. Note how buildq lets you build 'QUOTED' structure, so that the `'u' lets you get the variable name. Note that in macros, the RESULT is a piece of code which will then be substituted for the macro and evaluated. MSHOW([lis])::=BLOCK([ans:[],N:LENGTH(lis)], FOR i THRU N DO (ans:APPEND(ans, BUILDQ([u:lis[i]], ['u,"=",u])), IF i < N THEN ans :APPEND(ans, IF i < N-1 THEN [","] ELSE [", and"])), BUILDQ([U:ans],PRINT(SPLICE(u)))) The splice also works to put arguments into algebraic operations: (C108) BUILDQ([A:'[B,C,D]],+SPLICE(A)); (D108) D+C+B Note how the simplification only occurs AFTER the substitution, The operation applying to the splice in the first cae is the `+' while in the second it is the `*', yet logically you might thing `splice(a)+splice(A)' could be replaced by `2*splice(A)'. No simplification takes place with the buildq To understand what SPLICE is doing with the algebra you must understand that for MAXIMA, a formula an operation like `A+B+C' is really internally similar to `+(A,B,C)', and similarly for multiplication. Thus `*(2,B,C,D)' is `2*B*C*D' (C114) BUILDQ([A:'[B,C,D]],+SPLICE(A)); (D114) D+C+B (C111) BUILDQ([A:'[B,C,D]],SPLICE(A)+SPLICE(A)); (D111) 2*D+2*C+2*B but (C112) BUILDQ([A:'[B,C,D]],2*SPLICE(A)); (D112) 2*B*C*D Finally the buildq can be invaluable for building recursive functions. Suppose your program is solving a differential equation using the series method, and has determined that it needs to build a recursion relation F[N]:=(-((N^2-2*N+1)*F[N-1]+F[N-2]+F[N-3])/(N^2-N)) and it must do this on the fly inside your function. Now you would really like to add `expand'. F[N]:=EXPAND((-((N^2-2*N+1)*F[N-1]+F[N-2]+F[N-3]) /(N^2-N))); but how do you build this code. You want the `expand' to happen each time the function runs, NOT before it. kill(f), val:(-((N^2-2*N+1)*F[N-1]+F[N-2]+F[N-3])/(N^2-N)), define(f[n],buildq([u:val],expand(u))), does the job. This might be useful, since when you do With the Expand (C28) f[6]; (D28) -AA1/8-13*AA0/180 where as without it is kept unsimplified, and even after 6 terms it becomes: (C25) f[6]; (D25) (5*(-4*(-3*(-2*(AA1+AA0)+AA1+AA0)/2 -(AA1+AA0)/2+AA1) /3 -(-2*(AA1+AA0)+AA1+AA0)/6+(-AA1-AA0)/2) /4 +(-3*(-2*(AA1+AA0)+AA1+AA0)/2 -(AA1+AA0)/2+AA1) /12-(2*(AA1+AA0)-AA1-AA0)/6) /30 The expression quickly becomes complicated if not simplified at each stage, so the simplification must be part of the definition. Hence the `buildq' is useful for building the form.  File: maxima.info, Node: OPTIMIZATION, Next: Definitions for Function Definition, Prev: MACROS, Up: Function Definition OPTIMIZATION ============ When using TRANSLATE and generating code with MACSYMA, there are a number of techniques which can save time and be helpful. Do DEMO("optimu.dem") for a demonstration. In particular, the function FLOATDEFUNK from TRANSL;OPTIMU FASL, creates a function definition from a math-like expression, but it optimizes it (with OPTIMIZE) and puts in the MODE_DECLAREations needed to COMPILE correctly. (This can be done by hand, of course). The demo will only run in a fresh macsyma.