Opened 7 years ago
Last modified 5 years ago
#13555 new defect
Doctests of random functions needs to be improved.
Reported by: | JoalHeagney | Owned by: | mvngu |
---|---|---|---|
Priority: | major | Milestone: | sage-6.4 |
Component: | doctest coverage | Keywords: | random, matrices, random_matrix, properties of random objects, properties |
Cc: | Merged in: | ||
Authors: | Reviewers: | ||
Report Upstream: | N/A | Work issues: | |
Branch: | Commit: | ||
Dependencies: | Stopgaps: |
Description
Currently a lot of random functions are skipped during doc-testing, as their results can't be predicted.
However, in ticket #13554, it is clear that errors are slipping through, and properties of random objects should be checked when possible.
For example, in ticket #13554, the generated matrices should at least be tested for the following (if they aren't already):
- Presence of zero entries when method/documentation states that no zero entries should be created, unless density= keyword is used.
- method=echelon_form produces matrices in echelon form.
- method=echelonizable can be echelonized.
- method=unimodular has a determinant of 1.
- method=diagonizable can be diagonalized and eigenvalues are integers.
- 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.)
Change History (12)
comment:1 Changed 7 years ago by
comment:2 Changed 7 years ago by
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.
Fir example, random_unimodular_matrix
tests three very different results for determinant one.
comment:3 Changed 7 years ago by
But if there had been some, the inconsistency between documentation and result would have been spotted a long time ago. The bug that inspired this trac report has been around since 4.7.3. #11968
comment:4 follow-up: ↓ 5 Changed 7 years ago by
This is some code I put together to check matrix values element by element:
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))
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.
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.
comment:5 in reply to: ↑ 4 Changed 7 years ago by
You might consider using all
or any
:
A = random_matrix(ZZ,5); A def checkfunc(matrix, func): return any(func(val)==True for val in matrix.list()) # untested
Also, I'm not sure that there is an iterator for the elements of a matrix. I guess there's one for the rows (mat.__iter__()
), and then I guess for each row there's one (row.iteritems()
). I don't see one for all of the elements, though. (I tried searching the files in the matrix
directory for "yield" and didn't find much.)
comment:6 Changed 7 years ago by
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.
so it should be something like:
lambda x: (x < 4 | x >= 10)
or even better
lambda x: x not in range(4,10)
I did get an iterator-only method for getting elements of a matrix using this:
(A[valrow][valcolm] for valrow in xrange(A.dimensions()[0]) for valcolm in xrange(A.dimensions()[1]))
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.
comment:7 Changed 7 years ago by
Theoretically we could use jhpalmieri's approach thus:
A = random_matrix(ZZ,5); A any((lambda x: x == 0)(val)==True for val in A.list())
to completely avoid defining checkfunc at all. Don't know if this would be an advantage or not during doc-checking.
comment:8 Changed 7 years ago by
Found a way to iterate over elements in a matrix using a generator.
if M is a matrix, then this:
(M[vals[0],vals[1]] for vals in xmrange(M.dimensions()))
will return a generator object that does the job.
comment:9 Changed 6 years ago by
- Milestone changed from sage-5.11 to sage-5.12
comment:10 Changed 5 years ago by
- Milestone changed from sage-6.1 to sage-6.2
comment:11 Changed 5 years ago by
- Milestone changed from sage-6.2 to sage-6.3
comment:12 Changed 5 years ago by
- Milestone changed from sage-6.3 to sage-6.4
Sorry, on the last dot point from the documentation, it should check for the following instead: