# generate 2 random but distinct values between LO and HI

a = random(LO,HI,1)

do {b = random(LO,HI,1)} until (a != b)

For whatever it is worth, I think "do ... until (a not-equal b)" is more obviously-correct than "do ... while (a equal b)".

In any event, my initial goal is usually having different magnitudes for problem parameters. If I will allow parameters with different signs, it is usually done with

a *= List_Random(-1,1)

b *= List_Random(-1,1)

after having generated a and b to be distinct and positive. (This lets me avoid having a=-3 and b=3 in situations where that might confuse some students.)

Somewhere between getting 3 and 5 distinct values, I switch to using NchooseK (after loading PGchoicemacros.pl). On the other hand, I will often use an "until [FALSE]" construct when the exclusion is more stringent than merely avoiding duplication.

I have attached code in R to generate a rank-n integer matrix whose inverse is also an integer matrix. The key is the auxiliary function Low(n) which produces a random lower-triangular integer matrix with +/-1 on its diagonal. The main function computes the product of two independent uses of Low(n):

nonSingular(n) = Low(n) * t(Low(n))

I have not explored ways to bound entries in either the generated nonSingular matrix or its inverse. E.g.,

a) use severe bounds for entries in Low(n)

b) impose some sparseness constraints on Low(n)

Note: Evar Nering's text on Linear Algebra has an appendix "Matrices and Inverses with Integral Elements". It begins with two pages discussing procedures and then presents some explicit examples.