miércoles, 23 de enero de 2008

Funciones sobre Matrices en lenguaje ADA, Transpuesta, Sobrecarga de los operadores *,+,-,=

* Desarrollar una serie de operaciones para manejo de matrices junto con un procedimiento principal de prueba. La interfaz de las operaciones en base a la cual hay que realizar la implementación es la que sigue:

1. Definir un tipo para declarar matrices de cualquier tamaño y rango de variación de los índices.

2. Sobrecarga del operador "=".
entrada: matrices a comparar.
pre: el número de valores de los rangos de los respectivos índices de las matrices a comparar debe coincidir.
post: devuelve verdadero si los correspondientes elementos de ambas matrices son iguales y, falso, si algún elemento de una de las matrices no coincide con el correspondiente de la otra.

3. Sobrecarga del operador "+".
entrada: matrices a sumar.
pre: el número de valores de los rangos de los respectivos índices de las matrices a sumar debe coincidir.
post: devuelve la matriz suma de los correspondientes elementos de las matrices dadas.

4. Sobrecarga del operador "-".
entrada: matrices a restar.
pre: el número de valores de los rangos de los respectivos índices de las matrices a restar debe coincidir.
post: Devuelve la matriz diferencia de los correspondientes elementos de las matrices dadas.

5. Sobrecarga del operador "*".
entrada: matrices a multiplicar.
pre: el número de valores del rango del 2º índice de la matriz primer operando debe coincidir con el número de valores del 1er. índice de la matriz segundo operando.
post: devuelve la matriz producto.

6. Función Transpuesta.
entrada: matriz a transponer. post: devuelve la transpuesta de una matriz con igual número de filas e igual número de columnas al de la correspondiente matriz de entrada.



with Text_IO;
use Text_IO;

procedure Sentencias is


-- *********** Definiciones de tipos y paquetes *************

type Opciones is range 0..10;
type Matriz_nr is array (integer range<>,integer range<>) of integer;
package Opciones_IO is new Integer_IO(Opciones);
Package Real_IO is new Float_IO(Float);
Package Entero_IO is new Integer_IO(Integer);
use Opciones_IO, Real_IO,Entero_IO;
---------------------------------------------------------------


-- ************** Procedimientos *************

-- Lee los elementos por pantalla y los almacena en la matriz
-- pasada por parametro.
procedure LeeMatriz(Mat :in out Matriz_nr) is
begin
for i in Mat'First(1)..Mat'Last(1) loop
for j in Mat'First(2)..Mat'Last(2) loop
put("Elemento[");put(i);put(",");put(j);put("] <- ");
get(Mat(i,j));
new_line;
end loop;
end loop;
end LeeMatriz;
---------------------------------------------------------------
---------------------------------------------------------------


-- Escribe la matriz pasada por parametro en la
-- pantalla.
procedure EscribeMatriz(Mat: in Matriz_nr) is
begin
for i in Mat'Range(1) loop
for j in Mat'First(2)..Mat'Last(2) loop
put(Mat(i,j)); put(" ");
end loop;
new_line;
end loop;
end EscribeMatriz;
---------------------------------------------------------------
---------------------------------------------------------------


-- Compara las dos matrices pasadas y devuelve si tienen
-- la misma dimension y son iguales.
function "="(M1,M2: in Matriz_nr) return boolean is
Result : boolean ;

