Feature #10903
closed[PATCH] Matrix#zip returns a matrix
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
=> Matrix[[1, 1], [0, 0], [0, 0], [1, 1]]
And also:
> x.zip x, x # and so on
=> Matrix[[1, 1, 1], [0, 0, 0], [0, 0, 0], [1, 1, 1]]
Files
Updated by hsbt (Hiroshi SHIBATA) over 9 years ago
- Status changed from Open to Assigned
- Assignee set to marcandre (Marc-Andre Lafortune)
Updated by marcandre (Marc-Andre Lafortune) over 9 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) over 9 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) about 7 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?
Updated by marcandre (Marc-Andre Lafortune) about 7 years ago
- Status changed from Assigned to Closed