~kb/matrix

19ffe600d6480e8118111c96107ebbd61d32f688 — Kim Burgess 5 years ago 40d97f8
implement multiplication
2 files changed, 35 insertions(+), 0 deletions(-)

M spec/matrix_spec.cr
M src/matrix.cr
M spec/matrix_spec.cr => spec/matrix_spec.cr +19 -0
@@ 67,6 67,25 @@ describe Matrix do
    end
  end

  describe "#*" do
    a = Matrix(Int32, 2, 2).of 1

    it "supports matrix multiplication" do
      id = Matrix(Int32, 2, 2).identity
      (a * id).should eq(a)
      (id * a).should eq(a)

      c = Matrix(Int32, 2, 3).new { |i| i + 1 }
      d = Matrix(Int32, 3, 2).new { |i| i + 7 }
      e = Matrix(Int32, 2, 2).from StaticArray[58, 64, 139, 154]
      (c * d).should eq(e)
    end

    it "supports scalar multiplication" do
      (a * 2).should eq(Matrix(Int32, 2, 2).of 2)
    end
  end

  describe "#[]" do
    a = Matrix(Int32, 5, 5).new { |idx| idx }


M src/matrix.cr => src/matrix.cr +16 -0
@@ 96,6 96,22 @@ struct Matrix(T, M, N)
    merge(other) { |a, b| a - b }
  end

  # Performs a matrix multiplication with *other*.
  def *(other : Matrix(_, A, B))
    {{ raise("Dimension mismatch, cannot multiply a #{M}x#{N} by a #{A}x#{B}") \
      unless N == A }}

    Matrix(typeof(self[0] * other[0]), M, B).build do |i, j|
      pairs = row(i).zip other.col(j)
      pairs.map(&.product).sum
    end
  end

  # Performs a scalar multiplication with *other*.
  def *(other)
    map { |x| x * other }
  end

  # Retrieves the value of the element at *i*,*j*.
  #
  # Indicies are zero-based. Negative values may be passed for *i* and *j* to