matriz 0.1.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,221 @@
1
+ require "./lib/racionales.rb"
2
+ require "./lib/matriz.rb"
3
+ require "./lib/matriz_dispersa.rb"
4
+
5
+ class Matriz_densa < Matriz
6
+ attr_reader :fil, :col, :mat
7
+
8
+ def initialize (m,n) #Estructura de datos de la matriz densa
9
+ raise TypeError, "Error. Tipo de dimensiones incorrectas" if ((m < 0) or (n < 0))
10
+ super
11
+ # @fil, @col = m, n
12
+ @mat = Array.new(@fil) {Array.new(@col)}
13
+ end
14
+
15
+ def to_s #Metodo para mostrar una matriz densa
16
+ for i in (0...self.fil)
17
+ print "("
18
+ for j in (0...self.col)
19
+ print " #{self.mat[i][j]}\t"
20
+ end
21
+ puts ")\n"
22
+ end
23
+ puts "\n"
24
+ end
25
+
26
+ def generar (o) #Segun la opcion elegida (1 o 2) crear la matriz densa con valores aleatorios (1)enteros o (2)racionales
27
+ if (o==1)
28
+ @mat = Array.new(@fil) {Array.new(@col) {rand(-10..10)}}
29
+ elsif (o==2)
30
+ for i in (0...self.fil)
31
+ for j in (0...self.col)
32
+ self.mat[i][j]=NumerosRacionales.new(rand(-10..10),rand(1..10))
33
+ end
34
+ end
35
+ end
36
+ end
37
+
38
+ def llenar (other) #Recoge por parametro el array que formara la nueva matriz
39
+ if other.is_a?(Array)
40
+ for i in (0...self.fil)
41
+ for j in (0...self.col)
42
+ self.mat[i][j] = other[i][j]
43
+ end
44
+ end
45
+ end
46
+ end
47
+
48
+ def introducir_datos (o) #El usuario puede elegir los tipos de datos (1.enteros y 2.racionales) y datos que contendra la matriz
49
+ puts "Rellene la matriz..."
50
+ if (o==1)
51
+ for i in (0...self.fil)
52
+ for j in (0...self.col)
53
+ puts "casilla (#{i},#{j}): "
54
+ STDOUT.flush
55
+ dato=gets.chomp
56
+ self.mat[i][j]= dato.to_i
57
+ end
58
+ end
59
+ elsif
60
+ for i in (0...self.fil)
61
+ for j in (0...self.col)
62
+ puts "casilla (#{i},#{j}): "
63
+ puts "numerador: "
64
+ STDOUT.flush
65
+ num=gets.chomp
66
+ puts "denominador: "
67
+ STDOUT.flush
68
+ den=gets.chomp
69
+ self.mat[i][j]=NumerosRacionales.new(num.to_i,den.to_i)
70
+ end
71
+ end
72
+ end
73
+ end
74
+
75
+ def coerce (other) #Metodo para hacer la conversion de datos para poder operar con la clase matriz densa
76
+ if (other.is_a?(Matriz_dispersa))
77
+ a=Matriz_densa.new(other.fil,other.col)
78
+ for i in (0...a.fil)
79
+ for j in (0...a.col)
80
+ a.mat[i][j]=0
81
+ end
82
+ end
83
+ for i in (0...other.pos.size)
84
+ a.mat[other.pos[i][0]][other.pos[i][1]]= other.dato[i]
85
+ end
86
+ return [a,self]
87
+ end
88
+ end
89
+
90
+ def t #Calcula la traspuesta de una matriz
91
+ nueva = Matriz_densa.new(self.col,self.fil)
92
+ for i in (0...nueva.fil)
93
+ for j in (0...nueva.col)
94
+ nueva.mat[i][j] = self.mat[j][i]
95
+ end
96
+ end
97
+ nueva
98
+ end
99
+
100
+ def ==(other) #Compara si dos matrices son iguales o no
101
+ raise unless other.is_a?(Matriz)
102
+ if (other.is_a?(Matriz_dispersa))
103
+ other=self.coerce(other)
104
+ other=other[0]
105
+ end
106
+ if (self.fil == other.fil) and (self.col == other.col)
107
+ for i in (0...other.fil)
108
+ for j in (0...other.col)
109
+ if self.mat[i][j] != other.mat[i][j]
110
+ return false
111
+ end
112
+ end
113
+ end
114
+ true
115
+ end #if
116
+ end
117
+
118
+ def +(other) #Devuelve la suma de dos matrices
119
+ raise unless other.is_a?(Matriz)
120
+ if (other.is_a?(Matriz_dispersa))
121
+ other=self.coerce(other)
122
+ other=other[0]
123
+ end
124
+ if (self.fil == other.fil) and (self.col == other.col)
125
+ nueva = Matriz_densa.new(self.fil,self.col)
126
+ @fil.times do |i| # 0.upto(@fil-1) do |i| # for i in (0...self.fil)
127
+ @col.times do |j| # 0.upto(@col-1) do |j| # for j in (0...self.col)
128
+ nueva.mat[i][j]= self.mat[i][j] + other.mat[i][j]
129
+ end
130
+ end
131
+ nueva
132
+ else
133
+ puts "Error. No se pueden sumar matrices de distintas dimensiones."
134
+ end
135
+ end
136
+
137
+ def -(other) #Devuelve la resta de dos matrices
138
+ raise unless other.is_a?(Matriz)
139
+ if (other.is_a?(Matriz_dispersa))
140
+ other=self.coerce(other)
141
+ other=other[0]
142
+ end
143
+ if (self.fil == other.fil) and (self.col == other.col)
144
+ nueva = Matriz_densa.new(self.fil,self.col)
145
+ @fil.times do |i| # 0.upto(@fil-1) do |i| # for i in (0...self.fil)
146
+ @col.times do |j| # 0.upto(@col-1) do |j| # for j in (0...self.col)
147
+ nueva.mat[i][j] = self.mat[i][j] - other.mat[i][j]
148
+ end
149
+ end
150
+ nueva
151
+ else
152
+ puts "Error. No se pueden restar matrices de distintas dimensiones."
153
+ end
154
+ end
155
+
156
+
157
+ def *(other) #Multiplicacion: realiza el producto escalar o por otra matriz segun la clase de other
158
+ if other.is_a?(Numeric)
159
+ nueva = Matriz_densa.new(self.fil,self.col)
160
+ if (self.mat[0][0]).is_a?(NumerosRacionales)
161
+ n=NumerosRacionales.new(other,1)
162
+ else
163
+ n=other
164
+ end
165
+ @fil.times do |i| # 0.upto(@fil-1) do |i| # for i in (0...self.fil)
166
+ @col.times do |j| # 0.upto(@col-1) do |j| # for j in (0...self.col)
167
+ nueva.mat[i][j] = n*self.mat[i][j]
168
+ end
169
+ end
170
+ nueva
171
+ elsif other.is_a?(Matriz)
172
+ if (self.col == other.fil)
173
+ if (other.is_a?(Matriz_dispersa))
174
+ other=self.coerce(other)
175
+ other=other[0]
176
+ end
177
+ nueva = Matriz_densa.new(self.fil,other.col)
178
+ @fil.times do |i| # for i in (0...self.fil)
179
+ @col.times do |j| # for j in (0...other.col)
180
+ if (self.mat[0][0]).is_a?(NumerosRacionales)
181
+ nueva.mat[i][j] = NumerosRacionales.new(0,1)
182
+ else
183
+ nueva.mat[i][j] = 0
184
+ end
185
+ @col.times do |k| # for k in (0...self.col)
186
+ nueva.mat[i][j] += self.mat[i][k]*other.mat[k][j]
187
+ end
188
+ end
189
+ end
190
+ nueva
191
+ else
192
+ puts "Error. No se pueden multiplicar estas matrices. La col de la M1 debe coincidir con la fil de M2"
193
+ end
194
+ end
195
+ end
196
+
197
+ def max #Devuelve el elemento mayor de la matriz
198
+ r=-9999999
199
+ @mat.each do |i|
200
+ i.each do |j|
201
+ if (j.to_f > r.to_f)
202
+ r = j
203
+ end
204
+ end
205
+ end
206
+ r
207
+ end
208
+
209
+ def min
210
+ r= 9999999 #Devuelve el elemento menor de la matriz
211
+ @mat.each do |i|
212
+ i.each do |j|
213
+ if (j.to_f < r.to_f)
214
+ r = j
215
+ end
216
+ end
217
+ end
218
+ r
219
+ end
220
+
221
+ end
@@ -0,0 +1,323 @@
1
+ require "./lib/racionales.rb"
2
+ require "./lib/matriz.rb"
3
+ require "./lib/matriz_densa.rb"
4
+
5
+ class Matriz_dispersa < Matriz
6
+ attr_reader :fil, :col, :pos, :dato
7
+
8
+ def initialize (m,n) #Estructura de datos de la matriz dispersa
9
+ raise TypeError, "Error. Tipo de dimensiones incorrectas" if ((m < 0) or (n < 0))
10
+ super
11
+ # @fil, @col = m, n
12
+ @pos = Array.new(0){}
13
+ @dato = Array.new(0){}
14
+ end
15
+
16
+ def llenar (posciones,datos) #Crea la matriz dispersa a partir del array de posiciones y de datos: posiciones y datos tienen que tener la misma dimension y datos no puede contener ceros
17
+ for i in (0...posciones.size)
18
+ @pos << posciones[i]
19
+ @dato << datos[i]
20
+ end
21
+ end
22
+
23
+ def to_s #Metodo para mostrar una matriz dispersa
24
+ for i in (0...self.fil)
25
+ print "("
26
+ for j in (0...self.col)
27
+ b = buscar(i,j)
28
+ if (b != -1)
29
+ print " #{self.dato[b]}\t"
30
+ else
31
+ print " 0\t"
32
+ end
33
+ end
34
+ puts ")\n"
35
+ end
36
+ puts "\n"
37
+ end
38
+
39
+ def mi_random #Hago esto, pq rand(-10..10) puede generar el valor cero y esto no nos interesa almacenarlo
40
+ if (rand(10) > 4)
41
+ 1
42
+ else
43
+ -1
44
+ end
45
+ end
46
+
47
+ def generar (o) #Segun la opcion elegida (1 o 2) crear la matriz dispersa con valores aleatorios (1)enteros o (2)racionales
48
+ if (@fil*@col) == 1
49
+ elementos = 1
50
+ elsif
51
+ elementos =(rand(60..100)*(@fil*@col))/100 #minimo 60% de ceros
52
+ end
53
+ dim= (@fil*@col)-elementos #num de elementos posibles para introducir valores respetando la dispersion
54
+ @pos = Array.new(dim){[rand(0..(@fil-1)),rand(0..(@col-1))]}
55
+ for i in (0...dim)
56
+ if (o==1) #generamos enteros
57
+ @dato = Array.new(dim){mi_random*rand(1..10)}
58
+ elsif (o==2) #generamos racionales
59
+ @dato = Array.new(dim){NumerosRacionales.new(mi_random*rand(1..10),rand(1..10))}
60
+ end
61
+ end
62
+ end
63
+
64
+ def buscar (i,j) #Devuelve una posicion del array que coincide con los indices de los param
65
+ aux=[i,j]
66
+ posicion= -1
67
+ k=0
68
+ while (k < @pos.size) and (posicion==-1)
69
+ if (@pos[k]==aux)
70
+ posicion=k
71
+ end
72
+ k=k+1
73
+ end
74
+ posicion
75
+ end
76
+
77
+
78
+ def introducir_datos (o) #El usuario puede elegir los tipos de datos (1.enteros y 2.racionales) y datos que contendra la matriz
79
+ if (@fil*@col)==1
80
+ max=0
81
+ elsif
82
+ max= (@fil*@col*60)/100
83
+ max = (@fil*@col)-max
84
+ end
85
+ total= -1
86
+ while (total<0) or (total>max)
87
+ puts "Cuantos datos va a introducir? [0-#{max}]"
88
+ STDOUT.flush
89
+ total=gets.chomp
90
+ total=total.to_i
91
+ end
92
+ if (o==1) #de numeros enteros
93
+ for k in (0...total)
94
+ i,j= -1,-1
95
+ while (i<0) or (i>(@fil-1))
96
+ puts "introduce la coordenada i: "
97
+ STDOUT.flush
98
+ i=(gets.chomp).to_i
99
+ end
100
+ while (j<0) or (j>(@col-1))
101
+ puts "introduce la coordenada j: "
102
+ STDOUT.flush
103
+ j=(gets.chomp).to_i
104
+ end
105
+ @pos << [i.to_i,j.to_i]
106
+ dato=0
107
+ while (dato == 0)
108
+ puts "introduce el dato (=/=0) de la casilla (#{i},#{j}): "
109
+ STDOUT.flush
110
+ dato=(gets.chomp).to_i
111
+ end
112
+ @dato << dato
113
+ end
114
+ elsif #de numeros racionales
115
+ for k in (0...total)
116
+ i,j= -1,-1
117
+ while (i<0) or (i>(@fil-1))
118
+ puts "introduce la coordenada i: "
119
+ STDOUT.flush
120
+ i=(gets.chomp).to_i
121
+ end
122
+ while (j<0) or (j>(@col-1))
123
+ puts "introduce la coordenada j: "
124
+ STDOUT.flush
125
+ j=(gets.chomp).to_i
126
+ end
127
+ @pos << [i.to_i,j.to_i]
128
+ num=0
129
+ while (num == 0)
130
+ puts "introduce el dato (=/=0) de la casilla (#{i},#{j}): "
131
+ puts "numerador: "
132
+ STDOUT.flush
133
+ num=(gets.chomp).to_i
134
+ end
135
+ puts "denominador: "
136
+ STDOUT.flush
137
+ den=gets.chomp
138
+ @dato << NumerosRacionales.new(num,den.to_i)
139
+ end
140
+ end
141
+ end
142
+
143
+ def ==(other) #Compara si dos matrices son iguales o no
144
+ raise unless other.is_a?(Matriz) #deben ser matrices, da = si se comparan densas con dispersas
145
+ if (other.is_a?(Matriz_densa))
146
+ other=self.coerce(other)
147
+ other=other[0]
148
+ end
149
+ if (@fil == other.fil) and (@col == other.col)
150
+ if (@pos.size == 0) and (other.pos.size == 0)#si ambos estan estan vacios...
151
+ return true
152
+ elsif (@pos.size == other.pos.size)
153
+ for i in (0...@pos.size)
154
+ k = other.buscar(@pos[i][0],@pos[i][1]) #buscamos esa pos en el otro vector
155
+ if (k == -1)
156
+ return false
157
+ elsif (@dato[i] != other.dato[k])
158
+ return false
159
+ end
160
+ end
161
+ return true
162
+ else
163
+ return false
164
+ end
165
+ else
166
+ return false
167
+ end
168
+ end
169
+
170
+ def coerce(other) #Metodo para hacer la conversion de datos para poder operar con la clase matriz dispersa
171
+ a=Matriz_dispersa.new(other.fil,other.col)
172
+ for i in (0...other.fil)
173
+ for j in (0...other.col)
174
+ if (other.mat[i][j] != 0)
175
+ a.pos << [i,j]
176
+ a.dato << other.mat[i][j]
177
+ end
178
+ end
179
+ end
180
+ return[a,self]
181
+ end
182
+
183
+ def t ##Calcula la traspuesta de la matriz
184
+ nueva = Matriz_dispersa.new(@col,@fil)
185
+ for i in (0...@pos.size)
186
+ nueva.pos << [@pos[i][1],@pos[i][0]]
187
+ nueva.dato << @dato[i]
188
+ end
189
+ nueva
190
+ end
191
+
192
+ def +(other) #Devuelve la suma de dos matrices
193
+ raise unless other.is_a?(Matriz) #deben ser matrices, da = si se comparan densas con dispersas
194
+ if (other.is_a?(Matriz_densa))
195
+ other=self.coerce(other)
196
+ other=other[0]
197
+ end
198
+ if (@fil == other.fil) and (@col == other.col)
199
+ nueva= Matriz_dispersa.new(@fil,@col)
200
+ @pos.size.times do |i| # 0.upto(@pos.size-1) do |i| # for i in (0...@pos.size)
201
+ k = other.buscar(@pos[i][0],@pos[i][1])
202
+ if (k!= -1) #existe esa pos
203
+ if (@dato[i]+other.dato[k]) != 0
204
+ nueva.pos << @pos[i]
205
+ nueva.dato << (@dato[i]+other.dato[k])
206
+ end
207
+ else
208
+ nueva.pos << @pos[i]
209
+ nueva.dato << @dato[i]
210
+ end
211
+ end #times
212
+ #almacenamos los que no se hayan sumado de la otra matriz
213
+ other.pos.size.times do |i| # 0.upto(other.pos.size-1) do |i| #for i in (0...other.pos.size)
214
+ k = nueva.buscar(other.pos[i][0],other.pos[i][1])
215
+ if (k==-1)
216
+ nueva.pos << other.pos[i]
217
+ nueva.dato << other.dato[i]
218
+ end
219
+ end
220
+ else
221
+ puts "No se pueden sumar, no tienen las mismas dimensiones"
222
+ end #if
223
+ nueva
224
+ end
225
+
226
+ def -(other) #Devuelve la resta de dos matrices
227
+ raise unless other.is_a?(Matriz) #deben ser matrices, da = si se comparan densas con dispersas
228
+ if (other.is_a?(Matriz_densa))
229
+ other=self.coerce(other)
230
+ other=other[0]
231
+ end
232
+ if (@fil == other.fil) and (@col == other.col)
233
+ nueva= Matriz_dispersa.new(@fil,@col)
234
+ @pos.size.times do |i| # 0.upto(@pos.size-1) do |i| # for i in (0...@pos.size)
235
+ k = other.buscar(@pos[i][0],@pos[i][1])
236
+ if (k!= -1) #existe esa pos
237
+ if (@dato[i]-other.dato[k]) != 0
238
+ nueva.pos << @pos[i]
239
+ nueva.dato << (@dato[i]-other.dato[k])
240
+ end
241
+ else
242
+ nueva.pos << @pos[i]
243
+ nueva.dato << @dato[i]
244
+ end
245
+ end #for
246
+ #almacenamos los que no se hayan sumado de la otra matriz
247
+ other.pos.size.times do |i| # 0.upto(other.pos.size-1) do |i| #for i in (0...other.pos.size)
248
+ k = nueva.buscar(other.pos[i][0],other.pos[i][1])
249
+ if (k==-1)
250
+ nueva.pos << other.pos[i]
251
+ nueva.dato << -other.dato[i]
252
+ end
253
+ end
254
+ else
255
+ puts "No se pueden restar, no tienen las mismas dimensiones"
256
+ end #if
257
+ nueva
258
+ end
259
+
260
+ def *(other) #Producto: segun clase de other: si es un numero realiza el producto ecalar, si en cambio es otra matriz se realiza el producto de matrices.
261
+ if other.is_a?(Numeric)
262
+ nueva=self
263
+ @dato.size.times do |i| # for i in (0...@dato.size)
264
+ nueva.dato[i] = other*nueva.dato[i]
265
+ end
266
+ nueva
267
+ elsif other.is_a?(Matriz)
268
+ if (self.col == other.fil)
269
+ if (other.is_a?(Matriz_densa))
270
+ other=self.coerce(other)
271
+ other=other[0]
272
+ end
273
+ nueva= Matriz_dispersa.new(@fil,other.col)
274
+ @fil.times do |i| # for i in (0...@fil)
275
+ @col.times do |j| # for j in (0...@col)
276
+ resul = 0
277
+ @col.times do |k| # for k in (0...@col)
278
+ n = self.buscar(i,k)
279
+ if n != -1
280
+ m = other.buscar(k,j)
281
+ if m != -1
282
+ resul += self.dato[n] * other.dato[m]
283
+ end
284
+ end
285
+ end
286
+ if resul != 0
287
+ nueva.dato << resul
288
+ nueva.pos << [i,j]
289
+ end
290
+ end # for j
291
+ end #for i
292
+ nueva
293
+ else
294
+ puts "Error. No se pueden multiplicar estas matrices. La col de la M1 debe coincidir con la fil de M2"
295
+ end
296
+ end
297
+ end
298
+
299
+ def max #Devuelve el elemento mayor de la matriz
300
+ r = -999999
301
+ aux=@dato
302
+ aux<< 0
303
+ @dato.each do |i|
304
+ if (i.to_f>r.to_f)
305
+ r=i
306
+ end
307
+ end
308
+ r
309
+ end
310
+
311
+ def min #Devuelve el elemento menor de la matriz
312
+ r = 999999
313
+ aux=@dato
314
+ aux<< 0
315
+ @dato.each do |i|
316
+ if (i.to_f<r.to_f)
317
+ r=i
318
+ end
319
+ end
320
+ r
321
+ end
322
+
323
+ end