Class: Matrice

Inherits:
Object show all
Defined in:
lib/matrice.rb

Overview

Note:

Dans ce qui suit, dans les clauses ensure, des expressions telles que “.get(i)” et “.get(i, j)” sont parfois utilisees. Elles sont equivalentes a “[i]” ou “[i, j]”. Cette notation a ete utilisee parce que yard creait des problemes de reference en utisant directement les crochets.

Classe pour des matrices a deux dimensions (objets mutables).

Il existe deja une classe Matrix dans les gems publics, mais il s'agit d'une classe pour des matrices immuables. Il y a donc uniquement des constructeurs monolitique, c'est-a-dire qu'il est impossible de modifier une cellule d'une matrice une fois qu'elle a ete creee (style purement fonctionnel seulement, donc).

Class Attribute Summary collapse

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(nb_lignes, nb_colonnes = nil, elems = nil, rapide = nil) ⇒ Matrice

Creation d'une matrice.

Parameters:

  • nb_lignes (Fixnum)

    Nombre de lignes

  • nb_colonnes (Fixnum) (defaults to: nil)

    Nombre de colonnes

  • elems (Array<Array>) (defaults to: nil)

    Les divers elements de la matrice

  • rapide (Bool) (defaults to: nil)

    Si on veut une mise en oeuvre plus rapide mais avec certaines operations en moins

Requires:

  • elems => elems.size == nb_lignes && elems.get(i).size == nb_colonnes



54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
# File 'lib/matrice.rb', line 54

def initialize( nb_lignes, nb_colonnes = nil, elems = nil, rapide = nil )
  # Par defaut: Meme nombre de colonnes que de lignes.
  # Supprime de l'entete car yard signalait une erreur et terminait.
  nb_colonnes ||= nb_lignes

  DBC.require nb_lignes > 0 && nb_colonnes > 0, "*** Les nombres de lignes et de colonnes doivent etre positifs"
  @nb_lignes, @nb_colonnes = nb_lignes, nb_colonnes

  if elems
    DBC.require elems.size == nb_lignes, "*** Le nombre d'elements fournis pour initialize doit etre egal a nb_lignes"
    DBC.require elems.all? { |ligne| ligne.size == nb_colonnes }, "*** Les lignes doivent avoir nb_colonnes (#{nb_colonnes}) elements"
    DBC.require !block_given?, "*** Un bloc ne peut pas etre fourni si des elements sont specifies"
  end

  @rapide = !!rapide
  if @rapide
    @elems = Array.new( nb_lignes * nb_colonnes )

    class << self
      def [](i, j); @elems[i * @nb_colonnes + j]; end
      def []=(i, j, x); @elems[i * @nb_colonnes + j] = x; end
      def ligne( _i ); DBC.assert false, "*** ligne pas definie"; end
      def colonne( _i ); DBC.assert false, "*** colonne pas definie"; end
    end
  else
    @elems = Array.new( nb_lignes )
    @elems.map! { Array.new(nb_colonnes) }
  end

  if block_given? || elems
    (0...nb_lignes).each do |i|
      (0...nb_colonnes).each do |j|
        self[i, j] = elems ? elems[i][j] : yield(i, j)
      end
    end
  end
end

Class Attribute Details

.no_bound_checkBool

Pour indiquer si on doit, ou non, effectuer les verifications des bornes lors des acces aux elements de la matrice.

Valeur par defaut = nil. Donc, par defaut, on fait les verifications des bornes. Par contre, on peut vouloir ne pas les faire, notamment, pour mesurer/comparer les temps d'execution et l'acceleration absolue.

Returns:

  • (Bool)


36
37
38
# File 'lib/matrice.rb', line 36

def no_bound_check
  @no_bound_check
end

Instance Attribute Details

#nb_colonnesFixnum (readonly)

Returns:

  • (Fixnum)


43
44
45
# File 'lib/matrice.rb', line 43

def nb_colonnes
  @nb_colonnes
end

#nb_lignesFixnum (readonly)

Returns:

  • (Fixnum)


40
41
42
# File 'lib/matrice.rb', line 40

def nb_lignes
  @nb_lignes
end

Instance Method Details

#*(autre) ⇒ Matrice

Produit matriciel iteratif et sequentiel.

Parameters:

Returns:

Requires:

  • nb_colonnes == autre.nb_lignes



183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
# File 'lib/matrice.rb', line 183

def *( autre )
  DBC.require nb_colonnes == autre.nb_lignes, '*** Le nombre de lignes de la 2e matrice doit etre = nombre de colonne de la 1ere'

  r = Matrice.new( nb_lignes, autre.nb_colonnes, nil, @rapide )
  (0...nb_lignes).each do |i|
    (0...autre.nb_colonnes).each do |j|
      r[i, j] = 0
      (0...nb_colonnes).each do |k|
        r[i, j] += self[i,k] * autre[k,j]
      end
    end
  end

  r
