EDA - ITIS/ITIG ETSINF. UPV. Curso 2010/2011. Grupo 2D EJEMPLO DE USO DE UNA INTERFAZ Índice 1. Introducción 1 2. Ejercicios sobre el proyecto ejemploMat 2 3. Estructuras de datos para la representación de matrices 3.1. Representación densa . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 3.2. Representación dispersa . . . . . . . . . . . . . . . . . . . . . . . . . . . 2 2 3 A. Ficheros de datos para la creación de matrices 5 B. Breve discusión de la suma de matrices con representación dispersa 5 1. Introducción Este ejemplo constituye un primer ejercicio de uso de interfaces o clases totalmente abstractas. Parte del código se debe completar, tal como se pide en el apartado 2. Estos ejercicios suponen la implementación de operaciones sobre una determinada estructura de datos, manejando al mismo tiempo conceptos básicos de herencia. En la siguiente figura se muestra la estructura del proyecto ejemploMat, que contiene un paquete con una interfaz de operaciones matriciales, y un par de implementaciones basadas en diferentes estructuras de datos. Ambas implementaciones vienen con operaciones constructoras que pueden leer los datos de las matrices desde ficheros texto. En el proyecto aparecen los ficheros densa1.txt, densa2.txt, dispersa1.txt, dispersa2.txt, con los que se podrán hacer pruebas de las operaciones. En el apéndice A se describe el formato de estos ficheros. 1 2 2 EJERCICIOS SOBRE EL PROYECTO EJEMPLOMAT ejemploMat (proyecto) matrices (paquete) Matriz.java Interfaz y sus implementaciones 2. MDen.java densa1.txt densa2.txt dispersa1.txt dispersa1.txt MDis.java Ficheros de datos Ejercicios sobre el proyecto ejemploMat En las clases del paquete matrices falta por desarrollar una pequeña parte del código. En concreto, se pide: 1. Revisar la funcionalidad de Matriz. 2. Completar el código del método producto en la clase MDis, siguiendo las indicaciones del apartado 3.2. 3. Completar el código del método main de la clase Ejemplo allı́ donde se indica. 4. Modificar el perfil de las operaciones suma, producto para que cuando no se cumpla la precondición, en lugar de retornar null, se lance una excepción DimensionIncExc. Para esta clase de excepción se considerarán dos alternativas: a) Hacerla una excepción comprobada (derivada de Exception), b) o hacerla una excepción no comprobada (derivada de RuntimeException). 3. 3.1. Estructuras de datos para la representación de matrices Representación densa La clase MDen utiliza la siguiente estructura de datos para representar un objeto matriz: private double[][] m; private int filas; private int columnas; en donde m se debe crear para que almacene todas las componentes de la matriz, como en el siguiente ejemplo: 3 ESTRUCTURAS DE DATOS PARA LA REPRESENTACI ÓN DE MATRICES 3 0 1 m 0 1 3.2. " 0 1 2 # 0.0 0.7 -4.3 8.3 0.0 -8.3 0 1 2 0.0 8.3 0.7 0.0 -4.3 -8.3 filas 2 columnas 3 Representación dispersa Una matriz dispersa es adecuada para la representación de matrices en las que la mayorı́a de sus elementos valen 0.0, guardando en memoria únicamente los valores diferentes de 0.0. La clase MDis representa una matriz como un objeto con 5 atributos: int f[], array de filas (para componentes de valores no nulos), int c[], array de columnas (para componentes de valores no nulos), double val[], array de valores no nulos de la matriz dispersa, int filas, número de filas de la matriz, int columnas, número de columnas. Los tres arrays componentes del objeto tendrán la misma talla n, siendo n el número de valores no nulos de la matriz, y el significado de esta representación será: val[i] es el valor de la componente de la matriz en la fila f[i], y columna c[i]. Por ejemplo, considérese la siguiente matriz: 0 1 2 3 4 5 6 0 0.0 0.0 0.0 -1.4 0.0 0.0 0.0 1 0.0 9.1 0.0 0.0 0.0 0.0 0.0 2 1.2 0.0 0.0 0.0 0.0 0.0 0.0 3 4 0.0 0.0 3.0 0.0 0.0 4.7 0.0 0.0 2.3 0.0 0.0 0.0 0.0 0.0 se representa como 3 ESTRUCTURAS DE DATOS PARA LA REPRESENTACI ÓN DE MATRICES 4 0 1 2 3 4 5 f 0 1 1 2 3 4 c 2 1 3 4 0 3 val 1.2 9.1 3.0 4.7 -1.4 2.3 filas 7 columnas 5 En el fichero MDis.java se encuentran implementados todos los métodos de la interfaz, a falta de public double[] producto(double v[]) y para cuya implementación se recomienda observar lo siguiente: Sea m ij el valor de la componente ij de la matriz, sea N × M su dimensión, y por lo tanto sea M la dimensión de v. Sea x el vector resultante, que deberá ser de talla N . El cálculo de x suele expresarse indicando cómo se calcula cada una de sus N filas o componentes xi = mi0 v0 + mi1 v1 + · · · + miM −1 vM −1 , 0 ≤ i < N De ello se deduce que: Cada componente mij interviene únicamente en el cálculo de la componente x i del vector resultante, contribuyendo a su valor con el término m ij vj . Entonces, se puede calcular el producto sin importar el orden en que se recorran las componentes de la matriz, y obviando las componentes de valor nulo, que no contribuyen a ningún resultado. Es por ello que el cálculo x se puede realizar con el siguiente algoritmo: Creado un array x de talla N e inicializadas sus componentes a 0.0, para cada componente mij no nula de la matriz, se suma mij ·vj a xi . Ello se implementa fácilmente con un recorrido de los arrays f, c, val de la matriz. Por ejemplo, considérese el producto de la matriz m por el vector v de la siguiente figura, en la que m aparece como un objeto de la clase MDis: Supóngase, por ejemplo, el producto de la siguiente figura, en donde se muestra un estado intermedio del cálculo; las componentes de la matriz ya consideradas por el recorrido aparecen sombreadas: 0 1 2 3 4 5 this.f 0 1 1 2 3 4 this.c 2 1 3 4 0 3 this.val 1.2 9.1 3.0 4.7 -1.4 2.3 × v 1.0 2.0 3.0 4.0 5.0 +12.0 → 0 1 2 3 4 = x 3.6 18.2 0.0 0.0 0.0 0.0 0.0 0 1 2 3 4 5 6 A FICHEROS DE DATOS PARA LA CREACIÓN DE MATRICES A. 5 Ficheros de datos para la creación de matrices Las constructoras MDen(String fichero) y MDis(String fichero) presuponen que los ficheros cuya ruta viene dada por fichero describen las matrices en un determinado formato: Para matrices densas, la primera lı́nea contiene el número de filas y de columnas de la matriz, y el resto de lı́neas tiene la forma i j vij, que da el valor vij de la componente de fila i, columna j. Para matrices dispersas, el formato es similar, excepto que la segunda fila indica cuántas componentes no nulas tiene la matriz, y únicamente se incluye la descripción de estas componentes. Por ejemplo, la matriz " 0.0 0.7 -4.3 8.3 0.0 -8.3 # vendrı́a descrita por ficheros de contenidos 2 0 0 0 1 1 1 3 0 1 2 0 1 2 0.0 0.7 -4.3 8.3 0.0 -8.3 2 4 0 0 1 1 3 1 2 0 2 0.7 -4.3 8.3 -8.3 para las representaciones densa y dispersa respectivamente. Los ficheros de datos que se proporcionan con el proyecto ejemploMat se ajustan a estos formatos. B. Breve discusión de la suma de matrices con representación dispersa La suma de matrices implementada en MDis.java utiliza unos arrays auxiliares declarados de tamaño suficiente para albergar la suma de las componentes no nulas de this y m2. Las figuras que vienen a continuación constituyen una traza de la parte central del método, cuando se aplica para calcular la suma de las siguientes matrices ejemplo: B BREVE DISCUSIÓN DE LA SUMA DE MATRICES CON REPRESENTACI ÓN DISPERSA6 0 1 2 3 4 5 0 1 2 this.f 0 1 1 2 3 4 m2.f 1 2 4 this.c 2 1 3 4 0 3 m2.c 3 2 1 this.val 1.2 9.1 3.0 4.7 -1.4 2.3 m2.val 7.0 2.1 8.2 this.filas 7 m2.filas 7 this.columnas 5 m2.columnas 5 y pos i 0 1 2 3 4 5 6 7 8 0 auxf 0 1 1 2 3 4 0 0 0 1 2 m2.f 1 2 4 auxc 2 1 3 4 0 3 0 0 0 m2.c 3 2 1 auxval 1.2 9.1 3.0 4.7 -1.4 2.3 0.0 0.0 0.0 m2.val 7.0 2.1 8.2 0 1 2 3 4 5 6 7 8 auxf 0 1 1 2 3 4 0 0 0 auxc 2 1 3 4 0 3 0 0 auxval 1.2 9.1 10.0 4.7 -1.4 2.3 0.0 0.0 0 auxf 0 1 2 3 4 5 6 7 8 0 1 1 2 3 4 2 0 0 auxc 2 1 3 4 0 3 2 0 auxval 1.2 9.1 10.0 4.7 -1.4 2.3 2.1 0.0 0 auxf 0 1 2 3 4 5 6 7 8 0 1 1 2 3 4 2 4 0 m2.f auxc 2 1 3 4 0 3 2 1 0 auxval 1.2 9.1 10.0 4.7 -1.4 2.3 2.1 8.2 0.0 pos i 0 1 2 m2.f 1 2 4 0 m2.c 3 2 1 0.0 m2.val 7.0 2.1 8.2 0 1 2 m2.f 1 2 4 0 m2.c 3 2 1 0.0 m2.val 7.0 2.1 8.2 0 1 2 1 2 4 m2.c 3 2 1 m2.val 7.0 2.1 8.2 pos i pos