Add "arange" matrix creation
jtanderson opened this issue · comments
This would be useful for creating range-based matrices. The basic functionality is to take a start, end, and delta, and return a row-vector. This should probably mimic the numpy.arange interface.
Here is my first pass at adding this to the Matrix class:
def self.arange(start_val : T, end_val : T, delta = 1.0)
unless (end_val - start_val).sign == delta.sign && delta.abs > 0
raise IndexError.new("Range #{start_val}...#{end_val} invalid with step size #{delta}")
end
GeneralMatrix(T).new(1, ((end_val - start_val).abs.ceil / delta.abs).ceil.to_i) do |i,j|
start_val + j*delta
end
end
One complaint I have with this code so far is that if you do Matrix.arange(5,4,1) it will return [[5]] instead of a {1,0} matrix. It's a matter of adding some extra edge-cases, but I'd like to clean it up to avoid clutter.
Update: after reading/experimenting with numpy.arange
, this version follows it more closely, and is a bit friendlier in general:
def self.arange(start_val : T, end_val : T, delta = 1.0)
return GeneralMatrix(T).new(1,0) unless (end_val - start_val).sign == delta.sign && delta.abs > 0
GeneralMatrix(T).new(1, ((end_val - start_val).abs.ceil / delta.abs).ceil.to_i) do |i,j|
start_val + j*delta
end
end
One departure from numpy.arange
is that if delta: 0
then an empty row will be returned. The numpy
version just allows the inner division throw a ZeroDivisionError exception.
I have this code ready with tests and can submit a pull-request is anybody is around to approve!