~ubuntu-branches/ubuntu/trusty/ruby1.9/trusty

« back to all changes in this revision

Viewing changes to lib/matrix.rb

  • Committer: Bazaar Package Importer
  • Author(s): Lucas Nussbaum
  • Date: 2006-05-08 22:23:12 UTC
  • mfrom: (1.1.2 upstream)
  • Revision ID: james.westby@ubuntu.com-20060508222312-w2wqeaz030ifi59j
Tags: 1.9.0+20060423-3ubuntu1
* Resynchronized with Debian.
* Only change from Debian is the addition of
  debian/patches/903_sparc_fix_define.patch to fix illegal instructions
  at runtime on sparc. (change from 1.9.0+20050921-1ubuntu1)

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
#!/usr/local/bin/ruby
2
2
#--
3
3
#   matrix.rb - 
4
 
#       $Release Version: 1.0$
5
 
#       $Revision: 1.11 $
6
 
#       $Date: 1999/10/06 11:01:53 $
 
4
#       $Release Version: 1.0$
 
5
#       $Revision: 1.13 $
 
6
#       $Date: 2001/12/09 14:22:23 $
7
7
#       Original Version from Smalltalk-80 version
8
8
#          on July 23, 1985 at 8:37:17 am
9
9
#       by Keiju ISHITSUKA
105
105
# * <tt> #inspect                       </tt>
106
106
#
107
107
class Matrix
108
 
  @RCS_ID='-$Id: matrix.rb,v 1.11 1999/10/06 11:01:53 keiju Exp keiju $-'
 
108
  @RCS_ID='-$Id: matrix.rb,v 1.13 2001/12/09 14:22:23 keiju Exp keiju $-'
109
109
  
110
110
#  extend Exception2MessageMapper
111
111
  include ExceptionForMatrix
246
246
  # use to general users.
247
247
  #
248
248
  def initialize(init_method, *argv)
249
 
    self.send(init_method, *argv)
 
249
    self.funcall(init_method, *argv)
250
250
  end
251
251
  
252
252
  def init_rows(rows, copy)
265
265
  def [](i, j)
266
266
    @rows[i][j]
267
267
  end
 
268
  alias element []
 
269
  alias component []
 
270
 
 
271
  def []=(i, j, v)
 
272
    @rows[i][j] = v
 
273
  end
 
274
  alias set_element []=
 
275
  alias set_component []=
 
276
  private :[]=, :set_element, :set_component
268
277
 
269
278
  #
270
279
  # Returns the number of rows.
320
329
  #
321
330
  # Returns a matrix that is the result of iteration of the given block over all
322
331
  # elements of the matrix.
323
 
  #   Matrix[ [1,2], [3,4] ].collect { |i| i**2 }
 
332
  #   Matrix[ [1,2], [3,4] ].collect { |e| e**2 }
324
333
  #     => 1  4
325
334
  #        9 16
326
335
  #
602
611
      
603
612
      for i in 0 .. size
604
613
        next if i == k
605
 
        q = a[i][k] / akk
 
614
        q = a[i][k].quo(akk)
606
615
        a[i][k] = 0
607
616
        
608
617
        (k + 1).upto(size) do   
617
626
      
618
627
      (k + 1).upto(size) do
619
628
        |j|
620
 
        a[k][j] /= akk
 
629
        a[k][j] = a[k][j].quo(akk)
621
630
      end
622
631
      0.upto(size) do
623
632
        |j|
624
 
        @rows[k][j] /= akk
 
633
        @rows[k][j] = @rows[k][j].quo(akk)
625
634
      end
626
635
    end
627
636
    self
668
677
  
669
678
  #
670
679
  # Returns the determinant of the matrix.  If the matrix is not square, the
671
 
  # result is 0.
 
680
  # result is 0. This method's algorism is Gaussian elimination method
 
681
  # and using Numeric#quo(). Beware that using Float values, with their
 
682
  # usual lack of precision, can affect the value returned by this method.  Use
 
683
  # Rational values or Matrix#det_e instead if this is important to you.
 
684
  #
672
685
  #   Matrix[[7,6], [3,9]].determinant
673
 
  #     => 63
 
686
  #     => 63.0
674
687
  #
675
688
  def determinant
676
689
    return 0 unless square?
692
705
      end
693
706
      (k + 1).upto(size) do
694
707
        |i|
695
 
        q = a[i][k] / akk
 
708
        q = a[i][k].quo(akk)
696
709
        (k + 1).upto(size) do
697
710
          |j|
698
711
          a[i][j] -= a[k][j] * q
703
716
    det
704
717
  end
705
718
  alias det determinant
706
 
        
707
 
  #
708
 
  # Returns the rank of the matrix.  Beware that using Float values, with their
709
 
  # usual lack of precision, can affect the value returned by this method.  Use
710
 
  # Rational values instead if this is important to you.
 
719
 
 
720
  #
 
721
  # Returns the determinant of the matrix.  If the matrix is not square, the
 
722
  # result is 0. This method's algorism is Gaussian elimination method. 
 
723
  # This method uses Euclidean algorism. If all elements are integer,
 
724
  # really exact value. But, if an element is a float, can't return
 
725
  # exact value.   
 
726
  #
 
727
  #   Matrix[[7,6], [3,9]].determinant
 
