Как выполнить сложение векторов в Ruby? - PullRequest
11 голосов
/ 18 июня 2009

Как выполнить сложение векторов в Ruby, чтобы

[100, 100] + [2, 3] 

выходы

[102, 103] 

(вместо объединения двух массивов)?

Или это может быть другой оператор, такой как

[100, 100] @ [2, 3] 

или

[100, 100] & [2, 3]

Ответы [ 6 ]

33 голосов
/ 18 июня 2009

См. Вектор класс:

require "matrix"

x = Vector[100, 100]
y = Vector[2, 3]
print x + y

E:\Home> ruby t.rb
Vector[102, 103]

См. vectorops для дополнительных операций над векторами:

& hellip; следующие операции работают как ожидалось

  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]

См. Также vectorops .

18 голосов
/ 18 июня 2009

Массив # застежка-молния:

$ irb
irb(main):001:0> [100,100].zip([2,3]).map { |e| e.first + e.last }
=> [102, 103]

Короче:

irb(main):002:0> [100,100].zip([2,3]).map { |x,y| x + y }
=> [102, 103]

Обобщено до> 2 измерений с #inject:

irb(main):003:0> [100,100,100].zip([2,3,4]).map { |z| z.inject(&:+) }
=> [102, 103, 104]
3 голосов
/ 18 июня 2009

Когда в Риме .. monkeypatch.

module Enumerable
  def sum
    inject &:+
  end

  def vector_add(*others)
    zip(*others).collect &:sum
  end
end

Тогда вы можете сделать a.vector_add (b), и это работает. Я считаю, что для этого требуется Ruby 1.8.7 или расширение, которое добавляет Symbol.to_proc. Таким способом вы также можете добавить произвольное количество векторов.

3 голосов
/ 18 июня 2009

Или, если вы хотите произвольное поведение измерения этого сорта (например, сложение математического вектора)

 class Vector < Array
   def +(other)
     case other
     when Array
       raise "Incorrect Dimensions" unless self.size == other.size
       other = other.dup
       self.class.new(map{|i| i + other.shift})
     else
       super
     end
   end
 end

class Array
  def to_vector
    Vector.new(self)
  end
end 

[100,100].to_vector + [2,3] #=> [102,103]

Отсутствие карты в стиле lisp довольно неприятно.

2 голосов
/ 23 мая 2014

Если вы (как и я) чувствуете себя неудовлетворенным операциями, которые предоставляются классом Vector по умолчанию из ruby, просто обратите внимание на то, что вы можете взглянуть на мой драгоценный камень https://github.com/psorowka/vectorops, добавив некоторую функциональность, которую я ожидаю из правильной реализации вектора.

0 голосов
/ 18 июня 2009
module PixelAddition
  def +(other)
    zip(other).map {|num| num[0]+num[1]}
  end
end

Затем вы можете создать подкласс Array, который будет смешиваться в модуле, или добавить поведение к определенным массивам, например:

class <<an_array
  include PixelAddition
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...