end

#==(autre) ⇒ Bool

Comparaison d'egalite.

Parameters:

Returns:

  • (Bool)


204
205
206
207
208
209
210
211
212
213
214
# File 'lib/matrice.rb', line 204

def ==( autre )
  return false if nb_lignes != autre.nb_lignes
  return false if nb_colonnes != autre.nb_colonnes
  (0...nb_lignes).each do |i|
    (0...nb_colonnes).each do |j|
      return false if self[i, j] != autre[i, j]
    end
  end

  true
end

#[](i, j) ⇒ Object

Retourne un element ou une "tranche" d'elements de la matrice.

Parameters:

  • i (Fixnum, Range)

    L’index ou l’intervalle d’index desire

  • j (Fixnum, Range)

    L’index ou l’intervalle d’index desire

Returns:

  • SI i & j sont des Fixnum ALORS self.get(i, j) SINON la tranche indiquee

Requires:

  • Que les bornes soient valides



123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
# File 'lib/matrice.rb', line 123

def []( i, j )
  if i.class == Fixnum && j.class == Fixnum
    # Un seul element!
    unless Matrice.no_bound_check
      check_bounds i, nb_lignes
      check_bounds j, nb_colonnes
    end
    return @elems[i][j]
  end

  is = define_range( i, nb_lignes )
  js = define_range( j, nb_colonnes )

  lignes = Array.new(is.last - is.first + 1)
  lignes.each_index do |i|
    lignes[i] = Array.new(js.last - js.first + 1)
  end
  lignes.each_index do |i|
    lignes[i].each_index do |j|
      lignes[i][j] = self[i + is.first, j + js.first]
    end
  end

  if i.class == Fixnum || j.class == Fixnum
    lignes.first
  else
    lignes
  end
end

#[]=(i, j, x) ⇒ Object

Modifie l'element a la position i, j

Parameters:

  • i (Fixnum)

    No. de ligne

  • j (Fixnum)

    No. de colonne

  • x

    La nouvelle valeur

Returns:

  • x

Ensures:

  • self.get(i, j) == x

Requires:

  • 0 <= i < nb_lignes && 0 <= j < nb_colonnes



162
163
164
165
166
167
# File 'lib/matrice.rb', line 162

def []=( i, j, x )
  check_bounds i, nb_lignes unless Matrice.no_bound_check
  check_bounds j, nb_colonnes unless Matrice.no_bound_check

  @elems[i][j] = x
end

#colonne(j) ⇒ Array

Retourne la jeme colonne de la matrice.

Parameters:

  • j (Fixnum)

    L’indice de la colonne desiree

Returns:

  • (Array)

    La jeme colonne

Requires:

  • 0 <= j < nb_colonnes



110
111
112
113
114
# File 'lib/matrice.rb', line 110

def colonne( j )
  check_bounds j, nb_colonnes unless Matrice.no_bound_check

  (0...nb_lignes).map { |i| @elems[i][j] }
end

#each_index {|i, j, item| ... } ⇒ Object

Iterateur sequentiel sur les differents index/element de la matrice.

Yield Parameters:

  • i (Fixnum)
  • j (Fixnum)
  • item (Fixnum)

    self[i, j]

Yield Returns:

  • (void)


241
242
243
244
245
246
247
# File 'lib/matrice.rb', line 241

def each_index
  nb_lignes.times do |i|
    nb_colonnes.times do |j|
      yield(i, j, self[i, j])
    end
  end
end

#ligne(i) ⇒ Array

Retourne la ieme ligne de la matrice.

Parameters:

  • i (Fixnum)

    L’indice de la ligne desiree

Returns:

  • (Array)

    La ieme ligne

Requires:

  • 0 <= i < nb_lignes



98
99
100
101
102
# File 'lib/matrice.rb', line 98

def ligne( i )
  check_bounds i, nb_lignes unless Matrice.no_bound_check

  @elems[i]
end

#peach_index_ligne(opts = {}, &block) ⇒ Object



249
250
251
252
# File 'lib/matrice.rb', line 249

def peach_index_ligne( opts = {}, &block )
  DBC.require !@rapide, '*** Operation impossible si mise en oeuvre rapide'
  @elems.peach_index( opts, &block )
end

#to_aArray<Array>

Transforme les elements de la matrice en un Array d'Array

Returns:



173
174
175
# File 'lib/matrice.rb', line 173

def to_a
  @elems
end

#to_sString

Representation de la matrice en une chaine de caracteres.

Returns:

  • (String)


220
221
222
223
224
225
226
227
228
229
230
231
# File 'lib/matrice.rb', line 220

def to_s
  s = ''
  (0...nb_lignes).each do |i|
    (0...nb_colonnes).each do |j|
      x = self[i, j]
      s << (x ? "#{x} " : '? ')
    end
    s << "\n"
  end

  s
end