STACK Documentation

Documentation home | Category index | Parent | Site map

Random objects

STACK can generate structured random objects. STACK provides a Maxima function rand() which can be used in the question and answer variables.

Note: it is important not to use Maxima's own random() function. STACK creates pseudo-random numbers from a definite seed. This ensures that when a particular student returns they see the same version of the question. Hence, STACK provides its own function rand().

For the purposes of learning and teaching, we do not need an algorithm which is statistically perfect. We are much more interested in simplicity, efficiency and reproducibility across platforms. Hence, we adopt a linear recurrence method of generating pseudo-random numbers.

rand()

  • rand(n) generates an integer between \(0\) and \(n-1\).
  • rand(n.0) generates a floating point number between \(0\) and \(n\). It is probably more useful to use something like a=float(rand(1000)/1000) to obtain an accurate number of decimal places. An alterative is to use the Maxima function round()
  • rand([a,b,...,z]) makes a random selection from a list.
  • rand(matrix(..)) applies rand to each element of the matrix.

It is probably much better not to use conditional statements when creating random objects. For example, if you would like to create a random small prime number, try

p : rand([2,3,5,7,11,13,17,19]);

This might not appear to be the neatest mathematical solution, but it is probably the most reliable. Usually we need to combine rand() with some code to generate objects. For example, if you want a matrix with integer elements in the range -5..5 you need something like

A:matrix([5,5],[5,5])-rand(matrix([11,11],[11,11]));

rand_with_step(lower,upper,step)

Returns a random number from the set {lower, lower+step, lower+2*step, ... , final}. The examples below explain behaviour the best. Examples:

  • rand_with_step(-5,5,1) returns a random number from the set \(\{-5,-4,-3,-2,-1,0,1,2,3,4,5\}\).
  • rand_with_step(-5,5,2) returns a random number from the set \(\{-5,-3,-1,1,3,5\}\).
  • rand_with_step(-5,3,3) returns a random number from the set \(\{-5,-2,1\}\).

The function rand_range(lower,upper,step) does the same thing.

rand_with_prohib(lower,upper,list)

Returns a random integer from the set [lower,upper] such that it cannot be any value in list. This list can include values which are also random variables, for example, generated by rand_with_step. Examples:

  • rand_with_prohib(-5,5,[0]) returns a random number from the set \(\{-5,-4,-3,-2,-1,1,2,3,4,5\}\).
  • rand_with_prohib(-5,5,[-1,0,1,sqrt(pi)]) returns a random number from the set \(\{-5,-4,-3,-2,2,3,4,5\}\).
  • rand_with_prohib(-5,3,[-5/2,a]) returns a random number from the set \(\{-5,-4,-3,-2,-1,0,1,2,3\}\backslash\{a\}\).

This can be used with matrices, to generate a matrix with non-zero entries for example. The unnamed function in this example ignores its arguments.

matrixmap(lambda([ex],rand_with_prohib(-5,5,[0])),zeromatrix(5,5));

rand_selection(ex, n)

Returns a list containing a random selection of n different items from the list ex. If ex contains duplicates, then the result may also contain duplicates.

Generating random polynomials

Here is an example which generates a random polynomial, of degree 5, with coefficients between 0 and 6.

apply("+",makelist(rand(7)*x^(k-1),k,6));

Generating random expressions which needs to be "gathered and sorted".

It is relatively common to want to be able to generate random expressions which need to be "gathered and sorted". For example in \(2y-y+3y+1\) we need to collect together the \(y\) terms.

simp:false;
p:apply("+",makelist(ev(rand_with_prohib(-5,5,[0])*y^rand(2),simp), ev(rand(6)+2,simp)));
p:unary_minus_sort(p);

Now, the output from the first expression will be a random expression in constants and \(y\) variables. The second line tidies up the unary minus. For more details of this, see simplification.

4*y+5*y+(-2*y)
4*y+5*y-2*y

Random objects with corresponding information.

It is often necessary to generate a random object with a number of separate aspects to it. For example, if you have scientific data and you need to include this in a question.

t:rand(5)+3;
idx:rand(3)+1;  /* Array indexes in Maxima start at 1, rand(n) returns 0,...,n-1.  */
l1:["Mercury","Earth","Mars"];
l2:[3.61,9.8,3.75];
p:l1[idx];
ta:t*l2[idx]/(4*%pi^2);

The question text can then be

A pendulum is located on {@p@}. What length should the pendulum have in order to have a period of {@t@}s?

This indexing with the variable idx is quite robust. Note that indexes in Maxima start at \(1\), whereas rand(n) could return zero.

See also

Maxima reference topics.


Documentation home | Category index | Parent | Site map