Issue #10855 has been updated by Lito Nicolai.


Marc-Andre Lafortune wrote:
> Interesting.
> 
> I'm thinking it might be best to do the conversion even if some entries are not integral. Why do you feel it's best to have uniform types accross a matrix, in particular when would having an Integer instead of a Rational be a problem?

In the Matrix class, scalar divison is implemented by using the usual `/`
operation, which loses precision on `Integer`s but not on `Rational`s. If
the Matrix is a mix of the two, something like this will happen:

    > x = Matrix[[(3/1), 3, 3], [3, (3/1), 3], [3, 3, (3/1)]]
    => # as above
    > x / 2
    => Matrix[[(3/2), 1, 1], [1, (3/2), 1], [1, 1, (3/2)]]

I would find this mixed precision *really* surprising when writing matrix code!
Especially because the loss of precision could be hidden across a number
of matrix, vector, and scalar multiplications.

Actually, that's a good argument for returning rationals in ordinary matrix
scalar division (and changing this patch as you suggest), but that's out of 
line compared to what the rest of Ruby does with division.

----------------------------------------
Bug #10855: [PATCH] Matrix#inverse returns matrix of integers whenever possible
https://bugs.ruby-lang.org/issues/10855#change-51507

* Author: Lito Nicolai
* Status: Open
* Priority: Normal
* Assignee: Marc-Andre Lafortune
* ruby -v: 2.3.0
* Backport: 2.0.0: UNKNOWN, 2.1: UNKNOWN, 2.2: UNKNOWN
----------------------------------------
Currently, Matrix#inverse returns a matrix of Rationals, even when each
element has a denominator of 1. This leads to 

	> x = Matrix.identity 3
	=> Matrix[[1, 0, 0],
                  [0, 1, 0],
                  [0, 0, 1]]

	> x.inverse
	=> Matrix[[(1/1), (0/1), (0/1)],
		  [(0/1), (1/1), (0/1)],
                  [(0/1), (0/1), (1/1)]]

Even though `Matrix.identity.inverse` should be identical to `Matrix.identity`.

This patch guarantees that Matrix#inverse will return a matrix of integers
whenever it can. To maintain uniform types across a matrix, the conversion 
is only performedif *every* element can be converted to an integer.

---Files--------------------------------
matrix_inverse_to_integer.patch (2.14 KB)


-- 
https://bugs.ruby-lang.org/