728
  #     => 63
 
729
  #
 
730
  def determinant_e
 
731
    return 0 unless square?
 
732
    
 
733
    size = row_size - 1
 
734
    a = to_a
 
735
    
 
736
    det = 1
 
737
    k = 0
 
738
    begin 
 
739
      if a[k][k].zero?
 
740
        i = k
 
741
        begin
 
742
          return 0 if (i += 1) > size
 
743
        end while a[i][k].zero?
 
744
        a[i], a[k] = a[k], a[i]
 
745
        det *= -1
 
746
      end
 
747
      (k + 1).upto(size) do |i|
 
748
        q = a[i][k] / a[k][k]
 
749
        k.upto(size) do |j|
 
750
          a[i][j] -= a[k][j] * q
 
751
        end
 
752
        unless a[i][k].zero?
 
753
          a[i], a[k] = a[k], a[i]
 
754
          det *= -1
 
755
          redo
 
756
        end
 
757
      end
 
758
      det *= a[k][k]
 
759
    end while (k += 1) <= size
 
760
    det
 
761
  end
 
762
  alias det_e determinant_e
 
763
 
 
764
  #
 
765
  # Returns the rank of the matrix. Beware that using Float values,
 
766
  # probably return faild value. Use Rational values or Matrix#rank_e
 
767
  # for getting exact result.
 
768
  #
711
769
  #   Matrix[[7,6], [3,9]].rank
712
770
  #     => 2
713
771
  #
758
816
      end
759
817
      (k + 1).upto(a_row_size - 1) do
760
818
        |i|
761
 
        q = a[i][k] / akk
 
819
        q = a[i][k].quo(akk)
762
820
        (k + 1).upto(a_column_size - 1) do
763
821
          |j|
764
822
          a[i][j] -= a[k][j] * q
770
828
  end
771
829
 
772
830
  #
 
831
  # Returns the rank of the matrix. This method uses Euclidean
 
832
  # algorism. If all elements are integer, really exact value. But, if
 
833
  # an element is a float, can't return exact value.  
 
834
  #
 
835
  #   Matrix[[7,6], [3,9]].rank
 
836
  #     => 2
 
837
  #
 
838
  def rank_e
 
839
    a = to_a
 
840
    a_column_size = column_size
 
841
    a_row_size = row_size
 
842
    pi = 0
 
843
    (0 ... a_column_size).each do |j|
 
844
      if i = (pi ... a_row_size).find{|i0| !a[i0][j].zero?}
 
845
        if i != pi
 
846
          a[pi], a[i] = a[i], a[pi]
 
847
        end
 
848
        (pi + 1 ... a_row_size).each do |k|
 
849
          q = a[k][j] / a[pi][j]
 
850
          (pi ... a_column_size).each do |j0|
 
851
            a[k][j0] -= q * a[pi][j0]
 
852
          end
 
853
          if k > pi && !a[k][j].zero?
 
854
            a[k], a[pi] = a[pi], a[k]
 
855
            redo
 
856
          end
 
857
        end
 
858
        pi += 1
 
859
      end
 
860
    end
 
861
    pi
 
862
  end
 
863
 
 
864
 
 
865
  #
773
866
  # Returns the trace (sum of diagonal elements) of the matrix.
774
867
  #   Matrix[[7,6], [3,9]].trace
775
868
  #     => 16
844
937
    @rows.collect{|row| row.collect{|e| e}}
845
938
  end
846
939
  
 
940
  def elements_to_f
 
941
    collect{|e| e.to_f}
 
942
  end
 
943
  
 
944
  def elements_to_i
 
945
    collect{|e| e.to_i}
 
946
  end
 
947
  
 
948
  def elements_to_r
 
949
    collect{|e| e.to_r}
 
950
  end
 
951
  
847
952
  #--
848
953
  # PRINTING -=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-
849
954
  #++
922
1027
      when Vector
923
1028
        Scalar.Raise WrongArgType, other.class, "Numeric or Scalar or Matrix"
924
1029
      when Matrix
925
 
        self * _M.inverse
 
1030
        self * other.inverse
926
1031
      else
927
1032
        x, y = other.coerce(self)
928
 
        x / y
 
1033
        x.quo(y)
929
1034
      end
930
1035
    end
931
1036
    
1034
1139
  def [](i)
1035
1140
    @elements[i]
1036
1141
  end
 
1142
  alias element []
 
1143
  alias component []
 
1144
 
 
1145
  def []=(i, v)
 
1146
    @elements[i]= v
 
1147
  end
 
1148
  alias set_element []=
 
1149
  alias set_component []=
 
1150
  private :[]=, :set_element, :set_component
1037
1151
  
1038
1152
  #
1039
1153
  # Returns the number of elements in the vector.
1236
1350
    @elements.dup
1237
1351
  end
1238
1352
  
 
1353
  def elements_to_f
 
1354
    collect{|e| e.to_f}
 
1355
  end
 
1356
  
 
1357
  def elements_to_i
 
1358
    collect{|e| e.to_i}
 
1359
  end
 
1360
  
 
1361
  def elements_to_r
 
1362
    collect{|e| e.to_r}
 
1363
  end
 
1364
  
1239
1365
  #
1240
1366
  # FIXME: describe Vector#coerce.
1241
1367
  #