Sage: Ticket #13555: Doctests of random functions needs to be improved.
https://trac.sagemath.org/ticket/13555
<p>
Currently a lot of random functions are skipped during doc-testing, as their results can't be predicted.
</p>
<p>
However, in ticket <a class="ext-link" href="http://trac.sagemath.org/sage_trac/ticket/13554"><span class="icon"></span>#13554</a>, it is clear that errors are slipping through, and <span class="underline"><strong>properties</strong></span> of random objects should be checked when possible.
</p>
<p>
For example, in ticket <a class="ext-link" href="http://trac.sagemath.org/sage_trac/ticket/13554"><span class="icon"></span>#13554</a>, the generated matrices should at least be tested for the following (if they aren't already):
</p>
<ul><li>Presence of zero entries when method/documentation states that no zero entries should be created, unless density= keyword is used.
</li><li>method=echelon_form produces matrices in echelon form.
</li><li>method=echelonizable can be echelonized.
</li><li>method=unimodular has a determinant of 1.
</li><li>method=diagonizable can be diagonalized and eigenvalues are integers.
</li><li>x= , y= has all entries between x (inclusive) and y (non-inclusive), unless density= keyword is used and 0 isn't between x and y. (In that case entries should be either between x and y, or zero.)
</li></ul>en-usSagehttps://trac.sagemath.org/chrome/site/logo_sagemath_trac.png
https://trac.sagemath.org/ticket/13555
Trac 1.1.6JoalHeagneyMon, 01 Oct 2012 03:24:08 GMT
https://trac.sagemath.org/ticket/13555#comment:1
https://trac.sagemath.org/ticket/13555#comment:1
<p>
Sorry, on the last dot point from the documentation, it should check for the following instead:
</p>
<ul><li>all entries e between x <= e < y, <span class="underline"><strong>not including 0</strong></span> even if 0 is in this range, <strong><span class="underline">unless</span></strong> density= keyword is used.
</li></ul>
TicketrbeezerMon, 01 Oct 2012 03:44:29 GMT
https://trac.sagemath.org/ticket/13555#comment:2
https://trac.sagemath.org/ticket/13555#comment:2
<p>
I think some of the desired tests are performed on the subsidiary methods. There was a desire at the time not to put too much in the main documentation.
</p>
<p>
Fir example, <code>random_unimodular_matrix</code> tests three very different results for determinant one.
</p>
TicketJoalHeagneyMon, 01 Oct 2012 03:53:28 GMT
https://trac.sagemath.org/ticket/13555#comment:3
https://trac.sagemath.org/ticket/13555#comment:3
<p>
But if there had been some additional doctesting, the inconsistency between documentation and result would have been spotted a long time ago. The (duplicate) bug that inspired this trac report has been around since before 4.7.3. <a class="closed ticket" href="https://trac.sagemath.org/ticket/11968" title="defect: bug in documentation of random_matrix (closed: fixed)">#11968</a>
</p>
<p>
If something goes into the documentation, then it should probably be tested there as well, or removed from the documentation. If a change somewhere else then breaks the doctest, then that at least acts as a flag that the documentation needs to be changed.
</p>
TicketJoalHeagneyMon, 01 Oct 2012 04:20:26 GMT
https://trac.sagemath.org/ticket/13555#comment:4
https://trac.sagemath.org/ticket/13555#comment:4
<p>
This is some code I put together to check matrix values element by element:
</p>
<pre class="wiki">A = random_matrix(ZZ,5); A
def checkfunc(matrix, func):
for val in matrix.list():
if func(val) == True:
return True
return False
checkfunc(A, lambda x: x == 0)
A = random_matrix(ZZ,5,x=4,y=10)
checkfunc(A, lambda x: (x >= 4 & x < 10))
</pre><p>
It's been a while since I was an efficient python programmer, so I'm sure someone will show me a generator/list method which is a lot more efficient.
</p>
<p>
I did checkfunc as a function because I was thinking about large matricies and saving memory space (as well as returning on the first match to the conditions). I'm not satisfied with the fact that checkfunc iterates over a list rather than a generator.
</p>
TicketjhpalmieriMon, 01 Oct 2012 05:24:11 GMT
https://trac.sagemath.org/ticket/13555#comment:5
https://trac.sagemath.org/ticket/13555#comment:5
<p>
You might consider using <code>all</code> or <code>any</code>:
</p>
<pre class="wiki">A = random_matrix(ZZ,5); A
def checkfunc(matrix, func):
return any(func(val)==True for val in matrix.list()) # untested
</pre><p>
Also, I'm not sure that there is an iterator for the elements of a matrix. I guess there's one for the rows (<code>mat.__iter__()</code>), and then I guess for each row there's one (<code>row.iteritems()</code>). I don't see one for all of the elements, though. (I tried searching the files in the <code>matrix</code> directory for "yield" and didn't find much.)
</p>
TicketJoalHeagneyMon, 01 Oct 2012 06:15:52 GMT
https://trac.sagemath.org/ticket/13555#comment:6
https://trac.sagemath.org/ticket/13555#comment:6
<p>
I also got the second lambda function incorrect. We're testing if any values are outside the range 4 (inclusive) to 10 exclusive in my example matrix.
</p>
<p>
so it should be something like:
</p>
<pre class="wiki">lambda x: (x < 4 | x >= 10)
</pre><p>
or even better
</p>
<pre class="wiki">lambda x: x not in range(4,10)
</pre><p>
I did get an iterator-only method for getting elements of a matrix using this:
</p>
<pre class="wiki">(A[valrow][valcolm] for valrow in xrange(A.dimensions()[0]) for valcolm in xrange(A.dimensions()[1]))
</pre><p>
But then I realized that since we're only using this function (theoretically) in doc-checking, we probably don't have to worry about memory concerns and iterators versus lists. jhpalmieri's approach seems nice and simple.
</p>
TicketJoalHeagneyMon, 01 Oct 2012 06:21:11 GMT
https://trac.sagemath.org/ticket/13555#comment:7
https://trac.sagemath.org/ticket/13555#comment:7
<p>
Theoretically we could use jhpalmieri's approach thus:
</p>
<pre class="wiki">A = random_matrix(ZZ,5); A
any((lambda x: x == 0)(val)==True for val in A.list())
</pre><p>
to completely avoid defining checkfunc at all. Don't know if this would be an advantage or not during doc-checking.
</p>
TicketJoalHeagneyFri, 02 Nov 2012 23:22:25 GMT
https://trac.sagemath.org/ticket/13555#comment:8
https://trac.sagemath.org/ticket/13555#comment:8
<p>
Found a way to iterate over elements in a matrix using a generator.
</p>
<p>
if M is a matrix, then this:
</p>
<pre class="wiki">(M[vals[0],vals[1]] for vals in xmrange(M.dimensions()))
</pre><p>
will return a generator object that does the job.
</p>
TicketjdemeyerTue, 13 Aug 2013 15:35:53 GMTmilestone changed
https://trac.sagemath.org/ticket/13555#comment:9
https://trac.sagemath.org/ticket/13555#comment:9
<ul>
<li><strong>milestone</strong>
changed from <em>sage-5.11</em> to <em>sage-5.12</em>
</li>
</ul>
Ticketvbraun_spamThu, 30 Jan 2014 21:20:52 GMTmilestone changed
https://trac.sagemath.org/ticket/13555#comment:10
https://trac.sagemath.org/ticket/13555#comment:10
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.1</em> to <em>sage-6.2</em>
</li>
</ul>
Ticketvbraun_spamTue, 06 May 2014 15:20:58 GMTmilestone changed
https://trac.sagemath.org/ticket/13555#comment:11
https://trac.sagemath.org/ticket/13555#comment:11
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.2</em> to <em>sage-6.3</em>
</li>
</ul>
Ticketvbraun_spamSun, 10 Aug 2014 16:51:03 GMTmilestone changed
https://trac.sagemath.org/ticket/13555#comment:12
https://trac.sagemath.org/ticket/13555#comment:12
<ul>
<li><strong>milestone</strong>
changed from <em>sage-6.3</em> to <em>sage-6.4</em>
</li>
</ul>
Ticket