ruby-core@ruby-lang.org archive (unofficial mirror)
 help / color / mirror / Atom feed
* [ruby-core:68122] [Ruby trunk - Bug #10855] [Open] [PATCH] Matrix#inverse returns matrix of integers whenever possible
       [not found] <redmine.issue-10855.20150215190815@ruby-lang.org>
@ 2015-02-15 19:08 ` lito.nicolai
  2015-02-15 20:15 ` [ruby-core:68123] [Ruby trunk - Bug #10855] " ruby-core
                   ` (4 subsequent siblings)
  5 siblings, 0 replies; 6+ messages in thread
From: lito.nicolai @ 2015-02-15 19:08 UTC (permalink / raw
  To: ruby-core

Issue #10855 has been reported by Lito Nicolai.

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

* Author: Lito Nicolai
* Status: Open
* Priority: Normal
* Assignee: 
* 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/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:68123] [Ruby trunk - Bug #10855] [PATCH] Matrix#inverse returns matrix of integers whenever possible
       [not found] <redmine.issue-10855.20150215190815@ruby-lang.org>
  2015-02-15 19:08 ` [ruby-core:68122] [Ruby trunk - Bug #10855] [Open] [PATCH] Matrix#inverse returns matrix of integers whenever possible lito.nicolai
@ 2015-02-15 20:15 ` ruby-core
  2015-02-15 22:23 ` [ruby-core:68125] " lito.nicolai
                   ` (3 subsequent siblings)
  5 siblings, 0 replies; 6+ messages in thread
From: ruby-core @ 2015-02-15 20:15 UTC (permalink / raw
  To: ruby-core

Issue #10855 has been updated by Marc-Andre Lafortune.

Assignee set to Marc-Andre Lafortune

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?

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

* 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/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:68125] [Ruby trunk - Bug #10855] [PATCH] Matrix#inverse returns matrix of integers whenever possible
       [not found] <redmine.issue-10855.20150215190815@ruby-lang.org>
  2015-02-15 19:08 ` [ruby-core:68122] [Ruby trunk - Bug #10855] [Open] [PATCH] Matrix#inverse returns matrix of integers whenever possible lito.nicolai
  2015-02-15 20:15 ` [ruby-core:68123] [Ruby trunk - Bug #10855] " ruby-core
@ 2015-02-15 22:23 ` lito.nicolai
  2015-02-16 10:42 ` [ruby-core:68126] " eregontp
                   ` (2 subsequent siblings)
  5 siblings, 0 replies; 6+ messages in thread
From: lito.nicolai @ 2015-02-15 22:23 UTC (permalink / raw
  To: ruby-core

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/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:68126] [Ruby trunk - Bug #10855] [PATCH] Matrix#inverse returns matrix of integers whenever possible
       [not found] <redmine.issue-10855.20150215190815@ruby-lang.org>
                   ` (2 preceding siblings ...)
  2015-02-15 22:23 ` [ruby-core:68125] " lito.nicolai
@ 2015-02-16 10:42 ` eregontp
  2015-02-23  0:03 ` [ruby-core:68232] " lito.nicolai
  2015-02-23 16:38 ` [ruby-core:68265] " ruby-core
  5 siblings, 0 replies; 6+ messages in thread
From: eregontp @ 2015-02-16 10:42 UTC (permalink / raw
  To: ruby-core

Issue #10855 has been updated by Benoit Daloze.


Lito Nicolai wrote:
> 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?

It means every operation that follows must go through rational arithmetic which is likely to be slower and more memory hungry, isn't it?
But of course homogeneity also has its value and the code to lower explicitly Rational to Integer is not exactly nice.

> 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.

I would think this is a bug. Matrix division by a scalar should be exact, no?

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

* 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/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:68232] [Ruby trunk - Bug #10855] [PATCH] Matrix#inverse returns matrix of integers whenever possible
       [not found] <redmine.issue-10855.20150215190815@ruby-lang.org>
                   ` (3 preceding siblings ...)
  2015-02-16 10:42 ` [ruby-core:68126] " eregontp
@ 2015-02-23  0:03 ` lito.nicolai
  2015-02-23 16:38 ` [ruby-core:68265] " ruby-core
  5 siblings, 0 replies; 6+ messages in thread
From: lito.nicolai @ 2015-02-23  0:03 UTC (permalink / raw
  To: ruby-core

Issue #10855 has been updated by Lito Nicolai.


Hello! Are there any further thoughts or consensus on which path to take with this?

Here are the options:
1. When dividing matrices, if the resulting matrix has any rational numbers in it, it is entirely rational numbers-- 
even if they have a divisor of 1.
2. When dividing matrices, the result can have a mix of numeric types, even though this can result in a mix of 
precise (rational) and imprecise (integral) division in the next operation.
3. Scalar division of a matrix by an integer is patched to return a rational if needed, removing the loss of 
precision, but breaking with the rest of integral division in Ruby.

I'm happy to write up a patch with any of these changes!

Best,
L

Benoit Daloze wrote:
> Lito Nicolai wrote:
> > 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?
> 
> It means every operation that follows must go through rational arithmetic which is likely to be slower and more memory hungry, isn't it?
> But of course homogeneity also has its value and the code to lower explicitly Rational to Integer is not exactly nice.
> 
> > 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.
> 
> I would think this is a bug. Matrix division by a scalar should be exact, no?



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

* 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/

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [ruby-core:68265] [Ruby trunk - Bug #10855] [PATCH] Matrix#inverse returns matrix of integers whenever possible
       [not found] <redmine.issue-10855.20150215190815@ruby-lang.org>
                   ` (4 preceding siblings ...)
  2015-02-23  0:03 ` [ruby-core:68232] " lito.nicolai
@ 2015-02-23 16:38 ` ruby-core
  5 siblings, 0 replies; 6+ messages in thread
From: ruby-core @ 2015-02-23 16:38 UTC (permalink / raw
  To: ruby-core

Issue #10855 has been updated by Marc-Andre Lafortune.


TBH, I can't think of any legitimate use of `Matrix#/` with integer division.  Anyone?

I never really thought of that, but it's a bit odd that there is no natural way to write `Matrix.I(3) / 2`, say. There's no `quo` method on `Matrix`, so one has to do `Matrix.I(3) / 2r`, `Matrix.I(3) * 0.5r` or `Matrix.diagonal([0.5r] * 3)`.

I'm very tempted to change `/` to act like `quo`.

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

* 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/

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2015-02-23 16:35 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
     [not found] <redmine.issue-10855.20150215190815@ruby-lang.org>
2015-02-15 19:08 ` [ruby-core:68122] [Ruby trunk - Bug #10855] [Open] [PATCH] Matrix#inverse returns matrix of integers whenever possible lito.nicolai
2015-02-15 20:15 ` [ruby-core:68123] [Ruby trunk - Bug #10855] " ruby-core
2015-02-15 22:23 ` [ruby-core:68125] " lito.nicolai
2015-02-16 10:42 ` [ruby-core:68126] " eregontp
2015-02-23  0:03 ` [ruby-core:68232] " lito.nicolai
2015-02-23 16:38 ` [ruby-core:68265] " ruby-core

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).