Project

General

Profile

Feature #10903

[PATCH] Matrix#zip returns a matrix

Added by LitoNico (Lito Nicolai) over 4 years ago. Updated almost 2 years ago.

Status:
Closed
Priority:
Normal
Target version:
-
[ruby-core:68293]

Description

Currently:
> x = Matrix.I 2
> x.zip x
=> 1, 1], [0, 0], [0, 0], [1, 1 # It's an array!

With the patch:
> x.zip x
=> Matrix1, 1], [0, 0], [0, 0], [1, 1

And also:
> x.zip x, x # and so on
=> Matrix1, 1, 1], [0, 0, 0], [0, 0, 0], [1, 1, 1


Files

matrix_zip.patch (1.42 KB) matrix_zip.patch LitoNico (Lito Nicolai), 02/25/2015 04:43 AM

History

#1

Updated by hsbt (Hiroshi SHIBATA) over 4 years ago

  • Status changed from Open to Assigned
  • Assignee set to marcandre (Marc-Andre Lafortune)
#2

Updated by marcandre (Marc-Andre Lafortune) over 4 years ago

  • Tracker changed from Bug to Feature

Hi, sorry I missed your proposal until now, and thanks for the patch.

Could you explain in what kind of circumstances one would use this? I'm not sure I see what kind of mathematical operation this can correspond to.

Updated by LitoNico (Lito Nicolai) about 4 years ago

Marc-Andre Lafortune wrote:

Hi, sorry I missed your proposal until now, and thanks for the patch.

Could you explain in what kind of circumstances one would use this? I'm not sure I see what kind of mathematical operation this can correspond to.

No worries! Thanks for taking a look.

Matrix#zip is useful for simply implementing any binary (or n-ary) operation on matrices.

For instance, when I wrote this patch, I was working with matrices of binary numbers— if I wanted to elementwise AND the matrices, here are two ways to do it:

Pre-patch:
def & other
Matrix.build(self.row_count){|i, j| self[i, j] & other[i, j] }
end

With patch:
def & other
Matrix.zip(other).map{|a, b| a&b}
end

I like that this allows for a more Matrix-native coding style, much like Numpy matrices
or even APL arrays. Finding the elementwise max/min, the Hadamard product, and
(with a ‘pad-with-zeros’ function) Matrix convolution are all simpler in this notation.

Edit: I'm using this function as a zipWith rather than a zip, but I submitted zip because its use is a bit broader and it kept the spirit of Matrix implementing Enumerable.

Best,
Lito

Updated by marcandre (Marc-Andre Lafortune) almost 2 years ago

Wow, time flies. Sorry for not addressing this earlier.

I have some commits ready to address this: https://github.com/ruby/ruby/pull/1746

Naming: The issue I have with zip is not really the potential incompatibility, but that the builtin zip (at least in my head) does a kind of transposition, while it wouldn't for matrices (or it would do two, if you want to see it this way). Also, Array#zip is lax on sizes (you can zip arrays of different sizes). Finally, I would imagine that the result of zip for Matrices will always be chained with map, while Array#zip has other uses (keys.zip(values).to_h).

So I'm proposing combine instead, that takes a block (or returns an Enumerable).

What do you think?

#5

Updated by marcandre (Marc-Andre Lafortune) almost 2 years ago

  • Status changed from Assigned to Closed

Also available in: Atom PDF