How do I perform vector addition in Ruby?
See the Vector class:
require "matrix"
x = Vector[100, 100]
y = Vector[2, 3]
print x + y
E:\Home> ruby t.rb
Vector[102, 103]
See vectorops for additional operations on vectors:
… the following operations work like expected
v1 = Vector[1,1,1,0,0,0]
v2 = Vector[1,1,1,1,1,1]
v1[0..3]
# -> Vector[1,1,1]
v1 += v2
# -> v1 == Vector[2,2,2,1,1,1]
v1[0..3] += v2[0..3]
# -> v1 == Vector[2,2,2,0,0,0]
v1 + 2
# -> Vector[3,3,3,1,1,1]
See also vectorops.
How to sum array of numbers in Ruby?
Try this:
array.inject(0){ |sum, x| sum + x }
See Ruby's Enumerable Documentation
(note: the 0
base case is needed so that 0
will be returned on an empty array instead of nil
)
ruby: sum corresponding members of two or more arrays
Here's the transpose
version Anurag suggested:
[[1,2,3], [4,5,6]].transpose.map {|x| x.reduce(:+)}
This will work with any number of component arrays. reduce
and inject
are synonyms, but reduce
seems to me to more clearly communicate the code's intent here...
How do I add columns and rows to a Matrix in Ruby?
Since doing this isn't (so far as I know) a valid matrix operation in the mathematical sense, there's nothing to do this in place. You can create a new Matrix though:
m = Matrix.diagonal(1, 2, 3)
#=> Matrix[[1, 0, 0], [0, 2, 0], [0, 0, 3]]
Matrix.columns(m.to_a << [4, 5, 6])
#=> Matrix[[1, 0, 0, 4], [0, 2, 0, 5], [0, 0, 3, 6]]
Matrix.rows(m.to_a << [4, 5, 6])
#=> Matrix[[1, 0, 0], [0, 2, 0], [0, 0, 3], [4, 5, 6]]
This uses columns
or rows
to create a new matrix by adding a new array
to the array representation of the original matrix.
Algorithm implemented in ruby to add one to a number represented as an array
while new_number > 0
result.push new_number%10
new_number /= 10
end
Even though at first glance this loop seems to be O(n)
, it is at least Ω(n²)
.
Since big numbers in Ruby are stored and processed as arrays of binary digits (digits in base 2³²), division by 10
is a costly operation. The exact time complexity depends on the division algorithm Ruby uses, but new_number /= 10
will have to process all of the new_number
's binary digits, so it cannot be faster than O(n)
.
What's the efficient way to multiply two arrays and get sum of multiplied values in Ruby?
Update
I've just updated benchmarks according to new comments. Following Joshua's comment, the inject method will gain a 25% speedup, see array walking without to_a
in the table below.
However since speed is the primary goal for the OP we have a new winner for the contest which reduces runtime from .34
to .22
in my benchmarks.
I still prefer inject
method because it's more ruby-ish, but if speed matters then the while loop seems to be the way.
New Answer
You can always benchmark all these answers, I did it for curiosity:
> ./matrix.rb
Rehearsal --------------------------------------------------------------
matrix method 1.500000 0.000000 1.500000 ( 1.510685)
array walking 0.470000 0.010000 0.480000 ( 0.475307)
array walking without to_a 0.340000 0.000000 0.340000 ( 0.337244)
array zip 0.590000 0.000000 0.590000 ( 0.594954)
array zip 2 0.500000 0.000000 0.500000 ( 0.509500)
while loop 0.220000 0.000000 0.220000 ( 0.219851)
----------------------------------------------------- total: 3.630000sec
user system total real
matrix method 1.500000 0.000000 1.500000 ( 1.501340)
array walking 0.480000 0.000000 0.480000 ( 0.480052)
array walking without to_a 0.340000 0.000000 0.340000 ( 0.338614)
array zip 0.610000 0.010000 0.620000 ( 0.625805)
array zip 2 0.510000 0.000000 0.510000 ( 0.506430)
while loop 0.220000 0.000000 0.220000 ( 0.220873)
Simple array walking wins, Matrix method is worse because it includes object instantiation. I think that if you want to beat the inject
while
method (to beat here means an order of magnitude fastest) you need to implement a C
extension and bind it in your ruby program.
Here it's the script I've used
#!/usr/bin/env ruby
require 'benchmark'
require 'matrix'
array_A = [1, 2, 1, 4, 5, 3, 2, 6, 5, 8, 9]
array_B = [3, 2, 4, 2, 5, 1, 3, 3, 7, 5, 4]
def matrix_method a1, a2
(Matrix.row_vector(a1) * Matrix.column_vector(a2)).element(0,0)
end
n = 100000
Benchmark.bmbm do |b|
b.report('matrix method') { n.times { matrix_method(array_A, array_B) } }
b.report('array walking') { n.times { (0...array_A.count).to_a.inject(0) {|r, i| r + array_A[i]*array_B[i]} } }
b.report('array walking without to_a') { n.times { (0...array_A.count).inject(0) {|r, i| r + array_A[i]*array_B[i]} } }
b.report('array zip') { n.times { array_A.zip(array_B).map{|i,j| i*j }.inject(:+) } }
b.report('array zip 2') { n.times { array_A.zip(array_B).inject(0) {|r, (a, b)| r + (a * b)} } }
b.report('while loop') do
n.times do
sum, i, size = 0, 0, array_A.size
while i < size
sum += array_A[i] * array_B[i]
i += 1
end
sum
end
end
end
Related Topics
Ruby on Rails Map.Root Doesn't Seem to Be Working
Catching Timeout Errors with Ruby Mechanize
How to Fix a Slow Implicit Query on Pg_Attribute Table in Rails
Rails Devise - Current_User Is Nil
How to Convert a Scientific Notation String to Decimal Notation
How to Change Passenger Ruby Version Without Recompiling
How to Split String into Array as Integers
How to Read a Gzip File Line by Line
Is It Necessary to Close Stringio in Ruby
Stack Level Too Deep When Using Carrierwave Versions
Error "Undefinded Method "Load_Defaults" " When Trying to Deploy App on Heroku
Duplicating a Ruby Array of Strings
Ruby - Does Array a Contain All Elements of Array B
Ruby on Rails: How to Use Oauth2::Accesstoken.Post
/Usr/Bin/Env Ruby_Noexec_Wrapper Fails with No File or Directory
Understanding Precedence of Assignment and Logical Operator in Ruby