matrixlpp 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.
- checksums.yaml +7 -0
- data/.gitignore +19 -0
- data/Gemfile +7 -0
- data/Guarfile +9 -0
- data/LICENSE.txt +22 -0
- data/README.md +19 -0
- data/Rakefile +24 -0
- data/lib/matrixlpp/gcd.rb +10 -0
- data/lib/matrixlpp/matriz.rb +33 -0
- data/lib/matrixlpp/matriz_densa.rb +138 -0
- data/lib/matrixlpp/matriz_dispersa.rb +199 -0
- data/lib/matrixlpp/matriz_operaciones.rb +91 -0
- data/lib/matrixlpp/racional.rb +163 -0
- data/lib/matrixlpp/version.rb +3 -0
- data/lib/matrixlpp.rb +13 -0
- data/matrixlpp.gemspec +23 -0
- data/spec/matriz_spec.rb +342 -0
- data/test/tc_matrixlpp.rb +95 -0
- metadata +93 -0
checksums.yaml
ADDED
@@ -0,0 +1,7 @@
|
|
1
|
+
---
|
2
|
+
SHA1:
|
3
|
+
metadata.gz: ea46f16e3c9bd15e46bddeeac8e55b2c57d97883
|
4
|
+
data.tar.gz: 7784518a30bd7feb9e3a7aa811682d8a42930b28
|
5
|
+
SHA512:
|
6
|
+
metadata.gz: 40325a5a4ab29487ab37dda1fed9e7f5294056dfd021ce085afed6c0182458a64e37f111a3198071de9a55ee461d3e7519faa0c9558f39d2e21447448533e3df
|
7
|
+
data.tar.gz: b28718eccabd7ba18307853d50b1ffe1d31b16f11f31031e77523c6116660e1a0c1ef31e927454953d32ea7a7bf3c9e50f84117153b62d097c769d206e7e3f2a
|
data/.gitignore
ADDED
data/Gemfile
ADDED
data/Guarfile
ADDED
data/LICENSE.txt
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2013 Javier Mena Mena, Diego Williams Aguilar Montaño
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
Práctica de Laboratorio #11
|
2
|
+
===========================
|
3
|
+
|
4
|
+
|
5
|
+
Equipo-DJ
|
6
|
+
---------
|
7
|
+
Diego Williams Aguilar Montaño
|
8
|
+
Javier Mena Mena
|
9
|
+
|
10
|
+
Descripción de la práctica
|
11
|
+
--------------------------
|
12
|
+
Esta práctica en equipo consiste documentar la gema (utlizando RDOC) y desarrollar métodos con la filosofía de la programación funcional para la representación de Matrices de prácticas anteriores.
|
13
|
+
|
14
|
+
|
15
|
+
---
|
16
|
+
|
17
|
+
Universidad de La Laguna
|
18
|
+
Escuela Técnica Superior de Ingeniería Informática
|
19
|
+
Lenguajes y Paradigmas de la Programación 2013-14
|
data/Rakefile
ADDED
@@ -0,0 +1,24 @@
|
|
1
|
+
$:.unshift File.dirname(__FILE__) + 'lib'
|
2
|
+
$:.unshift './lib', './spec'
|
3
|
+
|
4
|
+
require "bundler/gem_tasks"
|
5
|
+
|
6
|
+
require 'rspec/core/rake_task'
|
7
|
+
RSpec::Core::RakeTask.new
|
8
|
+
|
9
|
+
task :default => :spec
|
10
|
+
|
11
|
+
desc "Espectativas de la clase Matriz"
|
12
|
+
task :test do
|
13
|
+
sh "rspec -I. spec/matriz_spec.rb --format documentation"
|
14
|
+
end
|
15
|
+
|
16
|
+
desc "Espectativas de la clase Matriz, con documentacion HTML"
|
17
|
+
task :thtml do
|
18
|
+
sh "rspec -I. spec/matriz_spec.rb --format html"
|
19
|
+
end
|
20
|
+
|
21
|
+
desc "Pruebas unitarias de las clases Matriz_Densa y Matriz_Dispersa"
|
22
|
+
task :tc do
|
23
|
+
sh "ruby -I. test/tc_matrixlpp.rb"
|
24
|
+
end
|
@@ -0,0 +1,33 @@
|
|
1
|
+
require './lib/matrixlpp/racional.rb'
|
2
|
+
|
3
|
+
module Matrixlpp
|
4
|
+
# Esta clase contendrá el número de filas y columnas de la matriz.
|
5
|
+
class Matriz
|
6
|
+
# Número de filas.
|
7
|
+
attr_reader :N
|
8
|
+
# Número de columnas.
|
9
|
+
attr_reader :M
|
10
|
+
# Vector que contendrá los datos de la matriz.
|
11
|
+
attr_reader :contenido
|
12
|
+
|
13
|
+
# Constructor de la matriz. Crea una matriz de tamaño N*M sin contenido, inicializando sólo N y M.
|
14
|
+
# * *Argumentos* :
|
15
|
+
# - +n+: Número de filas. Debe ser mayor que 0.
|
16
|
+
# - +m+: Número de columnas. Debe ser mayor que 0.
|
17
|
+
def initialize(n, m)
|
18
|
+
raise ArgumentError, 'Indice no valido' unless n.is_a? Fixnum and n > 0 and m.is_a? Fixnum and m > 0
|
19
|
+
|
20
|
+
@N, @M = n, m
|
21
|
+
end
|
22
|
+
|
23
|
+
# Método que permite acceder a un elemento de la matriz. Devuelve _nil_. Redefinido en clases hijas.
|
24
|
+
def get(i, j)
|
25
|
+
nil
|
26
|
+
end
|
27
|
+
# Método que permite almacenar un elemento en la matriz. Devuelve _nil_. Redefinido en clases hijas.
|
28
|
+
def set(i, j, val)
|
29
|
+
nil
|
30
|
+
end
|
31
|
+
|
32
|
+
end
|
33
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require "./lib/matrixlpp/matriz.rb"
|
2
|
+
|
3
|
+
module Matrixlpp
|
4
|
+
# Esta clase permite representar matrices densas. Las matrices densas son aquellas que no tienen más de un 60% de elementos nulos.
|
5
|
+
# Su representación será muy similar a como se suelen representar tradicionalmente.
|
6
|
+
class Matriz_Densa < Matriz
|
7
|
+
# Constructor de la matriz. Crea una matriz de tamaño N*M inicializada a valores nulos.
|
8
|
+
# * *Argumentos* :
|
9
|
+
# - +n+: Número de filas. Debe ser mayor que 0.
|
10
|
+
# - +m+: Número de columnas. Debe ser mayor que 0.
|
11
|
+
def initialize(n, m)
|
12
|
+
super
|
13
|
+
|
14
|
+
@contenido = Array.new(@N,0)
|
15
|
+
i = 0
|
16
|
+
while i < @N
|
17
|
+
@contenido[i] = Array.new(@M,0)
|
18
|
+
i += 1
|
19
|
+
end
|
20
|
+
end
|
21
|
+
# Permite obtener el elemento en la posición (i,j), donde:
|
22
|
+
# * *Argumentos* :
|
23
|
+
# - +i+: Número de fila.
|
24
|
+
# - +j+: Número de columna.
|
25
|
+
# - +value+: Valor a insertar en la matriz.
|
26
|
+
# * *Devuelve* :
|
27
|
+
# - Valor almacenado en la fila +i+ y en la columna +j+. Devuelve nil si +i+ o +j+ están fuera de rango.
|
28
|
+
def get(i, j)
|
29
|
+
if( i < 0 or i >=@N or j < 0 or j >= @M)
|
30
|
+
return nil
|
31
|
+
end
|
32
|
+
|
33
|
+
@contenido[i][j]
|
34
|
+
end
|
35
|
+
# Devuelve el porcentaje de valores nulos que hay en la matriz.
|
36
|
+
# * *Devuelve* :
|
37
|
+
# - Número flotante entre 0 y 1 que represente cuantos valores nulos existen en la matriz densa.
|
38
|
+
def null_percent
|
39
|
+
total = @N*@M
|
40
|
+
no_nulos = 0
|
41
|
+
|
42
|
+
i = 0
|
43
|
+
while(i < @N)
|
44
|
+
j = 0
|
45
|
+
while(j < @M)
|
46
|
+
if(@contenido[i][j] != @contenido[i][j].class.null)
|
47
|
+
no_nulos += 1
|
48
|
+
end
|
49
|
+
j += 1
|
50
|
+
end
|
51
|
+
i += 1
|
52
|
+
end
|
53
|
+
|
54
|
+
nulos = total - no_nulos
|
55
|
+
nulos.to_f/total.to_f
|
56
|
+
end #-- #endmethod null_percent #++
|
57
|
+
|
58
|
+
# Establece el valor _value_ en la posición (i,j) de la matriz, donde:
|
59
|
+
# * *Argumentos* :
|
60
|
+
# - +i+: Número de fila.
|
61
|
+
# - +j+: Número de columna.
|
62
|
+
# - +value+: Valor a insertar en la matriz.
|
63
|
+
|
64
|
+
def set(i, j, value)
|
65
|
+
if( i < 0 or i >=@N or j < 0 or j >= @M)
|
66
|
+
return nil
|
67
|
+
end
|
68
|
+
|
69
|
+
if(!(value.class.respond_to? :null))
|
70
|
+
puts "Se debe definir el metodo \"null\" que devuelva un elemento nulo para la clase #{value.class}"
|
71
|
+
return nil
|
72
|
+
end
|
73
|
+
#--
|
74
|
+
# Contar elementos nulos y comprobar si se hace una matriz dispersa
|
75
|
+
# De momento, no dejamos añadir elementos nulos
|
76
|
+
# ¿o si?
|
77
|
+
#if(value != nil and value != value.class.null) # Y se puede comprobar para todos los tipos si es necesario. (con un método zero, por ejemplo)
|
78
|
+
@contenido[i][j] = value
|
79
|
+
#end
|
80
|
+
#++
|
81
|
+
end
|
82
|
+
# Permite representar de manera gráfica la matriz por consola.
|
83
|
+
# * *Devuelve* :
|
84
|
+
# - Objeto del tipo string con todos los elementos de la matriz.
|
85
|
+
def to_s
|
86
|
+
s = ""
|
87
|
+
i = 0
|
88
|
+
while(i < @N)
|
89
|
+
j = 0
|
90
|
+
while(j < @M)
|
91
|
+
s += "#{@contenido[i][j].to_s}\t"
|
92
|
+
j += 1
|
93
|
+
end
|
94
|
+
s += "\n"
|
95
|
+
i += 1
|
96
|
+
end
|
97
|
+
s
|
98
|
+
end
|
99
|
+
|
100
|
+
# Devuelve el máximo valor almacenado en la matriz.
|
101
|
+
# * *Devuelve* :
|
102
|
+
# - Valor máximo almacenado en la matriz.
|
103
|
+
def max
|
104
|
+
m = get(0,0)
|
105
|
+
i = 0
|
106
|
+
while(i < @N)
|
107
|
+
j = 0
|
108
|
+
while(j < @M)
|
109
|
+
if (get(i,j) > m)
|
110
|
+
m = get(i,j)
|
111
|
+
end
|
112
|
+
j += 1
|
113
|
+
end
|
114
|
+
i += 1
|
115
|
+
end
|
116
|
+
m
|
117
|
+
end
|
118
|
+
|
119
|
+
# Devuelve el mínimo valor almacenado en la matriz.
|
120
|
+
# * *Devuelve* :
|
121
|
+
# - Valor mínimo almacenado en la matriz.
|
122
|
+
def min
|
123
|
+
m = get(0,0)
|
124
|
+
i = 0
|
125
|
+
while(i < @N)
|
126
|
+
j = 0
|
127
|
+
while(j < @M)
|
128
|
+
if (get(i,j) < m)
|
129
|
+
m = get(i,j)
|
130
|
+
end
|
131
|
+
j += 1
|
132
|
+
end
|
133
|
+
i += 1
|
134
|
+
end
|
135
|
+
m
|
136
|
+
end #-- # Method min
|
137
|
+
end # Class
|
138
|
+
end # Module #++
|
@@ -0,0 +1,199 @@
|
|
1
|
+
require "./lib/matrixlpp/matriz.rb"
|
2
|
+
require "./lib/matrixlpp/matriz_densa.rb"
|
3
|
+
|
4
|
+
module Matrixlpp
|
5
|
+
# Esta clase permite representar matrices dispersas. Estas matrices tendrán un 60% o más de valores nulos.
|
6
|
+
# La representación se hará por filas que no tengan elementos nulos, indicando para cada una de ellas qué elementos son no nulos.
|
7
|
+
class Matriz_Dispersa < Matriz
|
8
|
+
# Rellena el array de contenido de la matriz con hashes vacíos. Equivale a una matriz con un 100% de elementos nulos.
|
9
|
+
def reset
|
10
|
+
@contenido = Array.new(@N) #-- # Array con @N filas y ninguna columna (vacio) #++
|
11
|
+
i = 0
|
12
|
+
while(i < @N)
|
13
|
+
@contenido[i] = {}
|
14
|
+
i += 1
|
15
|
+
end
|
16
|
+
end
|
17
|
+
# Constructor de la matriz. Crea una matriz dispersa de tamaño N*M vacía (Array de hashes vacíos).
|
18
|
+
# * *Argumentos* :
|
19
|
+
# - +n+: Número de filas. Debe ser mayor que 0.
|
20
|
+
# - +m+: Número de columnas. Debe ser mayor que 0.
|
21
|
+
def initialize(n, m)
|
22
|
+
super
|
23
|
+
reset
|
24
|
+
end
|
25
|
+
|
26
|
+
# Se devuelve una matriz dispersa a partir de otra matriz pasada por parámetro con los mismos valores. Metodo factoria.
|
27
|
+
# * *Argumentos* :
|
28
|
+
# - +matriz+: Matriz densa. Si sólo tiene valores nulos, la matriz actual se inicializará a vacío.
|
29
|
+
# * *Devuelve* :
|
30
|
+
# - +obj+: Referencia al objeto creado.
|
31
|
+
def self.copy(matriz)
|
32
|
+
raise ArgumentError, 'Tipo invalido' unless matriz.is_a? Matrixlpp::Matriz_Densa
|
33
|
+
obj = new(matriz.N, matriz.M)
|
34
|
+
|
35
|
+
i = 0
|
36
|
+
while(i < matriz.N)
|
37
|
+
j = 0
|
38
|
+
while(j < matriz.M)
|
39
|
+
value = matriz.get(i,j)
|
40
|
+
raise RuntimeError , "No se ha definido \"null\" para la clase #{value.class}" unless value.class.respond_to? :null
|
41
|
+
|
42
|
+
if( value != value.class.null)
|
43
|
+
obj.contenido[i][j] = value
|
44
|
+
end #-- #endif
|
45
|
+
j += 1
|
46
|
+
end #endwhile j
|
47
|
+
i += 1
|
48
|
+
end #endwhile i
|
49
|
+
obj
|
50
|
+
end #endmethod copy #++
|
51
|
+
|
52
|
+
# Devuelve el porcentaje de elementos nulos que tiene la matriz.
|
53
|
+
# * *Devuelve* :
|
54
|
+
# - Número flotante entre 0 y 1 que represente cuantos valores nulos existen en la matriz densa.
|
55
|
+
def null_percent
|
56
|
+
total = @N*@M
|
57
|
+
no_nulos = 0
|
58
|
+
|
59
|
+
i = 0
|
60
|
+
while(i < @N)
|
61
|
+
no_nulos += @contenido[i].size #-- # Nunca habra elementos nulos en alguna fila #++
|
62
|
+
i += 1
|
63
|
+
end
|
64
|
+
|
65
|
+
nulos = total - no_nulos
|
66
|
+
nulos.to_f/total.to_f
|
67
|
+
end #-- #endmethod null_percent #++
|
68
|
+
# Permite obtener el elemento en la posición (i,j), donde:
|
69
|
+
# * *Argumentos* :
|
70
|
+
# - +i+: Número de fila.
|
71
|
+
# - +j+: Número de columna.
|
72
|
+
# * *Devuelve* :
|
73
|
+
# - Valor almacenado en la fila +i+ y en la columna +j+. Devuelve nil si +i+ o +j+ están fuera de rango. Devuelve 0 (valor nulo) si no existe el elemento en la matriz.
|
74
|
+
def get(i, j)
|
75
|
+
if( !(i.is_a? Fixnum) or i < 0 or i >=@N or !(j.is_a? Fixnum) or j < 0 or j >= @M)
|
76
|
+
return nil
|
77
|
+
end
|
78
|
+
|
79
|
+
if(@contenido[i][j] != nil) #-- # Elemento no nulo (esta en el hash)
|
80
|
+
return @contenido[i][j]
|
81
|
+
else # Elemento nulo (no esta en el Hash)
|
82
|
+
return 0
|
83
|
+
end
|
84
|
+
end #endmethod get #++
|
85
|
+
# Establece el valor _value_ en la posición (i,j) de la matriz, donde:
|
86
|
+
# * *Argumentos* :
|
87
|
+
# - +i+: Número de fila.
|
88
|
+
# - +j+: Número de columna.
|
89
|
+
# - +value+: Valor a insertar en la matriz. Si se sobrepasa el número de valores nulos permitidos, no se harán modificaciones en la matriz.
|
90
|
+
def set(i, j, value)
|
91
|
+
if(!(value.class.respond_to? :null))
|
92
|
+
puts "Se debe definir el metodo \"null\" que devuelva un elemento nulo para la clase #{value.class}"
|
93
|
+
return nil
|
94
|
+
end
|
95
|
+
|
96
|
+
if( !(i.is_a? Fixnum) or i < 0 or i >=@N or !(j.is_a? Fixnum) or j < 0 or j >= @M)
|
97
|
+
return nil
|
98
|
+
end
|
99
|
+
|
100
|
+
if(value == nil or value == value.class.null)
|
101
|
+
@contenido[i].delete(j) #-- # Borrar elemento (valor nulo) #++
|
102
|
+
else
|
103
|
+
@contenido[i][j] = value
|
104
|
+
end
|
105
|
+
|
106
|
+
if(null_percent < 0.6) #-- # Si se ha sobrepasado el número de elementos nulos, borramos el último elemento modificado #++
|
107
|
+
@contenido[i].delete(j)
|
108
|
+
puts "Borrado el elemento #{i},#{j} por sobrepasar el numero de elementos no nulos (Porcentaje actual: #{null_percent}"
|
109
|
+
end
|
110
|
+
|
111
|
+
end #-- #endmethod set #++
|
112
|
+
# Permite representar de manera gráfica la matriz por consola.
|
113
|
+
# * *Devuelve* :
|
114
|
+
# - Objeto del tipo string con todos los elementos de la matriz.
|
115
|
+
def to_s
|
116
|
+
#--
|
117
|
+
# Ejemplo: "Fila 0: \nFila 1: 0=>1 1=>3 \nFila 2: \n"
|
118
|
+
# 0 0
|
119
|
+
# 1 3
|
120
|
+
# 0 0
|
121
|
+
#++
|
122
|
+
i = 0
|
123
|
+
output = ""
|
124
|
+
while(i < @N)
|
125
|
+
output += "Fila #{i}: "
|
126
|
+
@contenido[i].sort.each{|k, v| output += "#{k.to_s}=>#{v.to_s} "}
|
127
|
+
output += "\n"
|
128
|
+
i += 1
|
129
|
+
end
|
130
|
+
output
|
131
|
+
end
|
132
|
+
|
133
|
+
# Devuelve el máximo valor no nulo almacenado en la matriz.
|
134
|
+
# * *Devuelve* :
|
135
|
+
# - Valor máximo no nulo almacenado en la matriz.
|
136
|
+
def max
|
137
|
+
if(null_percent == 1.0)
|
138
|
+
return nil #-- # o return 0 #++
|
139
|
+
end
|
140
|
+
#--
|
141
|
+
# Valor máximo: si todos los elementos son menores que el elemento nulo
|
142
|
+
# Se devolverá el mayor elemento no nulo.
|
143
|
+
max = nil
|
144
|
+
|
145
|
+
# Asignar al primer valor no-nulo de la matriz
|
146
|
+
i = 0
|
147
|
+
while(max == nil)
|
148
|
+
if(@contenido[i].size != 0)
|
149
|
+
max = @contenido[i].values[0]
|
150
|
+
end
|
151
|
+
i += 1
|
152
|
+
end
|
153
|
+
|
154
|
+
# Iterar por todos los elementos no nulos para encontrar el maximo
|
155
|
+
i = 0
|
156
|
+
while(i < @contenido.size)
|
157
|
+
if(@contenido[i].values.max != nil and @contenido[i].values.max > max)
|
158
|
+
max = @contenido[i].values.max
|
159
|
+
end
|
160
|
+
i += 1
|
161
|
+
end
|
162
|
+
|
163
|
+
max
|
164
|
+
end #++
|
165
|
+
# Devuelve el mínimo valor no nulo almacenado en la matriz.
|
166
|
+
# * *Devuelve* :
|
167
|
+
# - Valor mínimo no nulo almacenado en la matriz.
|
168
|
+
def min
|
169
|
+
if(null_percent == 1.0)
|
170
|
+
return nil #-- # o return 0 #++
|
171
|
+
end
|
172
|
+
# --
|
173
|
+
# Valor máximo: si todos los elementos son menores que el elemento nulo
|
174
|
+
# Se devolverá el mayor elemento no nulo.
|
175
|
+
min = nil
|
176
|
+
|
177
|
+
# Asignar al primer valor no-nulo de la matriz
|
178
|
+
i = 0
|
179
|
+
while(min == nil)
|
180
|
+
if(@contenido[i].size != 0)
|
181
|
+
min = @contenido[i].values[0]
|
182
|
+
end
|
183
|
+
i += 1
|
184
|
+
end
|
185
|
+
|
186
|
+
# Iterar por todos los elementos no nulos para encontrar el maximo
|
187
|
+
i = 0
|
188
|
+
while(i < @contenido.size)
|
189
|
+
if(@contenido[i].values.min != nil and @contenido[i].values.min < min)
|
190
|
+
min = @contenido[i].values.min
|
191
|
+
end
|
192
|
+
i += 1
|
193
|
+
end
|
194
|
+
|
195
|
+
min
|
196
|
+
end
|
197
|
+
|
198
|
+
end #endclass
|
199
|
+
end #end module #++
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require "./lib/matrixlpp/matriz.rb"
|
2
|
+
require "./lib/matrixlpp/matriz_dispersa.rb"
|
3
|
+
require "./lib/matrixlpp/matriz_densa.rb"
|
4
|
+
|
5
|
+
module Matrixlpp
|
6
|
+
class Matriz
|
7
|
+
# Permite sumar matrices (dispersas o densas) de iguales dimensiones.
|
8
|
+
# * *Argumentos* :
|
9
|
+
# - +other+: Matriz densa o dispersa. Debe ser de igual tamaño que la actual.
|
10
|
+
# * *Devuelve* :
|
11
|
+
# - Matriz de tamaño N*M resultado de la suma de la matriz actual con +other+. Si el porcentaje de valores nulos es mayor al 60%, se devuelve una matriz dispersa. Si no, se devuelve una matriz densa.
|
12
|
+
def +(other)
|
13
|
+
raise ArgumentError , 'Tipo invalido' unless other.is_a? Matriz
|
14
|
+
raise ArgumentError , 'Matriz no compatible' unless @N == other.N and @M == other.M
|
15
|
+
c = Matriz_Densa.new(@N, @M)
|
16
|
+
|
17
|
+
#(0...@N).each do |i|
|
18
|
+
#(0...@M).each do |j|
|
19
|
+
(@N).times do |i|
|
20
|
+
(@M).times do |j|
|
21
|
+
c.set(i, j, get(i,j) + other.get(i,j))
|
22
|
+
end
|
23
|
+
end
|
24
|
+
|
25
|
+
if (c.null_percent > 0.6)
|
26
|
+
return Matrixlpp::Matriz_Dispersa.copy(c)
|
27
|
+
else
|
28
|
+
return c
|
29
|
+
end
|
30
|
+
end # +(other) #++
|
31
|
+
|
32
|
+
# Permite restar matrices (dispersas o densas) de iguales dimensiones.
|
33
|
+
# * *Argumentos* :
|
34
|
+
# - +other+: Matriz densa o dispersa. Debe ser de igual tamaño que la actual.
|
35
|
+
# * *Devuelve* :
|
36
|
+
# - Matriz de tamaño N*M resultado de la resta de la matriz actual con +other+. Si el porcentaje de valores nulos es mayor al 60%, se devuelve una matriz dispersa. Si no, se devuelve una matriz densa.
|
37
|
+
def -(other)
|
38
|
+
raise ArgumentError , 'Tipo invalido' unless other.is_a? Matriz
|
39
|
+
raise ArgumentError , 'Matriz no compatible' unless @N == other.N and @M == other.M
|
40
|
+
c = Matriz_Densa.new(@N, @M)
|
41
|
+
|
42
|
+
(@N).times do |i|
|
43
|
+
(@M).times do |j|
|
44
|
+
c.set(i, j, get(i,j) - other.get(i,j))
|
45
|
+
end
|
46
|
+
end
|
47
|
+
|
48
|
+
if (c.null_percent > 0.6)
|
49
|
+
return Matrixlpp::Matriz_Dispersa.copy(c)
|
50
|
+
else
|
51
|
+
return c
|
52
|
+
end
|
53
|
+
end # -(other) #++
|
54
|
+
|
55
|
+
# Permite multiplicar un elemento a una matriz.
|
56
|
+
def *(other)
|
57
|
+
raise ArgumentError , 'Parametro invalido' unless other.is_a? Numeric or other.is_a? Matriz
|
58
|
+
|
59
|
+
if(other.is_a? Numeric) # Matriz * numero
|
60
|
+
c = Matriz_Densa.new(@N, @M)
|
61
|
+
|
62
|
+
(@N).times do |i|
|
63
|
+
(@M).times do |j|
|
64
|
+
c.set(i, j, get(i,j)*other)
|
65
|
+
end
|
66
|
+
end
|
67
|
+
else # Matriz * Matriz
|
68
|
+
raise ArgumentError , 'Matriz no compatible (A.N == B.M)' unless @M == other.N
|
69
|
+
c = Matriz_Densa.new(@N, other.M)
|
70
|
+
|
71
|
+
(@N).times do |i|
|
72
|
+
(other.M).times do |j|
|
73
|
+
buffer = (0...@M).inject(0) { |acc, k| get(i, k) * other.get(k,j) + acc }
|
74
|
+
c.set(i, j, buffer)
|
75
|
+
#(@M).times do |k|
|
76
|
+
# Esto NO es programación funcional...
|
77
|
+
# c.set(i, j, get(i, k) * other.get(k,j) + c.get(i,j))
|
78
|
+
#end
|
79
|
+
end
|
80
|
+
end
|
81
|
+
end
|
82
|
+
|
83
|
+
if (c.null_percent > 0.6)
|
84
|
+
return Matrixlpp::Matriz_Dispersa.copy(c)
|
85
|
+
else
|
86
|
+
return c
|
87
|
+
end
|
88
|
+
end # *(other) #++
|
89
|
+
|
90
|
+
end
|
91
|
+
end
|
@@ -0,0 +1,163 @@
|
|
1
|
+
require "./lib/matrixlpp/gcd.rb"
|
2
|
+
|
3
|
+
module Matrixlpp
|
4
|
+
# Esta clase permite representar números racionales de la forma _numerador/denominador_.
|
5
|
+
class Fraccion
|
6
|
+
#--
|
7
|
+
# Módulos usados
|
8
|
+
#++
|
9
|
+
include Comparable
|
10
|
+
|
11
|
+
#--
|
12
|
+
# Métodos principales
|
13
|
+
#++
|
14
|
+
# Los parámetros que se pasan son el numerador y el denominador, respectivamente:
|
15
|
+
# * *x*: Numerador.
|
16
|
+
# * *y*: Denominador.
|
17
|
+
def initialize(x,y)
|
18
|
+
raise ArgumentError , 'Argumentos no enteros.' unless x.is_a? Fixnum and y.is_a? Fixnum
|
19
|
+
raise ArgumentError , 'Denominador nulo.' unless y != 0
|
20
|
+
|
21
|
+
@num, @den = x, y
|
22
|
+
reducir
|
23
|
+
#--
|
24
|
+
# En caso de ser negativa, la fracción será -a/b, y no a/(-b)
|
25
|
+
#++
|
26
|
+
if(@num < 0 && @den < 0)
|
27
|
+
@num = -@num
|
28
|
+
@den = -@den
|
29
|
+
elsif(@den < 0)
|
30
|
+
@den = -@den
|
31
|
+
@num = -@num
|
32
|
+
end
|
33
|
+
end
|
34
|
+
# Devuelve el valor del numerador.
|
35
|
+
def num()
|
36
|
+
@num
|
37
|
+
end
|
38
|
+
# Devuelve el valor del denominador.
|
39
|
+
def den()
|
40
|
+
@den
|
41
|
+
end
|
42
|
+
# Este método permite invertir el orden de los operandos para posibilitar las operaciones aritméticas.
|
43
|
+
def coerce(other)
|
44
|
+
[Fraccion.new(other,1),self]
|
45
|
+
end
|
46
|
+
# Devuelve la fracción nula (con valor 0) _0/1_.
|
47
|
+
def self.null
|
48
|
+
Fraccion.new(0,1)
|
49
|
+
end
|
50
|
+
# Devuelve la representación de la fracción como "_numerador/denominador_".
|
51
|
+
def to_s
|
52
|
+
"#{@num}/#{@den}"
|
53
|
+
end
|
54
|
+
# Reduce la fracción a su mínima expresión.
|
55
|
+
def reducir
|
56
|
+
mcd = Matrixlpp::gcd(@num,@den)
|
57
|
+
@num = @num / mcd
|
58
|
+
@den = @den / mcd
|
59
|
+
end
|
60
|
+
# Permite usar números en representación de punto flotante en el numerador y en el denominador.
|
61
|
+
def to_f
|
62
|
+
@num.to_f/@den.to_f
|
63
|
+
end
|
64
|
+
|
65
|
+
#--
|
66
|
+
# Operadores unarios
|
67
|
+
#++
|
68
|
+
|
69
|
+
# Devulve el valor absoluto de una fracción
|
70
|
+
def abs
|
71
|
+
a, b = @num, @den
|
72
|
+
if @num < 0
|
73
|
+
a = @num * (-1)
|
74
|
+
end
|
75
|
+
if @den < 0
|
76
|
+
b = @den * (-1)
|
77
|
+
end
|
78
|
+
Fraccion.new(a.to_i,b.to_i)
|
79
|
+
end
|
80
|
+
# Devuelve la fracción recíproca.
|
81
|
+
def reciprocal
|
82
|
+
aux = @num
|
83
|
+
@num = @den
|
84
|
+
@den = aux
|
85
|
+
Fraccion.new(@num,@den)
|
86
|
+
end
|
87
|
+
# Devuelve la fracción con signo negativo.
|
88
|
+
def -@ # Operación negación
|
89
|
+
Fraccion.new(-@num, @den)
|
90
|
+
end
|
91
|
+
|
92
|
+
#--
|
93
|
+
# Operadores aritméticos
|
94
|
+
#++
|
95
|
+
|
96
|
+
# Permite sumar otro elemento a una fracción.
|
97
|
+
def +(other) #-- # Operación suma #++
|
98
|
+
if(other.respond_to? :den and other.respond_to? :num)
|
99
|
+
Fraccion.new(@num*other.den + @den*other.num, @den*other.den) # a/b + c/d = (a*d + b*c)/(b*d)
|
100
|
+
else
|
101
|
+
Fraccion.new(@num + @den*other, @den) # a/b + c = (a + b*c)/b
|
102
|
+
end
|
103
|
+
end
|
104
|
+
# Permite restar otro elemento a una fracción.
|
105
|
+
def -(other) #-- # Operación resta #++
|
106
|
+
if(other.respond_to? :den and other.respond_to? :num)
|
107
|
+
Fraccion.new(@num*other.den - @den*other.num, @den*other.den) # a/b - c/d = (a*d - b*c)/(b*d)
|
108
|
+
else
|
109
|
+
Fraccion.new(@num - @den*other, @den) # a/b - c = (a - b*c)/b
|
110
|
+
end
|
111
|
+
end
|
112
|
+
# Permite multiplicar otro elemento a una fracción.
|
113
|
+
def *(other) #-- # Operación producto #++
|
114
|
+
if(other.respond_to? :den and other.respond_to? :num)
|
115
|
+
if(@num*other.num == 0)
|
116
|
+
Fraccion.null
|
117
|
+
else
|
118
|
+
Fraccion.new(@num*other.num, @den*other.den) # a/b * c/d = (a*c)/(b*d)
|
119
|
+
end
|
120
|
+
else
|
121
|
+
Fraccion.new(@num*other, @den) # a/b * c = (a*c)/b
|
122
|
+
end
|
123
|
+
end
|
124
|
+
# Permite dividir otro elemento a una fracción.
|
125
|
+
def /(other) #-- # Operación división #++
|
126
|
+
if(other.respond_to? :den and other.respond_to? :num)
|
127
|
+
if(other.num == 0)
|
128
|
+
Fraccion.null
|
129
|
+
else
|
130
|
+
Fraccion.new(@num*other.den, @den*other.num) # a/b / c/d = (a*d)/(b*c)
|
131
|
+
end
|
132
|
+
else
|
133
|
+
if(other == 0)
|
134
|
+
Fraccion.null
|
135
|
+
else
|
136
|
+
Fraccion.new(@num, @den*other)
|
137
|
+
end
|
138
|
+
end
|
139
|
+
end
|
140
|
+
# Permite obtener el resto entre la división de una fracción y otro elemento.
|
141
|
+
def %(other) #-- # Operación módulo #++
|
142
|
+
raise ArgumentError, 'Argumento no racional' unless other.is_a? Fraccion
|
143
|
+
|
144
|
+
Fraccion.new(0,1) #-- # Resto de una división de fracciones = siempre nulo (0/1) #++
|
145
|
+
end
|
146
|
+
|
147
|
+
#--
|
148
|
+
# Operadores comparacionales
|
149
|
+
#++
|
150
|
+
|
151
|
+
# Este método permite hacer operaciones comparacionales entre una fracción y otro elemento.
|
152
|
+
def <=> (other)
|
153
|
+
#-- #raise ArgumentError, 'Argumento no racional' unless other.is_a? Fraccion #++
|
154
|
+
|
155
|
+
#-- # a/b <=> c/d -> (a*d)/(b*d) <=> (c*b)/(d*b) -> a*d <=> c*b #++
|
156
|
+
if(other.respond_to? :den and other.respond_to? :num)
|
157
|
+
(@num * other.den) <=> (other.num * @den)
|
158
|
+
else
|
159
|
+
(@num.to_f / @den.to_f) <=> (other)
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
163
|
+
end
|
data/lib/matrixlpp.rb
ADDED
@@ -0,0 +1,13 @@
|
|
1
|
+
require "./lib/matrixlpp/version"
|
2
|
+
require "./lib/matrixlpp/matriz.rb"
|
3
|
+
require "./lib/matrixlpp/matriz_densa.rb"
|
4
|
+
require "./lib/matrixlpp/matriz_dispersa.rb"
|
5
|
+
require "./lib/matrixlpp/matriz_operaciones.rb"
|
6
|
+
|
7
|
+
require "./lib/matrixlpp/racional.rb"
|
8
|
+
require "./lib/matrixlpp/gcd.rb"
|
9
|
+
|
10
|
+
|
11
|
+
module Matrixlpp
|
12
|
+
# Your code goes here...
|
13
|
+
end
|
data/matrixlpp.gemspec
ADDED
@@ -0,0 +1,23 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'matrixlpp/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "matrixlpp"
|
8
|
+
spec.version = Matrixlpp::VERSION
|
9
|
+
spec.authors = ["Javier Mena Mena", "Diego Williams Aguilar Montaño"]
|
10
|
+
spec.email = ["alu0100454741@ull.edu.es","alu0100592368@ull.edu.es"]
|
11
|
+
spec.description = %q{Esta es una clase Matrix}
|
12
|
+
spec.summary = %q{Contiene todo lo necesario para definir una clase matrix}
|
13
|
+
spec.homepage = "https://github.com/alu0100454741/EquipoDJ-prct11"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
22
|
+
spec.add_development_dependency "rake"
|
23
|
+
end
|
data/spec/matriz_spec.rb
ADDED
@@ -0,0 +1,342 @@
|
|
1
|
+
require "./lib/matrixlpp.rb"
|
2
|
+
|
3
|
+
describe Matrixlpp::Matriz do
|
4
|
+
before :each do
|
5
|
+
@m1 = Matrixlpp::Matriz.new(5, 5)
|
6
|
+
end
|
7
|
+
describe " # Almacenamiento de matrices. " do
|
8
|
+
it " # Se debe almacenar el numero de filas." do
|
9
|
+
@m1.N
|
10
|
+
end
|
11
|
+
it " # Se debe almacenar el numero de columnas." do
|
12
|
+
@m1.M
|
13
|
+
end
|
14
|
+
it " # Se debe almacenar un contenido." do
|
15
|
+
@m1.contenido
|
16
|
+
end
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe Matrixlpp::Matriz_Densa do
|
21
|
+
before :all do
|
22
|
+
class Fixnum
|
23
|
+
def self.null
|
24
|
+
0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
class String
|
29
|
+
def self.null
|
30
|
+
""
|
31
|
+
end
|
32
|
+
end
|
33
|
+
|
34
|
+
class Float
|
35
|
+
def self.null
|
36
|
+
0.0
|
37
|
+
end
|
38
|
+
end
|
39
|
+
|
40
|
+
# Etc
|
41
|
+
end
|
42
|
+
|
43
|
+
before :each do
|
44
|
+
@m1 = Matrixlpp::Matriz_Densa.new(2,2)
|
45
|
+
@m2 = Matrixlpp::Matriz_Densa.new(2,2)
|
46
|
+
|
47
|
+
@m1.set(0,0,1)
|
48
|
+
@m1.set(0,1,2)
|
49
|
+
@m1.set(1,0,3)
|
50
|
+
@m1.set(1,1,4)
|
51
|
+
|
52
|
+
@m2.set(0,0,5)
|
53
|
+
@m2.set(0,1,6)
|
54
|
+
@m2.set(1,0,7)
|
55
|
+
@m2.set(1,1,8)
|
56
|
+
|
57
|
+
end
|
58
|
+
describe " # Almacenamiento de matrices. " do
|
59
|
+
it " # Se debe poder acceder a los datos almacenados en la matriz " do
|
60
|
+
@m1.get(0,0).should eq(1)
|
61
|
+
@m1.get(0,1).should eq(2)
|
62
|
+
end
|
63
|
+
it " # Se deben poder modificar los datos almacenados en la matriz " do
|
64
|
+
@m1.set(0,0,5)
|
65
|
+
@m1.get(0,0).should eq(5)
|
66
|
+
|
67
|
+
@m1.set(0,1,8)
|
68
|
+
@m1.get(0,1).should eq(8)
|
69
|
+
end
|
70
|
+
it " # Se deben poder almacenar todo tipo de datos numericos (flotantes, enteros, etc...) " do
|
71
|
+
@m1.set(0,0,3.0)
|
72
|
+
@m1.set(0,1,-6)
|
73
|
+
@m1.to_s.should == "3.0\t-6\t\n3\t4\t\n"
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
describe " # Operaciones con matrices densas. " do
|
78
|
+
it " # Se debe poder sumar dos matrices " do
|
79
|
+
@m3 = Matrixlpp::Matriz_Densa.new(2,2)
|
80
|
+
@m3.set(0,0,6)
|
81
|
+
@m3.set(0,1,8)
|
82
|
+
@m3.set(1,0,10)
|
83
|
+
@m3.set(1,1,12)
|
84
|
+
|
85
|
+
(@m1+@m2).to_s.should eq(@m3.to_s)
|
86
|
+
end
|
87
|
+
|
88
|
+
it " # Se debe poder restar dos matrices " do
|
89
|
+
@m3 = Matrixlpp::Matriz_Densa.new(2,2)
|
90
|
+
@m3.set(0,0,4)
|
91
|
+
@m3.set(0,1,4)
|
92
|
+
@m3.set(1,0,4)
|
93
|
+
@m3.set(1,1,4)
|
94
|
+
|
95
|
+
(@m2-@m1).to_s.should eq(@m3.to_s)
|
96
|
+
end
|
97
|
+
it " # Se debe poder multiplicar dos matrices " do
|
98
|
+
@m3 = Matrixlpp::Matriz_Densa.new(2,2)
|
99
|
+
@m3.set(0,0,19)
|
100
|
+
@m3.set(0,1,22)
|
101
|
+
@m3.set(1,0,43)
|
102
|
+
@m3.set(1,1,50)
|
103
|
+
|
104
|
+
(@m1*@m2).to_s.should eq(@m3.to_s)
|
105
|
+
end
|
106
|
+
it " # Si una m. densa tiene mas de un 60% de nulos, debe ser dispersa." do
|
107
|
+
@m_neg = Matrixlpp::Matriz_Densa.new(2,2)
|
108
|
+
@m_neg.set(0,0,-1)
|
109
|
+
@m_neg.set(0,1,-2)
|
110
|
+
@m_neg.set(1,0,-3)
|
111
|
+
@m_neg.set(1,1,-1)
|
112
|
+
|
113
|
+
@m3 = Matrixlpp::Matriz_Dispersa.new(2,2)
|
114
|
+
@m3.set(1,1,3)
|
115
|
+
|
116
|
+
(@m1+@m_neg).to_s.should eq(@m3.to_s)
|
117
|
+
end
|
118
|
+
it " # Se debe poder operar con Fracciones." do
|
119
|
+
@mf = Matrixlpp::Matriz_Densa.new(2,2)
|
120
|
+
@mf.set(0,0,Matrixlpp::Fraccion.new(1,3))
|
121
|
+
@mf.set(0,1,Matrixlpp::Fraccion.new(1,3))
|
122
|
+
@mf.set(1,0,Matrixlpp::Fraccion.new(1,3))
|
123
|
+
@mf.set(1,1,Matrixlpp::Fraccion.new(1,3))
|
124
|
+
|
125
|
+
@mf_res = Matrixlpp::Matriz_Densa.new(2,2)
|
126
|
+
@mf_res.set(0,0,Matrixlpp::Fraccion.new(2,3))
|
127
|
+
@mf_res.set(0,1,Matrixlpp::Fraccion.new(2,3))
|
128
|
+
@mf_res.set(1,0,Matrixlpp::Fraccion.new(2,3))
|
129
|
+
@mf_res.set(1,1,Matrixlpp::Fraccion.new(2,3))
|
130
|
+
|
131
|
+
(@mf+@mf).to_s.should eq(@mf_res.to_s)
|
132
|
+
|
133
|
+
@mf1 = Matrixlpp::Matriz_Densa.new(2,2)
|
134
|
+
@mf1.set(1,0,Matrixlpp::Fraccion.new(1,4))
|
135
|
+
|
136
|
+
@mf2 = Matrixlpp::Matriz_Densa.new(2,2)
|
137
|
+
@mf2.set(0,0,1)
|
138
|
+
|
139
|
+
@mf_res = Matrixlpp::Matriz_Dispersa.new(2,2)
|
140
|
+
@mf_res.set(1,0,Matrixlpp::Fraccion.new(1,4))
|
141
|
+
|
142
|
+
(@mf1 * @mf2).to_s.should == @mf_res.to_s
|
143
|
+
|
144
|
+
end
|
145
|
+
end
|
146
|
+
describe " # Operaciones varias. " do
|
147
|
+
it " # Se debe poder calcular el maximo de una matriz densa (elemento no nulo)" do
|
148
|
+
@m1.max.should == 4
|
149
|
+
end
|
150
|
+
it " # Se debe poder calcular el minimo de una matriz densa (elemento no nulo)" do
|
151
|
+
@m2.min.should == 5
|
152
|
+
end
|
153
|
+
end
|
154
|
+
end
|
155
|
+
|
156
|
+
|
157
|
+
describe Matrixlpp::Matriz_Dispersa do
|
158
|
+
before :all do
|
159
|
+
class Fixnum
|
160
|
+
def self.null
|
161
|
+
0
|
162
|
+
end
|
163
|
+
end
|
164
|
+
|
165
|
+
class String
|
166
|
+
def self.null
|
167
|
+
""
|
168
|
+
end
|
169
|
+
end
|
170
|
+
|
171
|
+
class Float
|
172
|
+
def self.null
|
173
|
+
0.0
|
174
|
+
end
|
175
|
+
end
|
176
|
+
|
177
|
+
# Etc
|
178
|
+
end
|
179
|
+
|
180
|
+
before :each do
|
181
|
+
@m1 = Matrixlpp::Matriz_Densa.new(3,2)
|
182
|
+
|
183
|
+
@m1.set(0,0,0)
|
184
|
+
@m1.set(0,1,0)
|
185
|
+
|
186
|
+
@m1.set(1,0,1)
|
187
|
+
@m1.set(1,1,3)
|
188
|
+
|
189
|
+
@m1.set(2,0,0)
|
190
|
+
@m1.set(2,1,0)
|
191
|
+
|
192
|
+
@md1 = Matrixlpp::Matriz_Dispersa.copy(@m1)
|
193
|
+
@md2 = Matrixlpp::Matriz_Dispersa.new(3, 2)
|
194
|
+
|
195
|
+
end
|
196
|
+
|
197
|
+
describe " # Almacenamiento de matrices. " do
|
198
|
+
it " # Se debe poder crear matrices dispersas vacias o a partir de matrices densas." do
|
199
|
+
Matrixlpp::Matriz_Dispersa.new(5, 5)
|
200
|
+
Matrixlpp::Matriz_Dispersa.copy(@m1)
|
201
|
+
end
|
202
|
+
|
203
|
+
it " # Se debe poder calcular el porcentaje de elementos nulos de la matriz dispersa." do
|
204
|
+
@md2.null_percent.should == 1.0
|
205
|
+
@md1.null_percent.should == 4.0/6.0
|
206
|
+
end
|
207
|
+
|
208
|
+
it " # Se debe poder acceder a los elementos de la matriz dispersa." do
|
209
|
+
@md2.get(0,0).should == 0
|
210
|
+
|
211
|
+
@md1.get(1,1).should == 3
|
212
|
+
@md1.get(1,0).should == 1
|
213
|
+
@md1.get(0,0).should == 0
|
214
|
+
|
215
|
+
@md1.get(10,10).should == nil
|
216
|
+
end
|
217
|
+
|
218
|
+
it " # Se deben poder modificar los elementos de la matriz dispersa." do
|
219
|
+
@md2.set(0,0,1)
|
220
|
+
@md2.get(0,0).should == 1
|
221
|
+
|
222
|
+
@md2.set(0,1,1)
|
223
|
+
@md2.set(1,0,1)
|
224
|
+
@md2.set(1,1,1)
|
225
|
+
@md2.set(2,0,1)
|
226
|
+
@md2.set(2,1,1)
|
227
|
+
|
228
|
+
# Elemento nulo debido a que ha sobrepasado el porcentaje maximo de valores nulos
|
229
|
+
@md2.get(2,1).should == 0
|
230
|
+
|
231
|
+
@md1.set(1,1,4)
|
232
|
+
@md1.set(1,0,2)
|
233
|
+
@md1.get(1,1).should == 4
|
234
|
+
@md1.get(1,0).should == 2
|
235
|
+
|
236
|
+
@md1.get(0,0).should == 0
|
237
|
+
end
|
238
|
+
|
239
|
+
it " # Se debe poder transformar una matriz dispersa a una cadena de caracteres." do
|
240
|
+
@md1.to_s.should == "Fila 0: \nFila 1: 0=>1 1=>3 \nFila 2: \n"
|
241
|
+
@md2.to_s.should == "Fila 0: \nFila 1: \nFila 2: \n"
|
242
|
+
end
|
243
|
+
|
244
|
+
|
245
|
+
end
|
246
|
+
|
247
|
+
describe " # Operaciones con matrices dispersas. " do
|
248
|
+
it " # Se debe poder sumar dos matrices " do
|
249
|
+
@md3 = Matrixlpp::Matriz_Dispersa.new(3,2)
|
250
|
+
@md3.set(0,0,0)
|
251
|
+
@md3.set(0,1,0)
|
252
|
+
@md3.set(1,0,1)
|
253
|
+
@md3.set(1,1,3)
|
254
|
+
@md3.set(2,0,0)
|
255
|
+
@md3.set(2,1,0)
|
256
|
+
|
257
|
+
|
258
|
+
(@md1+@md2).to_s.should eq(@md3.to_s)
|
259
|
+
end
|
260
|
+
it " # Se debe poder restar dos matrices " do
|
261
|
+
@md3 = Matrixlpp::Matriz_Dispersa.new(3,2)
|
262
|
+
@md3.set(0,0,0)
|
263
|
+
@md3.set(0,1,0)
|
264
|
+
@md3.set(1,0,-1)
|
265
|
+
@md3.set(1,1,-3)
|
266
|
+
@md3.set(2,0,0)
|
267
|
+
@md3.set(2,1,0)
|
268
|
+
|
269
|
+
(@md2-@md1).to_s.should eq(@md3.to_s)
|
270
|
+
end
|
271
|
+
it " # Se debe poder multiplicar dos matrices " do
|
272
|
+
@md4 = Matrixlpp::Matriz_Dispersa.new(2,3)
|
273
|
+
@md4.set(1,0,-1)
|
274
|
+
@md4.set(1,1,-1)
|
275
|
+
@md4.set(1,2,0)
|
276
|
+
|
277
|
+
@md3 = Matrixlpp::Matriz_Dispersa.new(3,3)
|
278
|
+
@md3.set(0,0,0)
|
279
|
+
@md3.set(0,1,0)
|
280
|
+
@md3.set(0,2,0)
|
281
|
+
@md3.set(1,0,-3)
|
282
|
+
@md3.set(1,1,-3)
|
283
|
+
@md3.set(1,2,0)
|
284
|
+
@md3.set(2,0,0)
|
285
|
+
@md3.set(2,1,0)
|
286
|
+
@md3.set(2,2,0)
|
287
|
+
|
288
|
+
(@md1*@md4).to_s.should eq(@md3.to_s)
|
289
|
+
end
|
290
|
+
it " # Se debe poder hacer operaciones con Fracciones. " do
|
291
|
+
@mf1 = Matrixlpp::Matriz_Dispersa.new(2,2)
|
292
|
+
@mf1.set(1,0,Matrixlpp::Fraccion.new(1,4))
|
293
|
+
|
294
|
+
@mf2 = Matrixlpp::Matriz_Dispersa.new(2,2)
|
295
|
+
@mf2.set(1,0,Matrixlpp::Fraccion.new(-1,4))
|
296
|
+
|
297
|
+
@mf_res = Matrixlpp::Matriz_Dispersa.new(2,2)
|
298
|
+
@mf_res.set(1,0,Matrixlpp::Fraccion.new(1,2))
|
299
|
+
|
300
|
+
(@mf1-@mf2).to_s.should eq(@mf_res.to_s)
|
301
|
+
|
302
|
+
|
303
|
+
@mf3 = Matrixlpp::Matriz_Dispersa.new(2,2)
|
304
|
+
@mf3.set(1,0,Matrixlpp::Fraccion.new(1,4))
|
305
|
+
|
306
|
+
@mf4 = Matrixlpp::Matriz_Dispersa.new(2,2)
|
307
|
+
@mf4.set(0,0,1)
|
308
|
+
|
309
|
+
(@mf3 * @mf4).to_s.should == @mf3.to_s
|
310
|
+
|
311
|
+
@mf5 = Matrixlpp::Matriz_Densa.new(2,2)
|
312
|
+
@mf6 = Matrixlpp::Matriz_Dispersa.new(2,2)
|
313
|
+
|
314
|
+
@mf5.set(0,0,3)
|
315
|
+
@mf5.set(0,1,4)
|
316
|
+
@mf5.set(1,0,5)
|
317
|
+
@mf5.set(1,1,6)
|
318
|
+
|
319
|
+
@mf6.set(0,0,Matrixlpp::Fraccion.new(1,2))
|
320
|
+
|
321
|
+
@mf_res2 = Matrixlpp::Matriz_Densa.new(2,2)
|
322
|
+
@mf_res2.set(0,0,Matrixlpp::Fraccion.new(7,2))
|
323
|
+
@mf_res2.set(0,1,4)
|
324
|
+
@mf_res2.set(1,0,5)
|
325
|
+
@mf_res2.set(1,1,6)
|
326
|
+
|
327
|
+
(@mf5+@mf6).to_s.should == @mf_res2.to_s
|
328
|
+
|
329
|
+
end
|
330
|
+
|
331
|
+
|
332
|
+
end
|
333
|
+
describe " # Operaciones varias. " do
|
334
|
+
it " # Se debe poder calcular el maximo de una matriz densa (elemento no nulo)" do
|
335
|
+
@md1.set(1,0,4)
|
336
|
+
@md1.max.should == 4
|
337
|
+
end
|
338
|
+
it " # Se debe poder calcular el minimo de una matriz densa (elemento no nulo)" do
|
339
|
+
@md1.min.should == 1
|
340
|
+
end
|
341
|
+
end
|
342
|
+
end
|
@@ -0,0 +1,95 @@
|
|
1
|
+
# Implementar en este fichero las Pruebas Unitarias de nuestra gema
|
2
|
+
|
3
|
+
require "./lib/matrixlpp.rb"
|
4
|
+
require "test/unit"
|
5
|
+
|
6
|
+
# Fixnum
|
7
|
+
class Fixnum
|
8
|
+
# Devuelve el valor nulo de la clase Fixnum (0).
|
9
|
+
def self.null
|
10
|
+
0
|
11
|
+
end
|
12
|
+
end
|
13
|
+
#String
|
14
|
+
class String
|
15
|
+
# Devuelve el valor nulo de la clase String (cadena vacía).
|
16
|
+
def self.null
|
17
|
+
""
|
18
|
+
end
|
19
|
+
end
|
20
|
+
#Float
|
21
|
+
class Float
|
22
|
+
# Devuelve el valor nulo de la clase Float (0.0).
|
23
|
+
def self.null
|
24
|
+
0.0
|
25
|
+
end
|
26
|
+
end
|
27
|
+
|
28
|
+
# Clase de pruebas unitarias.
|
29
|
+
class Test_Matriz < Test::Unit::TestCase
|
30
|
+
# En este método se prueba que la suma de dos matrices densas @m1 y @m2 coincida con una matriz resultado densa @m3.
|
31
|
+
def test_simple
|
32
|
+
@m1 = Matrixlpp::Matriz_Densa.new(2,2)
|
33
|
+
@m2 = Matrixlpp::Matriz_Densa.new(2,2)
|
34
|
+
@m3 = Matrixlpp::Matriz_Densa.new(2,2)
|
35
|
+
|
36
|
+
@m1.set(0,0,1)
|
37
|
+
@m1.set(0,1,2)
|
38
|
+
@m1.set(1,0,3)
|
39
|
+
@m1.set(1,1,4)
|
40
|
+
|
41
|
+
@m2.set(0,0,5)
|
42
|
+
@m2.set(0,1,6)
|
43
|
+
@m2.set(1,0,7)
|
44
|
+
@m2.set(1,1,8)
|
45
|
+
|
46
|
+
@m3.set(0,0,6)
|
47
|
+
@m3.set(0,1,8)
|
48
|
+
@m3.set(1,0,10)
|
49
|
+
@m3.set(1,1,12)
|
50
|
+
|
51
|
+
|
52
|
+
assert_equal(@m3.to_s,(@m1+@m2).to_s)
|
53
|
+
end
|
54
|
+
# En este método se prueba que la resta entre dos matrices dispersas @md1 y @md2 coincida con una matriz dispersa resultado @m3.
|
55
|
+
def test_simple2
|
56
|
+
@md1 = Matrixlpp::Matriz_Dispersa.new(2,2)
|
57
|
+
@md2 = Matrixlpp::Matriz_Dispersa.new(2,2)
|
58
|
+
@m3 = Matrixlpp::Matriz_Dispersa.new(2,2)
|
59
|
+
|
60
|
+
@md1.set(0,0,0)
|
61
|
+
@md1.set(0,1,0)
|
62
|
+
@md1.set(1,0,5)
|
63
|
+
@md1.set(1,1,0)
|
64
|
+
|
65
|
+
@md2.set(0,0,0)
|
66
|
+
@md2.set(0,1,0)
|
67
|
+
@md2.set(1,0,3)
|
68
|
+
@md2.set(1,1,0)
|
69
|
+
|
70
|
+
@m3.set(0,0,0)
|
71
|
+
@m3.set(0,1,0)
|
72
|
+
@m3.set(1,0,2)
|
73
|
+
@m3.set(1,1,0)
|
74
|
+
|
75
|
+
assert_equal(@m3.to_s,(@md1-@md2).to_s)
|
76
|
+
|
77
|
+
|
78
|
+
end
|
79
|
+
# En este método se prueba que se de un fallo de tipo (TypeError).
|
80
|
+
def test_typecheck
|
81
|
+
@m1 = Matrixlpp::Matriz_Densa.new(1,1)
|
82
|
+
@m2 = Matrixlpp::Matriz_Densa.new(1,1)
|
83
|
+
@m1.set(0,0,5)
|
84
|
+
@m2.set(0,0,"hola")
|
85
|
+
|
86
|
+
assert_raise(TypeError) {@m1+@m2}
|
87
|
+
end
|
88
|
+
# En este test se hace fallar intencionadamente al programa.
|
89
|
+
def test_failure
|
90
|
+
@m1 = Matrixlpp::Matriz_Densa.new(1,1)
|
91
|
+
@m2 = Matrixlpp::Matriz_Densa.new(2,2)
|
92
|
+
|
93
|
+
assert_raise(ArgumentError) {@m1*@m2}
|
94
|
+
end
|
95
|
+
end
|
metadata
ADDED
@@ -0,0 +1,93 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: matrixlpp
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
platform: ruby
|
6
|
+
authors:
|
7
|
+
- Javier Mena Mena
|
8
|
+
- Diego Williams Aguilar Montaño
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2013-11-28 00:00:00.000000000 Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: bundler
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
|
+
requirements:
|
18
|
+
- - ~>
|
19
|
+
- !ruby/object:Gem::Version
|
20
|
+
version: '1.3'
|
21
|
+
type: :development
|
22
|
+
prerelease: false
|
23
|
+
version_requirements: !ruby/object:Gem::Requirement
|
24
|
+
requirements:
|
25
|
+
- - ~>
|
26
|
+
- !ruby/object:Gem::Version
|
27
|
+
version: '1.3'
|
28
|
+
- !ruby/object:Gem::Dependency
|
29
|
+
name: rake
|
30
|
+
requirement: !ruby/object:Gem::Requirement
|
31
|
+
requirements:
|
32
|
+
- - '>='
|
33
|
+
- !ruby/object:Gem::Version
|
34
|
+
version: '0'
|
35
|
+
type: :development
|
36
|
+
prerelease: false
|
37
|
+
version_requirements: !ruby/object:Gem::Requirement
|
38
|
+
requirements:
|
39
|
+
- - '>='
|
40
|
+
- !ruby/object:Gem::Version
|
41
|
+
version: '0'
|
42
|
+
description: Esta es una clase Matrix
|
43
|
+
email:
|
44
|
+
- alu0100454741@ull.edu.es
|
45
|
+
- alu0100592368@ull.edu.es
|
46
|
+
executables: []
|
47
|
+
extensions: []
|
48
|
+
extra_rdoc_files: []
|
49
|
+
files:
|
50
|
+
- .gitignore
|
51
|
+
- Gemfile
|
52
|
+
- Guarfile
|
53
|
+
- LICENSE.txt
|
54
|
+
- README.md
|
55
|
+
- Rakefile
|
56
|
+
- lib/matrixlpp.rb
|
57
|
+
- lib/matrixlpp/gcd.rb
|
58
|
+
- lib/matrixlpp/matriz.rb
|
59
|
+
- lib/matrixlpp/matriz_densa.rb
|
60
|
+
- lib/matrixlpp/matriz_dispersa.rb
|
61
|
+
- lib/matrixlpp/matriz_operaciones.rb
|
62
|
+
- lib/matrixlpp/racional.rb
|
63
|
+
- lib/matrixlpp/version.rb
|
64
|
+
- matrixlpp.gemspec
|
65
|
+
- spec/matriz_spec.rb
|
66
|
+
- test/tc_matrixlpp.rb
|
67
|
+
homepage: https://github.com/alu0100454741/EquipoDJ-prct11
|
68
|
+
licenses:
|
69
|
+
- MIT
|
70
|
+
metadata: {}
|
71
|
+
post_install_message:
|
72
|
+
rdoc_options: []
|
73
|
+
require_paths:
|
74
|
+
- lib
|
75
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
76
|
+
requirements:
|
77
|
+
- - '>='
|
78
|
+
- !ruby/object:Gem::Version
|
79
|
+
version: '0'
|
80
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
|
+
requirements:
|
82
|
+
- - '>='
|
83
|
+
- !ruby/object:Gem::Version
|
84
|
+
version: '0'
|
85
|
+
requirements: []
|
86
|
+
rubyforge_project:
|
87
|
+
rubygems_version: 2.0.3
|
88
|
+
signing_key:
|
89
|
+
specification_version: 4
|
90
|
+
summary: Contiene todo lo necesario para definir una clase matrix
|
91
|
+
test_files:
|
92
|
+
- spec/matriz_spec.rb
|
93
|
+
- test/tc_matrixlpp.rb
|