matrix_disp 0.0.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,567 @@
1
+ #require "matrix_disp/version"
2
+
3
+ module Math
4
+
5
+ class Matriz
6
+ def initialize (f,c,v)
7
+ @f, @c = f, c
8
+ @v = v
9
+ end
10
+
11
+ def def_tipo
12
+ if (((@v.count{|e| e == 0}*100)/(@f*@c)) >= 60)
13
+ resultado = SparseMatrix.new
14
+ for i in (0...@f*@c)
15
+ tmp = SparseVector.new
16
+ if @v[i] != 0
17
+ if resultado.matrix[i%@c].is_a? SparseVector
18
+ resultado.matrix[i%@c][i/@f] = @v[i]
19
+ else
20
+ tmp[i/@f] = @v[i]
21
+ resultado.matrix[i%@c] = tmp
22
+ end
23
+ end
24
+ end
25
+ return resultado
26
+ else
27
+ return DenseMatrix.new(@f,@c,@v)
28
+ end
29
+ end
30
+ end
31
+
32
+ class Fraccion
33
+ include Comparable
34
+ #Accessors para poder acceder a los métodos :num y :denom
35
+ attr_accessor :num
36
+ attr_accessor :denom
37
+
38
+ def coerce(other)
39
+ [self, other]
40
+ end
41
+ #método que llama al constructor del objeto de la clase
42
+ def initialize(n, d)
43
+ @num = n
44
+ @denom = d
45
+ gcd #reduce la fracción
46
+ end
47
+ #método que reduce la fracción calculando el mcd y dividiendolo entre el numerador y el denominador
48
+ def gcd
49
+ mcd, v = @num.abs, @denom.abs
50
+ while v > 0
51
+ mcd, v = v, mcd % v
52
+ end
53
+ @num = @num/mcd
54
+ @denom = @denom/mcd
55
+ end
56
+ #método que muestra la fracción en la forma a/b
57
+ def to_s
58
+ "#{@num}/#{@denom}"
59
+ #puts "#{@num}/#{@denom}"
60
+ #cadena = "#{@num}/#{@denom}" #se usa para que la función to_s devuelva lo que acaba de imprimir por pantalla
61
+ end
62
+ def to_f
63
+ @num.to_f/@denom.to_f
64
+ end
65
+ #método que muestra la fracción en la forma a/b en flotante
66
+ def to_sf
67
+ "#{@num.to_f}/#{@denom.to_f}"
68
+ #puts "#{@num.to_f}/#{@denom.to_f}"
69
+ #cadena = "#{@num.to_f}/#{@denom.to_f}" #se usa para que la función to_s devuelva lo que acaba de imprimir por pantalla
70
+ end
71
+ #método que devuelve true si la fracción con la que se compara es igual a la actual
72
+ def ==(o)
73
+ return @num == o.num && @denom == o.denom if o.instance_of? Fraccion
74
+ false
75
+ end
76
+ #método que calcula el valor absoluto de la fracción
77
+ def abs
78
+ @denom = @denom.abs
79
+ @num = @num.abs
80
+ end
81
+ #método que calcula el recíproco de la fracción.
82
+ def reciprocal
83
+ tmpNumerador = @num
84
+ @num = @denom
85
+ @denom = tmpNumerador
86
+ end
87
+ #método que calcula el inverso de la fracción
88
+ def -@
89
+ @num = -@num
90
+ end
91
+ #método que devuelve la suma de la fracción actual con la que se pasa como parámetro
92
+ def +(other)
93
+ Fraccion.new((@num*other.denom)+(@denom*other.num), @denom*other.denom)
94
+ end
95
+ #método que devuelve la resta de la fracción actual con la que se pasa como parámetro
96
+ def -(other)
97
+ Fraccion.new((@num*other.denom)-(@denom*other.num), @denom*other.denom)
98
+ end
99
+ #método que devuelve la multiplicación de la fracción actual con la que se pasa como parámetro
100
+ def *(other)
101
+ Fraccion.new(@num*other.num, @denom*other.denom)
102
+ end
103
+ #método que devuelve la división de la fracción actual con la que se pasa como parámetro
104
+ def /(other)
105
+ other.reciprocal
106
+ Fraccion.new(@num*other.num, @denom*other.denom)
107
+ end
108
+ #método que devuelve el módulo de la fracción actual con la que se pasa como parámetro
109
+ def %(other)
110
+ other.reciprocal
111
+ a = Fraccion.new(@num*other.num, @denom*other.denom)
112
+ a.num % a.denom
113
+ end
114
+ def divReciprocal(other)
115
+ other.reciprocal
116
+ a = Fraccion.new(@num*other.num, @denom*other.denom)
117
+ a.reciprocal
118
+ a
119
+ end
120
+ def <=>(other)
121
+ (@num.to_f/@denom.to_f) <=> (other.num.to_f/other.denom.to_f)
122
+ end
123
+ end
124
+
125
+ class SparseVector
126
+ attr_reader :vector
127
+
128
+ def initialize(h = {})
129
+ @vector = Hash.new(0)
130
+ @vector = @vector.merge!(h)
131
+ end
132
+
133
+ def [](i)
134
+ @vector[i]
135
+ end
136
+
137
+ def []=(i,v)
138
+ @vector[i] = v
139
+ end
140
+
141
+ def to_s
142
+ @vector.to_s
143
+ end
144
+
145
+ def keys
146
+ @vector.keys
147
+ end
148
+
149
+ def +(other)
150
+ resultado = SparseVector.new
151
+ for i in other.vector.keys do
152
+ resultado[i] = other[i]
153
+ end
154
+ for i in @vector.keys do
155
+ resultado[i] = @vector[i] + other[i]
156
+ end
157
+ resultado
158
+ end
159
+
160
+ def -(other)
161
+ resultado = SparseVector.new
162
+ for i in other.vector.keys do
163
+ resultado[i] = other[i]
164
+ end
165
+ for i in @vector.keys do
166
+ resultado[i] = @vector[i] - other[i]
167
+ end
168
+ resultado
169
+ end
170
+ end
171
+
172
+ class SparseMatrix < Matriz
173
+
174
+ attr_reader :matrix
175
+
176
+ def initialize(h = {})
177
+ @matrix = Hash.new({})
178
+ for k in h.keys do
179
+ @matrix[k] = if h[k].is_a? SparseVector
180
+ h[k]
181
+ else
182
+ @matrix[k] = SparseVector.new(h[k])
183
+ end
184
+ end
185
+ end
186
+
187
+ def [](i)
188
+ @matrix[i]
189
+ end
190
+
191
+ def []=(i,other)
192
+ for y in other.keys do
193
+ puts "---- other[#{y}] #{other[y]}"
194
+ @matrix[i][y] = other[y]
195
+ puts "---- matrix[#{i}][#{y}] #{@matrix[i][y]}"
196
+ end
197
+ end
198
+
199
+ def imp
200
+ for i in @matrix.keys do
201
+ puts "#{i} ---- #{@matrix[i].to_s}"
202
+ end
203
+ end
204
+
205
+ def col(j)
206
+ c = {}
207
+ for r in @matrix.keys do
208
+ c[r] = @matrix[r].vector[j] if @matrix[r].vector.keys.include? j
209
+ end
210
+ SparseVector.new c
211
+ end
212
+
213
+ def +(other)
214
+ resultado = SparseMatrix.new
215
+ for i in other.matrix.keys do
216
+ resultado.matrix[i] = other[i]
217
+ end
218
+ for i in @matrix.keys do
219
+ for j in @matrix[i].keys do
220
+ if other.matrix[i][j] == nil
221
+ resultado.matrix[i] = @matrix[i]
222
+ else
223
+ resultado.matrix[i][j] = @matrix[i][j]+other.matrix[i][j]
224
+ end
225
+ end
226
+ end
227
+ resultado
228
+ end
229
+
230
+ def -(other)
231
+ resultado = SparseMatrix.new
232
+ for i in other.matrix.keys do
233
+ resultado.matrix[i] = other[i]
234
+ end
235
+ for i in @matrix.keys do
236
+ for j in @matrix[i].keys do
237
+ if other.matrix[i][j] == nil
238
+ resultado.matrix[i] = @matrix[i]
239
+ else
240
+ resultado.matrix[i][j] = @matrix[i][j]-other.matrix[i][j]
241
+ end
242
+ end
243
+ end
244
+ resultado
245
+ end
246
+
247
+
248
+
249
+ def traspuesta
250
+ resultado = SparseMatrix.new
251
+ for i in @matrix.keys do
252
+ for j in @matrix[i].keys do
253
+ tmp = SparseVector.new
254
+ for x in @matrix.keys do
255
+ for y in @matrix[x].keys do
256
+ #puts "#{j} == #{y}"
257
+ if j == y
258
+ #puts "#{j} == #{y}, por tanto tmp[#{i}] = #{@matrix[x][y]}"
259
+ tmp[i] = @matrix[x][y]
260
+ #puts "TMP[#{i}] = #{tmp[i]}"
261
+ end
262
+ end
263
+ end
264
+ resultado.matrix[j] = tmp
265
+ #puts "resultado.matrix[#{j}] = #{tmp}, Y QUEDA: #{resultado.matrix[j]}"
266
+ end
267
+ end
268
+ resultado
269
+ end
270
+
271
+ def *(other)
272
+ trasp = self.traspuesta
273
+ resultado = SparseMatrix.new
274
+ for i in trasp.matrix.keys do
275
+ for j in trasp.matrix[i].keys do
276
+ if other.matrix[i][j] != nil
277
+
278
+ end
279
+ end
280
+ end
281
+ end
282
+
283
+ def max
284
+ max = 0
285
+ for i in @matrix.keys do
286
+ for j in @matrix[i].keys do
287
+ if @matrix[i][j].is_a? Fraccion
288
+ tmp = Fraccion.new(max,1)
289
+ if @matrix[i][j] > tmp
290
+ max = @matrix[i][j].to_f
291
+ end
292
+ else
293
+ if @matrix[i][j] > max
294
+ max = @matrix[i][j]
295
+ end
296
+ end
297
+ end
298
+ end
299
+ max
300
+ end
301
+
302
+ def min
303
+ min = 999999999
304
+ for i in @matrix.keys do
305
+ for j in @matrix[i].keys do
306
+ if @matrix[i][j].is_a? Fraccion
307
+ tmp = Fraccion.new(min,1)
308
+ if @matrix[i][j] < tmp
309
+ min = @matrix[i][j].to_f
310
+ end
311
+ else
312
+ if @matrix[i][j] < min
313
+ min = @matrix[i][j]
314
+ end
315
+ end
316
+ end
317
+ end
318
+ min
319
+ end
320
+ end
321
+
322
+
323
+ class DenseMatrix < Matriz
324
+ attr_accessor :m
325
+ attr_accessor :f
326
+ attr_accessor :c
327
+
328
+ def initialize(filas, columnas, v)
329
+ @f = filas
330
+ @c = columnas
331
+ @m = []
332
+ i = 0
333
+ while i < @f*@c
334
+ @m[i] = v[i]
335
+ i=i+1
336
+ end
337
+ end
338
+
339
+ def [](a,b)
340
+ @m[a+(b*@c)]
341
+ end
342
+
343
+ def []=(a,b,r)
344
+ @m[a+(b*@c)] = r
345
+ end
346
+
347
+ def *(other)
348
+ a = Array.new(@f*@c, 0)
349
+ resultado = DenseMatrix.new(@f, @c, a)
350
+ if @f*@c == other.c*other.f
351
+ for i in (0...@c) do
352
+ for j in (0...@f) do
353
+ s = 0
354
+ for k in (0...@c) do
355
+ s = s + (@m[i+(k*@c)] * other.m[k+(j*other.c)])
356
+ end
357
+ resultado[i,j] = s
358
+ end
359
+ end
360
+ else
361
+ puts "Las matriz A debe tener el mismo numero de filas que las columnas de B"
362
+ end
363
+ resultado
364
+ end
365
+
366
+ def +(other)
367
+ i = 0
368
+ tmp = []
369
+ while i < @f*@c
370
+ tmp[i] = @m[i]+other.m[i]
371
+ i=i+1
372
+ end
373
+ tmp
374
+ end
375
+
376
+ def -(other)
377
+ i = 0
378
+ tmp = []
379
+ while i < @f*@c
380
+ tmp[i] = @m[i]-other.m[i]
381
+ i=i+1
382
+ end
383
+ tmp
384
+ end
385
+
386
+ def det(*other)
387
+ resultado = 0
388
+ if other.size == 0
389
+ for i in (0...@c) do
390
+ j = 0;
391
+ adj = []
392
+ z = 0
393
+ for x in (0...@c) do
394
+ for y in (0...@f) do
395
+ if (x != i) && (y != j)
396
+ adj[z] = @m[x+(y*@c)]
397
+ z=z+1
398
+ end
399
+ end
400
+ end
401
+ if ((i+1)+(j+1))%2 == 0
402
+ resultado = resultado + @m[i+(j*@c)]*det(adj)
403
+ else
404
+ resultado = resultado - @m[i+(j*@c)]*det(adj)
405
+ end
406
+ end
407
+ else
408
+ if other[0].size == 1
409
+ tmp = other[0]
410
+ return tmp[0]
411
+ else
412
+ if other[0].size >= 4
413
+ for i in (0...Math.sqrt(other[0].size).to_i) do
414
+ j=0
415
+ adj = []
416
+ z = 0
417
+ for x in (0...Math.sqrt(other[0].size).to_i) do
418
+ for y in (0...Math.sqrt(other[0].size).to_i) do
419
+ if (x != i) && (y != j)
420
+ adj[z] = other[0][x+(y*Math.sqrt(other[0].size).to_i)]
421
+ z=z+1
422
+ end
423
+ end
424
+ end
425
+ if ((i+1)+(j+1))%2 == 0
426
+ tmp = other[0]
427
+ resultado = resultado + tmp[i+(j*Math.sqrt(other[0].size).to_i)]*det(adj)
428
+ else
429
+ tmp = other[0]
430
+ resultado = resultado - tmp[i+(j*Math.sqrt(other[0].size).to_i)]*det(adj)
431
+ end
432
+ end
433
+ end
434
+ end
435
+ end
436
+ return resultado
437
+ end
438
+
439
+ def adj()
440
+ a = Array.new(@f*@c, 0)
441
+ resultado = DenseMatrix.new(@f, @c, a)
442
+ for i in (0...@c) do
443
+ for j in (0...@f) do
444
+ adj = []
445
+ z = 0
446
+ for x in (0...@c) do
447
+ for y in (0...@f) do
448
+ if (x != i) && (y != j)
449
+ adj[z] = @m[x+(y*@c)]
450
+ z=z+1
451
+ end
452
+ end
453
+ end
454
+ if ((i+1)+(j+1))%2 == 0
455
+ resultado[i,j] = det(adj)
456
+ else
457
+ resultado[i,j] = -det(adj)
458
+ end
459
+ end
460
+ end
461
+ return resultado
462
+ end
463
+
464
+ def tras()
465
+ a = Array.new(@f*@c, 0)
466
+ resultado = DenseMatrix.new(@f, @c, a)
467
+ for i in (0...@c) do
468
+ for j in (0...@f) do
469
+ resultado[i,j] = @m[j+(i*@c)]
470
+ end
471
+ end
472
+ return resultado
473
+ end
474
+
475
+ def inv
476
+ determinante = self.det
477
+ if determinante != 0
478
+ a = Array.new(@f*@c, 0)
479
+ resultado = DenseMatrix.new(@f, @c, a)
480
+ resultado = self.adj
481
+ resultado = resultado.tras
482
+ for i in (0...resultado.c) do
483
+ for j in (0...resultado.f) do
484
+ resultado[i,j] = (1/determinante.to_f)*resultado[i,j]
485
+ end
486
+ end
487
+ return resultado
488
+ end
489
+ end
490
+
491
+ def imprimir
492
+ for i in (0...@c*@f) do
493
+ print "#{@m[i].round(2)}\t"
494
+ if i % @c == 2
495
+ print "\n"
496
+ end
497
+ end
498
+ end
499
+
500
+ def /(other1)
501
+ a = Array.new(@f*@c, 0)
502
+ resultado = DenseMatrix.new(@f, @c, a)
503
+ other = other1.inv
504
+ if @f*@c == other.c*other.f
505
+ for i in (0...@c) do
506
+ for j in (0...@f) do
507
+ s = 0
508
+ for k in (0...@c) do
509
+ s = s + (@m[i+(k*@c)] / other.m[k+(j*other.c)])
510
+ end
511
+ resultado[i,j] = s
512
+ end
513
+ end
514
+ else
515
+ puts "Las matriz A debe tener el mismo numero de filas que las columnas de B"
516
+ end
517
+ resultado
518
+ end
519
+ end
520
+
521
+ if __FILE__ == $0
522
+ # a = Fraccion.new(4,5)
523
+ # z = SparseMatrix.new 1000 => { 100 => a, 500 => 200}, 20000 => { 1000 => 3, 9000 => 200}
524
+ # y = SparseMatrix.new 1500 => { 100 => a, 500 => 20}, 20000 => { 1000 => 3, 9000 => 200}
525
+ # z.imp
526
+ # puts "z[1000] = #{z[1000]}"
527
+ # puts "z[1000][200] = #{z[1000][200]}"
528
+ # puts "z[4] = #{z[4]}"
529
+ # puts "z[1000][500] = #{z[1000][500]}"
530
+ # puts "z[0][0] = #{z[0][0]}"
531
+ #
532
+ # puts "-------------------------"
533
+ # x = z.traspuesta
534
+ # x.imp
535
+ # puts "-------------------------"
536
+ #
537
+ # puts "-------------------------"
538
+ # r = z - y
539
+ # puts "-------------------------"
540
+ # r.imp
541
+ # puts "-------------------------"
542
+ # b = SparseVector.new ({ 1 => 10, 2 => 22, 3 => 33 })
543
+ # c = SparseVector.new ({ 1 => 10, 2 => 20, 3 => 30 })
544
+ # x = b + c
545
+ #
546
+ # puts x
547
+ #
548
+ # mi = z.min
549
+ # puts mi
550
+
551
+ a = Matriz.new(3,3,[1,2,3,4,5,6,7,8,9])
552
+ b = a.def_tipo
553
+ puts b.class
554
+ puts "-------------------"
555
+ b.imprimir
556
+
557
+ c = Matriz.new(3,3,[1,0,0,0,0,6,0,0,9])
558
+ d = c.def_tipo
559
+ puts d.class
560
+ puts "-------------------"
561
+ d.imp
562
+
563
+
564
+ end
565
+
566
+ end
567
+