/* [wxMaxima batch file version 1] [ DO NOT EDIT BY HAND! ]*/ /* [ Created with wxMaxima version 19.05.7 ] */ /* [wxMaxima: title start ] Lists [wxMaxima: title end ] */ /* [wxMaxima: comment start ] You saw a couple of lists in the Ch. 1 Intro worksheet: 0101intro.wxm. Now we examine lists in more detail, and probably repeat some comments related to lists. We do so because of the extent to which Maxima relies on lists. Because there are many sections and subsections in this worksheet, you should have the Table of Contents open on the right hand side of your screen. Use the menu on the top of your wxMaxima screen: View, then click on Table of Contents. [wxMaxima: comment end ] */ /* [wxMaxima: section start ] Preface [wxMaxima: section end ] */ /* [wxMaxima: comment start ] 0102Lists.wxm Maxima by Example, Ch. 1, Introduction to Maxima Ted Woollett, Oct 25, 2020. http://web.csulb.edu/~woollett/ We are using the 5.43.0 version of wxMaxima here. (19.05.7) [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] This worksheet 0102Lists.wxm is partly based on the worksheet 0102Lists.wxmx downloaded [ and heavily modified] from the webpage: http://www.wxmaximaecon.com/about-the-book/exercises/ which contains multiple worksheets which supplement the text: Microeconomic Theory and Computation: Applying the Maxima Open-Source Computer Algebra System, by Mike Hammock and Wilson Mixon, Springer, 2013. Their home page, called wxMaxima in Economics, Applying the open-source computer algebra program to economic analysis, is at: http://www.wxmaximaecon.com/ -------------------------------------------------------------------------- [wxMaxima: comment end ] */ /* [wxMaxima: section start ] Maxima Manual and other online resources [wxMaxima: section end ] */ /* [wxMaxima: comment start ] A good summary of Maxima abilities (with examples) can be found in the Maxima Overview webpage by Burkhard Bunk: http://www-com.physik.hu-berlin.de/~bunk/kurs/maxima/maxima.html ------------------------------------------------------------------------------- An excellent 245 page pdf online introduction to Maxima can be found at https://www2.palomar.edu/users/cchamberlin/Math%20205%20pages/Maxima/MaximaBook.pdf -------------------------------------------------------------------------------------- An excellent 52 page pdf with the titile: Multivariable Calculus with Maxima, by G. Jay Kerns, is at http://gkerns.people.ysu.edu/maxima/maximaintro/maximaintro.pdf -------------------------------------------------------------------------------------------- The current Maxima html manual is available at http://maxima.sourceforge.net/docs/manual/maxima_singlepage.html [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] ============================================================== [wxMaxima: comment end ] */ /* [wxMaxima: section start ] Getting Started [wxMaxima: section end ] */ /* [wxMaxima: comment start ] We first set fpprintprec to 4 (ie., bind fpprintprec to 4) [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ fpprintprec; 1.2345678; fpprintprec : 4$ 1.2345678; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] and check on the current state of two of the lists that Maxima maintains: values and functions. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ listp (values); listp (functions); length (values); length (functions); values; functions; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Here you see that the Maxima list values is currently an empty list whose length is zero, and the Maxima list functions is currently a four element list (with length 4). The definition of these functions comes from my personal maxima-init.mac file: [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] * this is c:\Users\wooll\maxima\maxima-init.mac */ maxima_userdir: "c:/work5" $ maxima_tempdir : "c:/work5"$ file_search_maxima : append(["c:/work5/###.{mac,mc}"],file_search_maxima )$ file_search_lisp : append(["c:/work5/###.lisp"],file_search_lisp )$ rnddp(expr,dp):= if floatnump (expr) then float((round(expr*10^dp)/10^dp)) else expr$ rnd_list_dp(alist,dp) := map (lambda([xx], rnddp(xx, dp)), alist)$ rnd_matrix_dp(%Amatrix,dp) := matrixmap (lambda([xx], rnddp(xx, dp) ), %Amatrix)$ print_matrix (AA) := map (lambda([xx], apply ('print,xx)), args(AA))$ [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] which wxMaxima automatically loads when you start a new session. Unless your maxima-init.mac file includes similar definitions, you won't see the same return value from functions. [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] The definitions of any functions you see mentioned in the Maxima list functions can be examined using the Maxima function fundef: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ fundef (rnddp); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Both of the lists values and functions are updated by the Maxima engine whenever new symbol bindings are made and when new functions are defined, as well as when bindings and/or function definitions are excised by using the Maxima function kill. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ a : 10.4$ yy(x) := a*sin (a*x) /(x - 10)$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ values; functions; kill(a, yy)$ values; functions; /* [wxMaxima: input end ] */ /* [wxMaxima: section start ] Reserved Words in Maxima [wxMaxima: section end ] */ /* [wxMaxima: comment start ] Among the many RESERVED WORDS in Maxima, which you should AVOID USING as variable or function names, are: abs, alias, and, args, at, beta, block, box, break, cabs, carg, cf, coeff, col, cons, copy, cos, del, diff, disp, do, else, elseif, end, erf, error, ev, exp, false, fft, fib, fix, float, floor, for, from, functions, get, go, if, ilt, in, inf, integrate, is, lhs, limit, log, map, max, min, minf, mod, next, not, num, op, or, pop, product, psi, put, quit, rat, real, rem, rest, rhs, rk, row, sec, sign, sin, sqrt, some, sort, step, string, sum, tan, tex, then, thru, time, true, unless, values, while, [wxMaxima: comment end ] */ /* [wxMaxima: section start ] Looking up definitions of Maxima core functions [wxMaxima: section end ] */ /* [wxMaxima: comment start ] Let's check on the definition of the Maxima function listp, using the syntax ? listp$ In response you will get the instruction (in red print): Enter space-separated numbers, 'all' or 'none': In response use 0 ( you could also use all ) [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ ? listp$ /* [wxMaxima: input end ] */ /* [wxMaxima: answer start ] */ 0; /* [wxMaxima: answer end ] */ /* [wxMaxima: comment start ] In response you should get: -Function: listp () Returns 'true' if is a list else 'false' [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] You can also look at the latest html version of the Maxima manual at the web address: http://maxima.sourceforge.net/docs/manual/maxima_singlepage.html The default opening display is the Contents display. Instead switch to the Index display. Left-click on the blue word Index on the top line to get the Index display, which has the heading "Function and Variable Index". Then left-click on the letter L. Then use Page-Down key (and Up or Down keys) to get down to the listp area, where you will see two different entries: listp: Functions and Variables for Lists listp: Functions and Variables for linearalgebra left-click on the first entry and you get: -------------------------------------------------------------------- Function: listp (expr) Returns true if expr is a list else false. · Category: Lists · Category: Predicate functions ------------------------------------------------------------------- On the bottom after the word Category, left click on the link labeled Lists and you will be taken to a listing of a large number of Maxima functions which involve lists: Category: Lists · append · assoc · cons · copylist · create_list · delete · eighth · endcons · fifth · first · firstn · flatten · fourth · fullsetify · join · last · lastn · length · listarith · listp · lmax · lmin · lreduce · makelist · member · ninth · permut · permutations · pop · push · random_permutation · rest · reverse · rreduce · second · setify · seventh · sixth · some · sort · sublist · sublist_indices · tenth · third · tree_reduce · xreduce In the Contents display of the Manual, you would go to "Functions and Variables for Lists" section to get the first definition of listp we got above. [wxMaxima: comment end ] */ /* [wxMaxima: section start ] Effects of display2d binding on display of strings, grind, stringp, map, fourth [wxMaxima: section end ] */ /* [wxMaxima: comment start ] Here is a list which includes four strings ( objects enclosed with double quotes) and one floating point number ( a "float"). ["This is", "a list that", "contains", 5.0, "items."] Most of the lists that we use for analysis consist of numbers or symbols bound to numbers. The text strings must be bracketed by double quotes ("). If the 5.0 were so bracketed, it would be treated as a string and would not be available for mathematical manipulation. We bind this list to the name aList. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ aList : ["This is", "a list that", "contains", 5.0, "items."]; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] You access individual elements of the list myL (in general) using the syntax: myL [n] You can also use first, second, third, fourth, fifth, sixth, seventh, eighth, ninth, tenth, and last. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ aList; aList[1]; aList[3]; fourth (aList); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Notice that (assuming default wxMaxima behavior) the output list does not show any double quotes, and you might forget about the string property of most of the list elements. You can use the Maxima function grind to see the dumb text version, which will reveal the double quotes. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ aList[1]; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ grind(%)$ /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Another way to check on the string property is to use stringp (expr) which will return 'true' is expr is a Maxima string, otherwise will return 'false'. [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] We can hope stringp "distributes over lists" [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ stringp (aList); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] and we are not in luck. stringp works find on an expression, like aList[1] [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ stringp (aList[1]); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] To check all five list elements for the string property, we can map the function stringp on all the list elements at once using the map function, which has the general behavior: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ map (f, [a, b, c] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ map (stringp, aList); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] which shows that only the fourth element of aList in NOT a string. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ aList[4]; fourth (aList); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Instead of using grind you can temporarily (or permanently) change the binding of display2d. The default binding of display2d is to the symbol true, and with that default binding (setting) you don't see the double quotes. However, after we change the binding of display2d to the symbol false, all double quotes will be revealed. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ display2d; aList; display2d : false$ aList; display2d : true$ aList; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ display2d; /* [wxMaxima: input end ] */ /* [wxMaxima: section start ] All about π (%e) , float, bfloat, fpprec, numer [wxMaxima: section end ] */ /* [wxMaxima: comment start ] Let's play with %pi, which is how you type in the irrational number π. %pi represents the ratio of the perimeter of a circle to its diameter. The numeric value of %pi is the double-precision floating-point value 3.141592653589793d0. float (expr) converts integers, rational numbers and bigfloats in expr to floating point numbers. In interactive use we can also use command, numer; to get a floating point result. bfloat (expr) converts all numbers and functions of numbers in expr to bigfloat numbers. The number of significant digits in the resulting bigfloats is specified by the global variable fpprec. In interactive use we can also use expr, bfloat; to convert expr to big floats. [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] First we check the current value of fpprec. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ fpprec; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ fpprintprec : 16$ %pi; grind (%)$ float (%pi); %pi, numer; bfloat (%pi); %pi, bfloat; fpprintprec : 4$ float (%pi); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] One use for using big floats (rather than ordinary 16 digit arithmetic floats) is you can carry along more digits in your arithmetic and achieve a more accurate answer in a calculation. The number of digits used depends on the value of fpprec. The default value is 16, as we saw above. [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] Let's temporarily set fpprec to values greater than 16 and look at more digits of %pi. We need to change fpprintprec to have the extra digits all printed out. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ fpprintprec : 0$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ bfloat (%pi); bfloat (%pi), fpprec : 20; bfloat (%pi), fpprec : 30; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We haven't changed the global value of fpprec: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ fpprec; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We need to remember to reset the value of fpprintprec to 4 [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ fpprintprec : 4$ float (%pi); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We discuss the use of big floats in much more detail in Maxima by Example, Ch. 9, Big Floats and High Accuracy Quadrature. [wxMaxima: comment end ] */ /* [wxMaxima: section start ] flatten, flatListp, some [wxMaxima: section end ] */ /* [wxMaxima: comment start ] Thus far we have dealt with simple lists, none of whose elements are themselves lists. The Maxima function flatten (alist) will convert all sublists, subsublists,... into top level elements of alist. Here is an example from the manual: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ flatten ([a, b, [c, [d, e], f], [[g, h]], i, j]); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We can call this result a "flat list." [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] We want to define a function that will return true if a list is a flat list and return false otherwise. We will check 1. is the object a list, and 2. are any of the list elements themselves a list? Don't worry now about completely understanding this definition. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ flatListp (alist) := if listp (alist) and not some (listp, alist) then true else false$ /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Let's first try out this on a simple list. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ flatListp ( [1,2,3,4] ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Next let's try this out on two non-flat lists. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ flatListp ( [1, 2, [3, 4], 5, 6, 7, 8] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ flatListp ( [1, 2, [3, 4], 5, 6, [7, 8] ] ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We can understand how this function works by playing with both listp and 'some' in the above context. [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] First with a flat list [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ listp ( [1,2,3,4] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ some ( listp, [1,2,3,4] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ not some ( listp, [1,2,3,4] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ flatListp ( [1,2,3,4] ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Next with a simple non-flat list [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ listp ( [1, 2, 3, [4, 5], 6] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ some ( listp, [1, 2, 3, [4, 5], 6] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ not some ( listp, [1, 2, 3, [4, 5], 6] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ flatListp ( [1, 2, 3, [4, 5], 6] ); /* [wxMaxima: input end ] */ /* [wxMaxima: section start ] List Arithmetic [wxMaxima: section end ] */ /* [wxMaxima: subsect start ] Addition and Subtraction of Lists, makelist, length, is, equal [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] We can think of a list of length 10 as a vector in a 10 dimensional space. [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] We use the Maxima function makelist to create a list with 10 list elements - a list which has a length of 10. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ V1 : makelist ( j * (%pi / 10), j, 1, 10 ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] The syntax for makelist is (from the manual): The most general form, makelist (expr, i, i_0, i_max, step), returns the list of elements obtained when ev (expr, i=j) is applied to the elements j of the sequence: i_0, i_0 + step, i_0 + 2*step, ..., with |j| less than or equal to |i_max|. The increment step can be a number (positive or negative) or an expression. If it is omitted, the default value 1 will be used. If both i_0 and step are omitted, they will both have a default value of 1. Let's check on omitting i_0 (as well as step): [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ V1 : makelist ( j * (%pi / 10), j, 10 ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We see that we get the same ten element list. Check the length, using the Maxima function length. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ length (V1); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] In interactive use V1, numer; will return a floating point version of the list V1. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ V1, numer; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] or we can use float (list): [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ V1 : float (V1); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We create a second ten element list V2 in floating point form, taking a shortcut: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ V2 : makelist ( j * (%pi / 20), j, 10 ), numer; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ length (V2); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Let V1p2 be the sum V1 + V2 of these two "vectors" [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ V1p2 : V1 + V2; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Let V1m2 be the difference V1 - V2 of these two "vectors" [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ V1m2 : V1 - V2; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] The sum V1p2 + V1m2 should equal 2*V1. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ is (equal (2*V1, V1p2 + V1m2)); /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] Multiplication and Division of Lists by a scalar, log, log10 [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] We can think of a list of three numbers as a specification of a 3-vector. If we multiply the vector by a scalar, the components of the 3-vector all are either increased or decreased. Let's stretch a vector [1,2,3] by a factor of 3: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ 3 * [1, 2, 3]; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] or multiply by (1/3) or equivalently divide by 3: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ [1, 2, 3] / 3; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Of course this property of "distributes over lists" of multiplication works for symbols as well [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ d * [a, b, c]; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ grind (%)$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ [a, b, c] / d; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Here we make sure the symbol f is an unbound symbol. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ kill(f); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] and we can confirm this lack of binding by multiplying f into a list [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ f; f* [a,b,c]; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Let's define a function f(x) which multiplies x by aa and divides the result by bb [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ f(xx) := aa * xx / bb$ /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We can always use the Maxima function fundef to see another kind of display of the function definition: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ fundef (f); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ grind (%)$ /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] or call the function f with a simple unbound symbol as an argument: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ f(x); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] What about using this new function with a list, as in f ( L )? [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ f ([1, 2, 3]); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] If we had to, we could have resorted to using map: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ map (f, [1,2,3] ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We see that our homemade function f distributes over lists automatically, so we can simply use f ( List ) instead of map (f, List). The Maxima core function stringp needs to be mapped onto a list to get string info on each element of the list. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ stringp ( [1, 2, 3] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ map ('stringp, [1,2,3]); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] so we see that stringp does not automatically distribute over lists, so we need to use the map method. [wxMaxima: comment end ] */ /* [wxMaxima: subsubsect start ] math functions distribute over lists [wxMaxima: subsubsect end ] */ /* [wxMaxima: comment start ] Common math functions such as sin, cos, tan, sqrt,... distribute over lists: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ sin ([0.1, 0.3, 0.5]); cos ([0.1, 0.3, 0.5]); tan ([0.1, 0.3, 0.5]); sqrt ([0.1, 0.3, 0.5]); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We now use the kill function to remove the definition of f from Maxima's memory. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ kill(f); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] and confirm that Maxima has forgotten about our definition above [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ f; f * [1, 2, 3]; /* [wxMaxima: input end ] */ /* [wxMaxima: subsubsect start ] log [wxMaxima: subsubsect end ] */ /* [wxMaxima: comment start ] The Maxima function log (expr) returns the natural logarithm (not the log to base 10). [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ aList[3]; log (aList[3]); grind (%)$ aList[4]; log (aList[4]); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Natually, Maxima doesn't know what to do with the natural logarithm of a string! [wxMaxima: comment end ] */ /* [wxMaxima: subsubsect start ] log10 [wxMaxima: subsubsect end ] */ /* [wxMaxima: comment start ] We can define our own log to the base 10 and call it log10 [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ log10 (xx) := log (xx) / log (10)$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ fundef (log10); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] As a check on our definition, we should get log to base 10 (10^3) --> 3 [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ log10 (10^3); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ float(%); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ log10 (10^3), numer; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ log10 ( [10^2, 10^3, 10^4] ), numer; /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] Multiplication of a list by an equal length list [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] If the two lists are the same length, corresponding elements are multiplied together, producing a list of the same length as each of the original lists. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ [a,b] * [c,d]; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ [a,b,c] * [d,e,f]; /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] Division of a list by an equal length list [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] If the two lists are the same length, element a [ m ] of "numerator" is divided by element b [m] of the "denominator", producing a list of the same length as each of the original lists. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ [a,b] / [c,d]; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ [a,b,c] / [d,e,f]; /* [wxMaxima: input end ] */ /* [wxMaxima: section start ] reverse [wxMaxima: section end ] */ /* [wxMaxima: comment start ] You can reverse the order of elements in a list using the Maxima function reverse [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ makelist (j^2, j, 10); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ reverse (%); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ reverse (%); /* [wxMaxima: input end ] */ /* [wxMaxima: section start ] sort, lmin, lmax [wxMaxima: section end ] */ /* [wxMaxima: comment start ] Some examples of using the Maxima sort function with a list: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ sort ([1, a, b, 2, 3, c], 'orderlessp); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sort ([1, a, b, 2, 3, c] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ reverse (%); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sort ([1, a, b, 2, 3, c], 'ordergreatp); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ reverse (%); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ lmin ([1,2,3]); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ lmax ([1,2,3]); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ apply ("+" , [1,2,3] ); /* [wxMaxima: input end ] */ /* [wxMaxima: section start ] Most Useful List Functions (besides length, flatten and reverse) [wxMaxima: section end ] */ /* [wxMaxima: comment start ] If you would like to use any of the non-core functions defined here with your other work with Maxima, you should create a file containing these definitions, and call the file, say, utilities.mac, and place it in your work folder. Then you can place a line like: load(utilities)$ in your maxima-init.mac file, so the definitions in the file will always be loaded when you start a new instance of Maxima. Alternatively, you can just place these definitions in your maxima-init.mac file. [wxMaxima: comment end ] */ /* [wxMaxima: subsect start ] rest [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] Some examples of using the Maxima function rest with a list. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ L1 : makelist (a[j], j, 20); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] rest (L1) returns the list minus the first element, as does rest (L1, 1). [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ rest (L1); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ rest (L1, 1); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] rest (L1, 2) returns the list minus the first two elements. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ rest (L1, 2); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] rest (L1, -1) returns the list minus the last element. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ rest (L1, -1); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] rest (L1, -2) returns the list minus the last two elements. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ rest (L1, -2); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We can use the rest function to define head and tail functions to look at the first few or the last few elements of a list. [wxMaxima: comment end ] */ /* [wxMaxima: subsect start ] head, tail [wxMaxima: subsect end ] */ /* [wxMaxima: input start ] */ head(L) := if listp (L) then rest (L, - (length (L) - 3) ) else error("Input to 'head' must be a list of expressions ")$ declare(head,evfun)$ tail (L) := if listp (L) then rest (L, length (L) - 3 ) else error("Input to 'tail' must be a list of expressions ")$ declare(tail,evfun)$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ head (L1); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ L1, head; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ tail (L1); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ L1, tail; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Look also at the cases that return an error message: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ head (x); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ tail (x); /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] fll - [first, last, length] [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] Another useful function to look at long lists is ffl (alist) which returns the list: [first-element, last-element, length] [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ fll(L) := if listp (L) then [first(L),last(L),length(L)] else error("Input to 'fll' must be a list of expressions ")$ declare (fll, evfun)$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ fll (L1); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ L1, fll; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ fll (x); /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] Lsum, apply [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] We can also define a useful function to sum the elements of a simple flat list, Lsum, using the Maxima function apply. [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] First, here is what apply does: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ gg; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ apply ('gg, [1,2,3,4]); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] ie., causes the elements of the list to become the arguments of the function gg. We are going to apply the multiplication function "+" [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ Lsum (alist) := if flatListp (alist) then apply ( "+", alist) else error("Input to 'Lsum' must be a flat list ")$ /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] and try it out: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ Lsum ( [1,2,3,4] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ [1,2,3,4], Lsum; /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] Lavg [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] The arithmetic unweighted average of a a set of numbers which are the elements of a list can be computed using Lavg(alist), which we define here. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ Lavg (alist) := if flatListp (alist) then float (Lsum (alist) / length (alist) ) else error("Input to 'Lavg' must be a flat list ")$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ Lavg ( [1,2,3,4] ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] You can use the Maxima function mean (and then convert the result to floating point form) to get the same answer. The function mean is defined in the package decriptive, which is automatically loaded when you call a function defined in that package. The descriptive package provides useful functions for descriptive statistical calculations and plots. [wxMaxima: comment end ] */ /* [wxMaxima: subsubsect start ] mean, descriptive, matrix, args [wxMaxima: subsubsect end ] */ /* [wxMaxima: input start ] */ mean ( [1,2,3,4] ), numer; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ fundef (mean); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Better to see this definition in display2d = false form: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ grind (%)$ /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] There is no information about the function listofexpr in the manual, so it must be an undocumented function defined in the package descriptive, located in ...share/descriptive/descriptive.mac. We see four specialized definitions there, one of which is listofexpr. In any case, it is functioning: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ listofexpr ([1,2,3,4] ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] and we can inspect its definition (without looking at descriptive.mac with a text editor): [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ fundef (listofexpr); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We can find next to this definition in descriptive.mac the comment: /* True if the argument is a list containing */ /* no lists, false otherwise. */ [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] The definition of the descriptive package function mean looks very close to our Lavg (except for using float ), but check out what arg (alist) produces: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ args ( [1,2,3,4] ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] So args (alist) --> alist. The descriptive package code for mean uses args because the function mean in meant to be useful for both lists and matrices. Let's see how it works with a 3 x 3 matrix of symbols. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ MM : matrix ([a, b, c], [d, e, f], [g, h, i] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ args (MM); length (MM); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We see that args (aMatrix) has replaced 'matrix' with '[' plus ']' ie., we go from a function to a list of lists. [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] What does apply ("+", MM) do? [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ apply ("+", args (MM) ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We see that the matrix elements of each column are considered separately and added up. We will then divide each sum by the number of rows (3) which is the length of this matrix. This is done using list arithmetic. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ % / 3; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] This should agree with mean (MM): [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ mean (MM); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] This has been an example of "taking apart a function" interactively in order to understand the logic of the function construction. [wxMaxima: comment end ] */ /* [wxMaxima: section start ] intervalsList [wxMaxima: section end ] */ /* [wxMaxima: comment start ] Of course, every list has a length, the number of items in the list. Maxima records this value and assigns it the name length. This fact can be used to divide the interval {0, 1} into a a set of equally long subintervals. Working interactively, we can use the commands n:12$, makelist(k,k,0,n);, and %/(length(%)-1); to create a list of 13 values (0 is included) that show the endpoints of 12 intervals. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ n : 12$ makelist (j, j, 0, n); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ % / ( length (%) - 1); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ float (%); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ length (%); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] The computation above divides the interval [0,1] into twelve (12) equal length intervals via a list with 13 elements. We can define a general function intervalsList (n) which divides the interval [0,1] into n equal length intervals using n+1 list elements. This function definition is a two statement multi-statement definition, which we enclose with parenthses. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ intervalsList (nn) := ( makelist (j, j, 0, nn), %% / ( length (%%) - 1 ) )$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ fundef ( intervalsList ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Here we recover the list dividing [0, 1] into 12 subintervals: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ intervalsList (12); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] and here dividing [0, 1] into 5 equal subintervals: [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ intervalsList (5); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Notice that inside a multi-statement function definition, we use %% to refer to the output of the previous statement. [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] We can convert such an intervals list into an equal division of the interval [0, B] by multiplying the list by the scalar B. Thus to divide the interval [0, 10] into five (5) equal subintervals, we would use 10 * intervalsList (5): [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ 10 * intervalsList (5); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We can convert numbers x in the range [0, 1] into numbers y in the range [A, B] with the transformation y = (B - A) * x + A. In other words, first multiply the list of numbers by (B - A) and then use list arithmetic to add A to each number in the list. [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] Example 1. Convert the interval list over the range [0, 1] into an equal interval list over the range [5, 10]. Here A = 5, B = 10, (B - A) = 5. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ 5 * intervalsList (5) + 5; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Example 2. Convert the interval list over the range [0, 1] into an equal interval list over the range [5, 15]. Here A = 5, B = 15, (B - A) = 10. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ 10 * intervalsList (5) + 5; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sin (%), numer; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] This example shows how you can sample a function at equally spaced intervals, perhaps for plotting a complicated function. Of course, sin(x) is not a complicated function. [wxMaxima: comment end ] */ /* [wxMaxima: section start ] Augmenting and Merging Lists [wxMaxima: section end ] */ /* [wxMaxima: subsect start ] append [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] Use append ([expr], alist ) to create a new list with expr as the first element and the remaining elements those in alist. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ append ( [x], [a,b,c,d] ); append ( [ x, y], [a,b,c,d] ); append ( [ [A, B] ], [a,b,c,d] ); /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] cons [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] Use cons (expr, alist) to create a new list with expr as the first element and the remaining elements those in alist. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ cons (x, [a,b,c,d]); cons ([x,y], [a,b,c,d] ); flatten (%); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] A typical use of cons (in either interactive use or inside a function) is to build up the contents of a list in a way that depends on using a user defined function. Here is an interactive use example. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ myF (x) := sin (x)/x^2$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ myF(1), numer; /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ myL : []$ for j thru 10 do myL : cons ( myF(j^2), myL)$ float (reverse (myL) ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ kill( myF, myL)$ /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] join [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] From the manual: join (l, m) creates a new list containing the elements of lists l and m, interspersed. The result has elements [ l[1], m[1], l[2], m[2], ... ]. The lists l and m may contain any type of elements. If the lists are different lengths, join ignores elements of the longer list. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ join ( [ a[1], a[2], a[3], a[4] ], [ b[1], b[2], b[3] ] ); /* [wxMaxima: input end ] */ /* [wxMaxima: section start ] Even More List Operations [wxMaxima: section end ] */ /* [wxMaxima: subsect start ] listToProd (alist), lists_to_prod (alist) [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] Convert a flat list to a product of list elements. Convert a list of flat lists to a product of list elements. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ listToProd ( alist) := if flatListp (alist) then apply ("*", alist) else (print (" list needs to be a flat list"), done)$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ listToProd ( [a,b,c] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ listToProd ([ [a, b], c, d]); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ lists_to_prod (L) := if flatListp (L) then listToProd (L) else listToProd ( map ( 'listToProd, L) )$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ lists_to_prod ([ [a],[b], [c] ]); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ lists_to_prod ([ [a, b],[ c, d], [ e, f] ]); /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] Select Elements of a New List Based on Some Feature(s) [wxMaxima: subsect end ] */ /* [wxMaxima: subsubsect start ] sublist (alist, property) [wxMaxima: subsubsect end ] */ /* [wxMaxima: comment start ] sublist (list, p) Returns the list of elements of list for which the predicate p returns true. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ sublist ([1,2.0, 3, 4.0], integerp ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sublist ([1,2.0, 3, 4.0], evenp ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sublist ([1,2.0, 3, 4.0], oddp ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sublist ([1,2.0, 3, 4.0], atom ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sublist ([1,2.0, 3, 4.0], listp ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sublist ([1,2.0, 3, 4.0], floatnump ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sublist ([1,2.0, 3, 4.0], constantp ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sublist ([1,2.0, 3, 4.0], numberp ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sublist ([1,2.0, 3, 4.0], stringp ); /* [wxMaxima: input end ] */ /* [wxMaxima: subsubsect start ] unique (alist) [wxMaxima: subsubsect end ] */ /* [wxMaxima: comment start ] unique (L) Returns the unique elements of the list L. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ unique ( [1, %pi, a + b, 2, 1, %e, %pi, a + b, [1] ] ); /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] push (expr, alist) and pop (alist) [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] push (item, list) push prepends the item item to the list list and returns a copy of the new list. The second argument list must be a mapatom that is bound to a list. The first argument item can be any Maxima symbol or expression. If the argument list is not bound to a list, Maxima signals an error. pop (list) pop removes and returns the first element from the list list. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ myL : []; push (x, myL); myL; push (a^2 + b, myL); myL; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We see that, after a use of push, the new list is bound to the name of the original list. pop (alist) pop removes and returns the first element from the list alist. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ myL; pop (myL); myL; pop (myL); myL; /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] We see that after each use of pop, the new list is bound to the name of the original list. [wxMaxima: comment end ] */ /* [wxMaxima: subsect start ] member (expr, alist ), inlist ( alist, expr), lfreeof, freeof [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] from the Manual: member (expr_1, expr_2) Returns true if is(expr_1 = a) for some element a in args(expr_2), otherwise returns false. expr_2 is typically a list, in which case args(expr_2) = expr_2 and is(expr_1 = a) for some element a in expr_2 is the test. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ member (a, [e,f,g,a,b,c] ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ member (a, [e,f,g,[a,b,c] ] ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] A homemade version of member (with the arguments reversed!) is inlist ( alist, AA), which uses lfreeof. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ inlist( alist, AA) := not lfreeof ( alist, AA)$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ inlist ( [e,f,g,a,b,c], a ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ inlist ( [e,f,g,[a,b,c] ], a ); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] From the Manual: lfreeof (list, expr) For each member m of list, calls freeof (m, expr). It returns false if any call to freeof returns false and true otherwise. [wxMaxima: comment end ] */ /* [wxMaxima: subsect start ] pos( alist, A), lfreeof, return, sublist_indices (L, P), lambda [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] pos ( alist, A) returns the list position of the first A in alist or else returns 0 The Maxima function return is used to return 0 is A is not a member of the list, and also used to exit the do loop. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ pos (alist,%AA) := block ( [nloc:0 ], if lfreeof (alist, %AA) then return( 0), for jj thru length (alist) do if alist [jj] = %AA then ( nloc : jj, return() ), nloc )$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ pos ([n1,n2,n3],n1); pos ([n1,n2,n3],n2); pos ([n1,n2,n3],n3); pos ([n1,n2,n3],n4); pos ( [n1,n2,n1,n3,n1], n1); /* [wxMaxima: input end ] */ /* [wxMaxima: comment start ] Let's compare the use of pos (L, x) with the use of the Maxima core function sublist_indices (L, P) [wxMaxima: comment end ] */ /* [wxMaxima: comment start ] sublist_indices (L, P) Returns the indices of the elements x of the list L for which the predicate maybe(P(x)) returns true; this excludes unknown as well as false. P may be the name of a function or a lambda expression. L must be a literal list. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ sublist_indices ( '[n1,n2,n3], lambda ([x] , x = 'n1)); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sublist_indices ( '[n1,n2,n1,n3,n1], lambda ([x] , x = 'n1)); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ sublist_indices ( '[n1,n2,n3], lambda ([x] , x = 'n4)); /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] rpl (alist, k, A), replace k'th element of list alist with A, copylist, integerp [wxMaxima: subsect end ] */ /* [wxMaxima: comment start ] rpl (alist, k, A) returns a list identical to alist, except alist[k] is replaced by A. The function copylist makes a copy of alist and that copy is altered and then returned. [wxMaxima: comment end ] */ /* [wxMaxima: input start ] */ rpl (L, j, x) := if listp (L) and integerp (j) and j > 0 then block ([Lc], Lc : copylist (L), Lc[j] : x, Lc) else (print (" first arg must be a list, second arg must be a positive integer "), done)$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ rpl ([a,b,c,d,e], 3, AA); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ rpl ([a,b,c,d,e], z, AA); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ rpl ([a,b,c,d,e], 3, [ A ]); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ rpl ([a,b,c,d,e], -3, [ A ]); /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] remL1 (alist, n) return copy of alist with alist[n] removed [wxMaxima: subsect end ] */ /* [wxMaxima: input start ] */ remL1 (_aL% ,_mm%) := block ([ln], if integerp (_mm%) and _mm% > 0 then ( ln : length (_aL%), if _mm% > ln then ( disp ("remL1: n > length (list)"), return () ), if _mm% = 1 then rest ( _aL%, 1 ) else if _mm% = ln then rest ( _aL%, -1 ) else flatten ( cons (rest ( _aL%, -(ln - _mm% + 1 ) ), rest ( _aL%, _mm% ) ) ) ) else ( disp (" second arg must be a positive integer"), return (_aL%) ))$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ remL1 ([a,b,c,d,e], 3 ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ remL1 ([a,b,c,d,e], 7 ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ remL1 ([a,b,c,d,e], 3.0 ); /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ remL1 ([a,b,c,d,e], -3 ); /* [wxMaxima: input end ] */ /* [wxMaxima: subsect start ] remL2 (alist, n1, n2) return copy of alist with alist[n1] and alist[n2] removed [wxMaxima: subsect end ] */ /* [wxMaxima: input start ] */ remL2 (%bL,%z1,%z2) := block ([y1,y2,%bbL], if %z1 = %z2 then ( disp ("remL2: %z's are the same"), return (%bL)), if not integerp(%z1) or not integerp(%z2) then ( disp ("remL2: %z's must be integers "), return (%bL)), %bbL : copy (%bL), [y1,y2] : sort ([%z1,%z2]), remL1 (%bbL,y1), remL1 (%%,y2 - 1))$ /* [wxMaxima: input end ] */ /* [wxMaxima: input start ] */ aL : [n1,n2,n3,n4,n5,n6,n7,n8,n9,n10]$ remL2 (aL,3,5); /* [wxMaxima: input end ] */ /* Old versions of Maxima abort on loading files that end in a comment. */ "Created with wxMaxima 19.05.7"$