Ticket #5142 (closed defect: fixed)

Opened 4 years ago

Last modified 4 years ago

[with patch, positive review] speed up elementary_divisors for sparse integer matrices?

Reported by: jhpalmieri Owned by: jhpalmieri
Priority: critical Milestone: sage-3.3
Component: linear algebra Keywords: sparse, elementary_divisors
Cc: Work issues:
Report Upstream: Reviewers:
Authors: Merged in:
Dependencies: Stopgaps:

Description

It seems to me that if mat is a sparse integer matrix, then

mat.dense_matrix().elementary_divisors()

is much faster than

mat.elementary_divisors()

Is this correct? I've checked this on certain families of matrices, but probably not extensively enough.

If so, we should change how elementary divisors for sparse integer matrices are computed. I've patched this, pretty naively, by sticking a new method in matrix_integer_sparse.pyx which just contains the above code. I would appreciate any comments or corrections.

Attachments

5142.patch Download (1.9 KB) - added by jhpalmieri 4 years ago.
5142-rebased.patch Download (1.9 KB) - added by jhpalmieri 4 years ago.
rebased against 3.3.alpha6
5142-new.patch Download (3.1 KB) - added by jhpalmieri 4 years ago.
only apply this patch

Change History

Changed 4 years ago by jhpalmieri

comment:1 Changed 4 years ago by jhpalmieri

This is a simple patch, but may raise complicated issues:

Here's the situation, as I see it: the code for sparse matrices needs a lot of work, and the particular problem on this ticket is one symptom of this. Right now, if you call elementary_divisors on a sparse matrix, it will likely take a long time, and might even crash. The patch proposes a fix to this -- converting to a dense matrix first. This will crash, too, for some matrices; I'm guessing that it will crash for strictly fewer matrices than elementary_divisors will. Therefore this patch is not a terrible idea.

It is rather makeshift, though. The right thing to do is to rewrite the sparse matrix code so that it works and is faster (and also less buggy -- see #5099, for instance).

This patch would be a temporary fix. Is it a good idea to include this now, with the idea to fix it the right way later? Or is it better to leave less than ideal code there now, first as an encouragement to fix it, and second so that we don't leave a patch like this in as a longterm solution?

comment:2 Changed 4 years ago by mabshoff

  • Milestone changed from sage-3.4.1 to sage-3.3

Another simple fix that ought to be in 3.3.

Cheers,

Michael

comment:3 Changed 4 years ago by jhpalmieri

  • Owner changed from was to jhpalmieri

comment:4 Changed 4 years ago by mabshoff

  • Summary changed from [with patch, needs review] speed up elementary_divisors for sparse integer matrices? to [with patch, needs review, needs rebase] speed up elementary_divisors for sparse integer matrices?
  • Milestone changed from sage-3.3 to sage-3.4.1

Hi John,

this patch does not apply to my 3.3.rc0 merge tree. Please try to rebase it against 3.3.alpha6:

sage-3.3.rc0/devel/sage$ patch -p1 < trac_5142.patch 
patching file sage/matrix/matrix_integer_sparse.pyx
Hunk #1 FAILED at 296.
1 out of 1 hunk FAILED -- saving rejects to file sage/matrix/matrix_integer_sparse.pyx.rej

Cheers,

Michael

Changed 4 years ago by jhpalmieri

rebased against 3.3.alpha6

comment:5 Changed 4 years ago by jhpalmieri

The new patch is just a rebase against 3.3.alpha6.

comment:6 Changed 4 years ago by jhpalmieri

  • Summary changed from [with patch, needs review, needs rebase] speed up elementary_divisors for sparse integer matrices? to [with patch, needs review] speed up elementary_divisors for sparse integer matrices?

comment:7 Changed 4 years ago by AlexGhitza

  • Summary changed from [with patch, needs review] speed up elementary_divisors for sparse integer matrices? to [with patch, needs work] speed up elementary_divisors for sparse integer matrices?

The patch looks good; I have three complaints regarding the docstring:

  • in the description of the algorithm 'pari', you presumably mean "works robustly", since "works robustless" doesn't mean anything
  • this is a one-line method, and it is pretty self-explanatory, so I don't think it needs a description of the implementation in the docstring
  • the OUTPUT description claims that the method returns a list of int's; this is not true, since the output is a list of Integer's

I'll very happily give this a positive review once these issues are resolved. This patch is a good idea and, as John points out, similar things should be done for other methods for sparse matrices (determinant is another example). For the record, trying

sage: A = random_matrix(ZZ, 100, 100, sparse=True)
sage: time e = A.elementary_divisors()

simply fails with a mysterious TypeError in the current code, whereas with the patch applied it works in 1.44 seconds.

Changed 4 years ago by jhpalmieri

only apply this patch

comment:8 Changed 4 years ago by jhpalmieri

Thanks for the comments. Here is a new patch which addresses them.

It also makes another change: my docstring for elementary_divisors was just copied from the docstring for the version in matrix_integer_dense, so since you pointed out the issues with my new docstring, I thought I should change that one, too. I made one change to the old docstring in addition to the ones you suggested: I deleted the paragraph which suggests that we use linbox. (We haven't used linbox for elementary_divisors for almost two years.)

comment:9 Changed 4 years ago by jhpalmieri

  • Summary changed from [with patch, needs work] speed up elementary_divisors for sparse integer matrices? to [with patch, needs review] speed up elementary_divisors for sparse integer matrices?

comment:10 Changed 4 years ago by AlexGhitza

  • Priority changed from minor to critical
  • Summary changed from [with patch, needs review] speed up elementary_divisors for sparse integer matrices? to [with patch, positive review] speed up elementary_divisors for sparse integer matrices?
  • Milestone changed from sage-3.4.1 to sage-3.3

Good stuff.

I'm upgrading this to a critical bug, due to the fact that it's not just a question of speed, but it also fails (see the example above).

comment:11 Changed 4 years ago by mabshoff

  • Status changed from new to closed
  • Resolution set to fixed

Merged in Sage 3.3.rc0.

Cheers,

Michael

comment:12 Changed 4 years ago by mabshoff

As John pointed out in  http://groups.google.com/group/sage-devel/t/312339a77bf58908: I merged 5142-rebased.patch instead of 5142-new.patch. So I reverted 5142-rebased.patch and merged 5142-new.patch in 3.3.rc1. Sorry for the screwup.

Cheers,

Michael

Note: See TracTickets for help on using tickets.