begin
Result := true;
if ((M1'Length(1) = M2'Length(1)) and (M1'Length(2) = M2'Length(2))) then
-- dimensiones correctas? ..... seguimos ....
for i in 1..(M1'Length(1)) loop
for j in 1..(M1'Length(2)) loop
if ( M1(M1'First(1)+i-1,M1'First(2)+j-1)/=
M2(M2'First(1)+i-1,M2'First(2)+j-1) ) then
Result := false;
end if;
end loop;
end loop;
else
Result := false;
end if;
return Result;
end "=";
---------------------------------------------------------------
---------------------------------------------------------------


-- Suma la matriz segunda a la primera y devuelve la matriz
-- resultante.
function "+"(M1,M2: in Matriz_nr) return Matriz_nr is
Result : Matriz_nr(1..(M1'Length(1)),1..(M1'Length(2)));
begin
if ((M1'Length(1) = M2'Length(1)) and (M1'Length(2) = M2'Length(2))) then
-- dimensiones correctas? ..... seguimos ....
for i in 1..(M1'Length(1)) loop
for j in 1..(M1'Length(2)) loop
Result(i,j) := M1(M1'First(1)+i-1,M1'First(2)+j-1)+
M2(M2'First(1)+i-1,M2'First(2)+j-1);
end loop;
end loop;
else
put_line("Hagan caso omiso del contenido de M3!");
put_line("Hagan caso omiso del contenido de M3!");
put_line("Hagan caso omiso del contenido de M3!");
put_line("_____________________________________");
put_line("No coinciden las dimensiones");
put_line("_____________________________________");
new_line;
end if;
return Result;
end "+";
---------------------------------------------------------------
---------------------------------------------------------------


-- Resta la matriz segunda a la primera y devuelve la matriz
-- resultante.
function "-"(M1,M2: in Matriz_nr) return Matriz_nr is
Result : Matriz_nr(1..(M1'Length(1)),1..(M1'Length(2)));
begin
if ((M1'Length(1) = M2'Length(1)) and (M1'Length(2) = M2'Length(2))) then
-- dimensiones correctas? ..... seguimos ....
for i in 1..(M1'Length(1)) loop
for j in 1..(M1'Length(2)) loop
Result(i,j) := M1(M1'First(1)+i-1,M1'First(2)+j-1)-
M2(M2'First(1)+i-1,M2'First(2)+j-1);
end loop;
end loop;
else
put_line("No coinciden las dimensiones");
put_line("_____________________________________");
put_line("Hagan caso omiso del contenido de M3!");
put_line("_____________________________________");
new_line;
end if;
return Result;
end "-";
---------------------------------------------------------------
---------------------------------------------------------------


-- Multiplica la primera matriz por la segunda y
-- devuelve la matriz resultante.
function "*"(M1,M2: in Matriz_nr) return Matriz_nr is
Result : Matriz_nr(1..(M1'Length(1)),1..(M2'Length(2)));
begin
if (M1'Length(2) = M2'Length(1)) then
-- dimensiones correctas? ..... seguimos ....
for i in 1..(M1'Length(1)) loop
for j in 1..(M2'Length(2)) loop
Result(i,j) := 0 ;
for k in 1..(M1'Length(2)) loop
Result(i,j) := Result(i,j) +
M1(M1'First(1)+i-1,M1'First(2)+k-1)*
M2(M2'First(1)+k-1,M2'First(2)+j-1);
end loop;
end loop;
end loop;
else
put_line("No coinciden las dimensiones");
put_line("_____________________________________");
put_line("Hagan caso omiso del contenido de M3!");
put_line("_____________________________________");
new_line;
end if;
return Result;
end "*";
---------------------------------------------------------------
---------------------------------------------------------------


-- Transpone una matriz
function Transpuesta(M1: in Matriz_nr) return Matriz_nr is
Result : Matriz_nr(1..(M1'Length(2)),1..(M1'Length(1)));
begin
for i in 1..(M1'Length(1)) loop
for j in 1..(M1'Length(2)) loop
if (i=j) then
Result(i,j) := M1(M1'First(1)+i-1 ,M1'First(2)+j-1);
else
Result(j,i) := M1( M1'First(1)+i-1 , M1'First(2)+j-1 );
end if;
end loop;
new_line;
end loop;
return Result;
end Transpuesta;
---------------------------------------------------------------
---------------------------------------------------------------


-- ************* Programa Principal **************************

--Declaraciones de variables
o : Opciones ;
OpciónLeída : Opciones ;
M1ii,M1if,M2ii,M2if : integer ;
M1ji,M1jf,M2ji,M2jf : integer ;
begin
put_line("Bienvenido");
put_Line("Practica 1 _________________________________");
put_Line("Programa de tratamiento de matrices: ");
put_Line("");
put_Line("Primero leeremos los rangos de las 2 matrices");
put_Line("");
put_Line("Matriz 1");
put_Line("________");
put_Line("");
put_Line("Filas");
put_Line("-----");
put("Valor inicial : ");get(M1ii);
put("Valor final : ");get(M1if);
put_Line("");
put_Line("Columnas");
put_Line("--------");
put("Valor inicial : ");get(M1ji);
put("Valor final : ");get(M1jf);
put_Line("");
put_Line("Matriz 2");
put_Line("________");
put_Line("");
put_Line("Filas");
put_Line("-----");
put("Valor inicial : ");get(M2ii);
put("Valor final : ");get(M2if);
put_Line("");
put_Line("Columnas");
put_Line("--------");
put("Valor inicial : ");get(M2ji);
put("Valor final : ");get(M2jf);
put_Line("");


--El programa permanece en un bucle hasta que se elige terminar
declare
M1 : Matriz_nr(M1ii..M1if,M1ji..M1jf);
M2 : Matriz_nr(M2ii..M2if,M2ji..M2jf);
M3S : Matriz_nr(1..(M1'Length(1)),1..(M1'Length(2)));
M3P : Matriz_nr(1..(M1'Length(1)),1..(M2'Length(2)));
M3T : Matriz_nr(1..(M1'Length(2)),1..(M1'Length(1)));
M3T2 : Matriz_nr(1..(M2'Length(2)),1..(M2'Length(1)));
begin
loop
--Presentación del menú de opciones

put_Line("__________________MENU______________________");
put_Line(" 0 - Terminar ");
put_Line(" 1 - Rellenar matriz 1 ");
put_Line(" 2 - Rellenar matriz 2 ");
put_Line(" 3 - Comparacion (sobrecarga de =) ");
put_Line(" 4 - Suma (sobrecarga de +) ");
put_Line(" 5 - Resta (sobrecarga de -) ");
put_Line(" 6 - Producto (sobrecarga de *) ");
put_Line(" 7 - Transpuesta ");
put_Line("____________________________________________");
put("Elija su opcion: ");get(OpciónLeída);
new_line;
new_line;
case OpciónLeída is --Se ejecuta la opción elegida

when 0 => exit;

when 1 => begin
put_line("Leyendo M1..........");
new_line;
LeeMatriz(M1);
put_line("Contenido de M1.....");
new_line;
EscribeMatriz(M1);
end;

when 2 => begin
put_line("Leyendo M2..........");
new_line;
LeeMatriz(M2);
put_line("Contenido de M2.....");
new_line;
EscribeMatriz(M2);
end;

when 3 => begin
put_line("Comparando M1 con M2.....");
new_line;
if (M1=M2) then
put_line("Las matrices M1 y M2 son 'Iguales' ");
else
put_line("Las matrices M1 y M2 son 'Distintas'");
end if;
new_line;
end;


when 4 => begin
put_line("Sumando M1 y M2.....");
new_line;
M3S := M1 + M2;
put_line("Resultado en M3.");
new_line;
put_line("Leyendo M3.....");
new_line;
EscribeMatriz(M3S);
end;

when 5 => begin
put_line("Restando M1 y M2..........");
new_line;
M3S := M1 - M2;
put_line("Resultado en M3.");
new_line;
put_line("Leyendo M3.....");
new_line;
EscribeMatriz(M3S);
end;

when 6 => begin
put_line("Multiplicando M1 y M2.....");
new_line;
M3P := M1 * M2;
put_line("Resultado en M3.");
new_line;
put_line("Leyendo M3.....");
new_line;
EscribeMatriz(M3P);
end;

when 7 => begin
loop
put_line ("Seleccione la matriz a transponer:");
put_line ("1.- tranpone la matriz M1");
put_line ("2.- tranpone la matriz M2");
put ("seleccione : ");get(o);
new_line;
exit when ((o=1) or (o=2));
end loop;
if (o=1) then
put_line("Transponiendo M1.....");
new_line;
M3T := Transpuesta(M1);
put_line("Resultado en M3.");
new_line;
put_line("Leyendo M3.....");
new_line;
EscribeMatriz(M3T);
else
put_line("Transponiendo M2.....");
new_line;
M3T2 := Transpuesta(M2);
put_line("Resultado en M3.");
new_line;
put_line("Leyendo M3.....");
new_line;
EscribeMatriz(M3T2);
end if;
end;

when others => put_line("La opcion elegida no es valida");
end case;
new_line;
new_line;
end loop;
put_line("Gracias, por usar este programa");
end;
return;
end Sentencias;