Project

General

Profile

Bug #2365 ยป matrix_coercion.diff

marcandre (Marc-Andre Lafortune), 11/14/2009 10:35 AM

View differences:

lib/matrix.rb
102 102
class Matrix
103 103
  @RCS_ID='-$Id: matrix.rb,v 1.13 2001/12/09 14:22:23 keiju Exp keiju $-'
104 104

  
105
  module CoercionHelper
106
    def apply_through_coercion(obj, oper)
107
      coercion = obj.coerce(self)
108
      raise TypeError unless coercion.is_a? Array && coercion.length == 2
109
      coercion[0].public_send(oper, coercion[1])
110
    rescue
111
      raise TypeError, "#{obj.inspect} can't be coerced into #{self.class}"
112
    end
113
    private :apply_through_coercion
114
  end
115

  
116
  include CoercionHelper
105 117
#  extend Exception2MessageMapper
106 118
  include ExceptionForMatrix
107 119

  
......
483 495
      }
484 496
      return new_matrix rows, m.column_size
485 497
    else
486
      x, y = m.coerce(self)
487
      return x * y
498
      return apply_through_coercion(m, __method__)
488 499
    end
489 500
  end
490 501

  
......
502 513
      m = Matrix.column_vector(m)
503 514
    when Matrix
504 515
    else
505
      x, y = m.coerce(self)
506
      return x + y
516
      return apply_through_coercion(m, __method__)
507 517
    end
508 518

  
509 519
    Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
......
530 540
      m = Matrix.column_vector(m)
531 541
    when Matrix
532 542
    else
533
      x, y = m.coerce(self)
534
      return x - y
543
      return apply_through_coercion(m, __method__)
535 544
    end
536 545

  
537 546
    Matrix.Raise ErrDimensionMismatch unless row_size == m.row_size and column_size == m.column_size
......
562 571
    when Matrix
563 572
      return self * other.inverse
564 573
    else
565
      x, y = other.coerce(self)
566
      return x / y
574
      return apply_through_coercion(other, __method__)
567 575
    end
568 576
  end
569 577

  
......
965 973

  
966 974
  class Scalar < Numeric # :nodoc:
967 975
    include ExceptionForMatrix
976
    include CoercionHelper
968 977

  
969 978
    def initialize(value)
970 979
      @value = value
......
980 989
      when Scalar
981 990
        Scalar.new(@value + other.value)
982 991
      else
983
        x, y = other.coerce(self)
984
        x + y
992
        apply_through_coercion(other, __method__)
985 993
      end
986 994
    end
987 995

  
......
994 1002
      when Scalar
995 1003
        Scalar.new(@value - other.value)
996 1004
      else
997
        x, y = other.coerce(self)
998
        x - y
1005
        apply_through_coercion(other, __method__)
999 1006
      end
1000 1007
    end
1001 1008

  
......
1006 1013
      when Vector, Matrix
1007 1014
        other.collect{|e| @value * e}
1008 1015
      else
1009
        x, y = other.coerce(self)
1010
        x * y
1016
        apply_through_coercion(other, __method__)
1011 1017
      end
1012 1018
    end
1013 1019

  
......
1020 1026
      when Matrix
1021 1027
        self * other.inverse
1022 1028
      else
1023
        x, y = other.coerce(self)
1024
        x.quo(y)
1029
        apply_through_coercion(other, __method__)
1025 1030
      end
1026 1031
    end
1027 1032

  
......
1034 1039
      when Matrix
1035 1040
        other.powered_by(self)
1036 1041
      else
1037
        x, y = other.coerce(self)
1038
        x ** y
1042
        apply_through_coercion(other, __method__)
1039 1043
      end
1040 1044
    end
1041 1045
  end
......
1083 1087
#
1084 1088
class Vector
1085 1089
  include ExceptionForMatrix
1086

  
1090
  include Matrix::CoercionHelper
1087 1091
  #INSTANCE CREATION
1088 1092

  
1089 1093
  private_class_method :new
......
1215 1219
    when Matrix
1216 1220
      Matrix.column_vector(self) * x
1217 1221
    else
1218
      s, x = x.coerce(self)
1219
      s * x
1222
      apply_through_coercion(x, __method__)
1220 1223
    end
1221 1224
  end
1222 1225

  
......
1234 1237
    when Matrix
1235 1238
      Matrix.column_vector(self) + v
1236 1239
    else
1237
      s, x = v.coerce(self)
1238
      s + x
1240
      apply_through_coercion(v, __method__)
1239 1241
    end
1240 1242
  end
1241 1243

  
......
1253 1255
    when Matrix
1254 1256
      Matrix.column_vector(self) - v
1255 1257
    else
1256
      s, x = v.coerce(self)
1257
      s - x
1258
      apply_through_coercion(v, __method__)
1258 1259
    end
1259 1260
  end
1260 1261