3 Código

Anuncio
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
3. CÓDIGO
3.1
INTRODUCCIÓN
Continuando con nuestra subida desde el nivel más bajo hasta el más
alto, hemos llegadoal capítulo dedicado al código, el paso previo al nivel de
usuario. En este capítulo desgranaremos todos los desarrollos que se han
realizado para dar a la aplicación el aspecto global y la funcionalidad de la
que goza.
3.2
ESTRUCTURA GENERAL
Como se ha comentado en capítulos anteriores, esta aplicación está
desarrollada íntegramente en Java, siendo el entorno de desarrollo elegido
Netbeans.
Se ha creado un proyecto nuevo con Netbeans para alojar el código de la
aplicación, siendo el nombre de este proyecto TDSApplet.
El desarrollo de la aplicación está basado en dos tipos de código
fundamentales:
•
•
Librerías o clases externas: Son clases que han sido desarrolladas
por terceros y que están disponibles (bajo diversos tipos de
licencia) para su utilización. El código fuente puede estar o no
disponible y no tienen por qué ser editables.
Clases propias: Son clases que han sido desarrolladas
expresamente para esta aplicación por el autor de la misma, el
código fuente está disponible y es editable.
Visualizando las categorías de nuestro IDE, podemos diferenciar
claramente estos dos tipos de clases, ya que cada uno está agrupado bajo
un epígrafe diferente, estando las clases propias agrupadas bajo Source
Packages y las librerías bajo Libraries:
27
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
3.3
LIBRERÍAS
Las librerías que se han utilizado para el desarrollo de esta aplicación
son las siguientes:
•
•
•
•
•
JDK 1.7
JGraphX
ApacheMath
JFreeChart
JTransforms
Cada una de estas librerías tiene un cometido diferente dentro de la
ejecución de la aplicación. En los subapartados siguientes nos detendremos
en cada una de ellas para analizarlas con mayor profundidad.
3.3.1 JDK 1.7
Este es el Application Programming Interface (API) de Java versión 1.7.
y está incluido dentro del JDK con el que hemos realizado la compilación de
la aplicación. El API de Java contiene una gran variedad de clases y
utilidades diferentes que con cada versión nueva aumentan más y más:
28
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
está completamente desarrollado en Java y constituye la base sobre la cual
desarrollar cualquier aplicación en Java.
Las clases del API de Java que se han utilizado en este desarrollo están
englobadas en 5 paquetes diferentes:
•
•
•
•
•
AWT: Es el Abstract Window Toolkit, AWT (Herramientas de
Ventanas Abstractas). Soporta la programación de Graphical User
Interface, GUI (Interfaz Gráfica de Usuario). Las características
más importantes de AWT son:
- Es un conjunto de componentes de interfaz de usuario
nativo en Java.
- Tiene un modelo de gestión de eventos robusto.
- Contiene herramientas gráficas y de imágenes, incluyendo
clases de formas, colores y fuentes.
- Implementa gestores de ventanas que permiten que las
ventanas no dependan de un tamaño de ventana particular
o de una determinada resolución de pantalla.
Incluye clases de transferencia de datos para el copiado y
pegado a través del portapapeles nativo de la plataforma.
Io: Implementa entradas y salidas de flujos de datos, serialización
y sistema de archivos.
Net: Proporciona clases para implementar aplicaciones de red.
Util: Contiene colecciones de elementos útiles como gestores de
eventos, colección de utilidades tradicionales, gestores de fecha y
hora, utilidades de internacionalización y otra miscelánea de
utilidades (generador de números aleatorios, arrays de bits, etc.)
Swing:Implementa un conjunto de componentes para la
construcción de GUIs y para el añadido de funcionalidades gráficas
e interactividad mejoradas a aplicaciones de Java. Los
componentes de Swing están implementados completamente en
Java. Estos componentes permiten a los GUIs mostrar la misma
apariencia en todas las plataformas o tomar la apariencia propia
de cada plataforma por separado (como Windows, Solaris o
Linux).
Los elementos utilizados de cada uno de estos conjuntos son los
siguientes:
•
•
•
•
java.awt.BorderLayout: Proporciona un contenedor para el
cambio de tamaño y organización de sus componentes en cinco
regiones (norte, sur, este, oeste y centro).
java.awt.Color: La clase Color se utiliza para encapsular los
colores en el espacio por defecto RGB (Red, Green, Blue) o en
espacios arbitrarios identificados por ColorSpace.
java.awt.Desktop: La clase Desktop permite a una aplicación
Java lanzar aplicaciones registradas en el escritorio nativo para
manejar una URI o archivo.
java.awt.Dimension: La clase Dimension encapsula la altura y
anchura de un objeto (en precisión Integer) en un solo objeto.
29
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
•
java.awt.event.MouseAdapter:
La
clase
MouseAdapter
implementa un adaptador abstracto para la recepción de eventos
de ratón. Esta clase se puede editar a conveniencia para crear
listeners de objetos.
java.awt.event.MouseEvent: La clase MouseEvent implementa
un listener que indica que una acción de ratón se ha producido en
un componente.
java.awt.geom.Ellipse2D: La clase Ellipse2D implementa una
elipse que está definida por un rectángulo y enmarcada en él.
java.io.IOException: Indica que una excepción de algún tipo de
entrada/salida se ha producido.
java.net.URI: Representa una referencia de un Uniform Resource
Identifier (URI).
java.util.logging.Level: La clase Level define un conjunto de
niveles de registro estándar que pueden ser utilizados para
controlar el registro de salida.
java.util.logging.Logger: El objeto Logger se utiliza para
registrar los mensajes de un sistema o componente específico de
la aplicación.
java.util.Map: El objeto Map es un objeto que mapea elementos
en valores.
java.util.regex.Matcher: La clase Matcher implementa un motor
que realiza operaciones de búsqueda y coincidencia en una cadena
de caracteres mediante la interpretación de un patrón Pattern.
java.util.regex.Pattern: El objeto Pattern es una representación
compilada de una expresión regular.
java.util.Vector: La clase Vector implementa un conjunto
ampliable de objetos.
javax.swing.JFrame: La clase JFrame es una versión extendida
de java.awt.Frame que añade soporte para la arquitectura de
componentes Swing.
javax.swing.JPanel: La clase JPanel implementa un contenedor
ligero genérico.
javax.swing.JTable: La clase JTable se utiliza para visualizar y
editar tablas de dos dimensiones.
javax.swing.SwingUtilities: La clase SwingUtilities implementa
un conjunto de métodos de utilidad para Swing.
javax.swing.table.DefaultTableModel:
La
clase
DefaultTableModel es una implementación de TableModel que
utiliza un vector de vectores para almacenar los valores de los
objetos de las celdas.
javax.swing.tree.DefaultMutableTreeNode:
la
clase
DefaultMutableTreeNode es un nodo de propósito general en una
estructura de datos de árbol.
javax.swing.tree.TreePath: La clase TreePath representa una
matriz de objetos que identifican unívocamente la ruta de acceso
a un nodo en un árbol.
30
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
3.3.2 JGraphX
JGraphX es una librería de visualización de diagramas de Java Swing
licenciada bajo la licencia NewBSD (New Berkeley Software Distribution).
Esta licencia tiene menos restricciones en comparación con otras como la
GPL estando muy cercana al dominio público. La licencia BSD al contrario
que la GPL permite el uso del código fuente en software no libre.
A pesar de que los paquetes usan el nombre de “mxGraph”, la librería no
se llama mxGraph ya que mxGraph es la librería de graficado de JavaScript
que sólo está disponible a través de compra y no es de código libre.
Originalmente la librería fue nombrada JGraph a secas hasta la versión
1.5. En la versión 1.6 se decidió cambiar el nombre a JGraphX para reflejar
que el código base de la API fue reescrito desde cero.
JGraphX proporciona funcionalidades para la visualización e interacción
con grafos (no gráficos). Algunos ejemplos de aplicaciones que pueden ser
escritos con esta librería son editores de flujos de trabajo, cuadros de
organizaciones, herramientas de modelado de procesos de negocios,
visualizador de circuitos electrónicos, visualizador de redes de
telecomunicaciones, etc. es decir, una multitud de aplicaciones en las que
esté presente el concepto de grafo.
JGraphX también incluye soporte para XML, importación y exportación
de grafos, maquetación, etc.
Esta librería puede ser encontrada en la siguiente dirección web
http://www.jgraph.com y constituye, junto con el JDK 1.7 de Java, la base
de nuestra aplicación.
Es con esta librería con la que se implementa el grafo (aristas, bloques
funcionales y conectividad entre ellos) del Panel de Operaciones. Este grafo
es el que permite mover el flujo de información de un bloque a otro y
realizar el cálculo de las distintas operaciones.
Los elementos de esta librería utilizados en la confección del código de
nuestra aplicación son los siguientes:
•
•
•
com.mxgraph.analysis.mxAnalysisGraph:
La
clase
mxAnalysisGraph implementa un conjunto de métodos útiles para
analizar la estructura y propiedades del grafo.
com.mxgraph.model.mxCell: La clase mxCell representa un
elemento del modelo del grafo (celda). Los vértices, aristas y
grupos de ellos son modelados como mxCell.
com.mxgraph.model.mxGeometry: La clase mxGeometry
representa la geometría de una celda. Para vértices la geometría
consta de localización en los ejes X e Y así como de anchura y
altura. Para aristas, la geometría define los terminales origen y
destino.
31
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
•
•
•
•
•
•
•
•
com.mxgraph.swing.mxGraphComponent: Esta clase lanza
los siguientes eventos: START_EDITING, LABEL_CHANGED,
ADD_OVERLAY, BEFORE_PAINT.
com.mxgraph.util.mxConstants: Esta clase contiene todas las
constantes globales del grafo.
com.mxgraph.util.mxEvent: Esta clase implementa los eventos
del grafo.
com.mxgraph.util.mxEventObject: La clase mxEventObject
constituye la base para objetos que lanzan eventos con nombre.
com.mxgraph.util.mxEventSource.mxIEventListener:
Esta
clase define los requisitos para un objeto que escucha una fuente
de eventos.
com.mxgraph.util.mxPoint: La clase mxPoint implementa un
punto bidimensional con coordinadas de precisión Double.
com.mxgraph.view.mxEdgeStyle:
La
clase
mxEdgeStyle
proporciona varios estilos de aristas que se utilizarán como
valores para mxConstants.STYLE_EDGE en el estilo de las celdas.
De manera alternativa, las constantes mxConstants.EDGESTYLE_*
pueden ser utilizadas para hacer referencia a un estilo de arista a
través del registro mxStyleRegistry.
com.mxgraph.view.mxGraph: La clase mxGraph implementa
un objeto que permite crear grafos a partir de un modelo de
grafos y una hoja de estilos. Es la clase base a partir de la cual se
construye el grafo de nuestra aplicación.
3.3.3 ApacheMath
La Apache Commons Mathematics Library es una librería ligera de
componentes matemáticos y estadísticos autocontenidos que abordan los
problemas matemáticos más comunes que no están disponibles en las
librerías nativas de Java.
Sus principios están basados en:
•
•
•
•
•
Las aplicaciones al mundo real determinan las prioridades de su
desarrollo.
El desarrollo de la librería hace hincapié en el desarrollo de
pequeños componentes de fácil integración en lugar del desarrollo
de grandes componentes con complejas dependencias entre ellos.
Todos los algoritmos están completamente documentados y
siguen, generalmente, las pautas de edición aceptadas
comúnmente.
En situaciones donde existen multitud de algoritmos estándar, se
utiliza
un
patrón
estratégico
para
soportar
múltiples
implementaciones.
Dependencias limitadas. No existen dependencias externas más
allá de los propios componentes Commons y las librerías nativas
32
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
de Java (requiere al menos Java 3 para la versión 1.2 de la librería
y Java 5 para la versión 2.0).
Esta librería es distribuida bajo la Apache License 2.0, que es una
licencia de software libre creada por la Apache Software Foundation (ASF).
La licencia Apache (con versiones 1.0, 1.1 y 2.0) requiere la conservación
del aviso de copyright y el disclaimer, pero no es una licencia copyleft, ya
que no requiere la redistribución del código fuente cuando se distribuyen
versiones modificadas.
El uso principal que se le ha dado a esta librería es el de soportar los
cálculos del más bajo nivel para números complejos.
La única clase que se ha utilizado en este desarrollo de esta librería ha
sido la siguiente:
•
org.apache.commons.math3.complex.Complex:
La
clase
Complex soporta la representación de un número complejo, es
decir, un número que tiene parte real y parte imaginaria. Las
implementaciones de las operaciones aritméticas manejan valores
NaN e Infinito de acuerdo con la aritmética de valores Double.
3.3.4 JFreeChart
El proyecto JFreeChart fue fundado hace catorce años, en el año 2000
por David Gilbert. JFreeChart es la más ampliamente utilizada librería de
graficado para Java, con más de 2.1 millones de descargas hasta la fecha.
El proyecto continúa su desarrollo a día de hoy gracias a la gestión del
propio David Gilbert y la contribución de una diversa comunidad de
desarrolladores.
JFreeChart es una librería gratuita desarrollada íntegramente en Java y
que facilita a los desarrolladores la implementación de gráficos profesionales
y de calidad en sus desarrollos. Las características más importantes de
JFreeChart incluyen:
•
•
•
Una API consistente y bien documentada que soporta un amplio
abanico de gráficos diferentes.
Un diseño flexible que lo hace fácilmente extensible orientado
tanto a aplicaciones en el lado del servidor como del cliente.
Soporta una variada gama de tipos de salidas diferentes,
incluyendo componentes Swing, archivos de imagen (incluyendo
PNG y JPEG) e incluso archivos en formato vectorial (incluyendo
PDF, EPS y SVG).
33
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
JFreeChart es de código abierto, más concretamente, es software libre.
Se distribuye bajo los términos de la licencia GNU LGPL (GNU Lesser
General Public Licence), la cual permite su uso en aplicaciones propietarias.
Algunos ejemplos de lo que esta librería es capaz de ofrecer se muestran
en las siguientes figuras:
34
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
Esta librería constituye el corazón de la representación gráfica de la
salida de los cálculos realizados por nuestro desarrollo. Las clases de esta
librería utilizada en el desarrollo de esta aplicación han sido las siguientes:
•
•
•
•
•
•
org.jfree.chart.axis.NumberAxis:
La
clase
NumberAxis
implementa un eje para la visualización de datos numéricos. Si el
eje está configurado para determinar automáticamente su rango
para mostrar los datos, se puede asegurar que el cero está
incluido dentro del rango configurando autoRangeIncludesZero a
true. Esta clase tiene un mecanismo para seleccionar
automáticamente la unidad de división apropiada dependiendo del
rango del eje.
org.jfree.chart.ChartFactory: La clase ChartFactory incluye una
colección de métodos para crear diferentes gráficos estándar de
JFreeChart (diagramas de Gantt, tartas, de barras, de área, etc.).
org.jfree.chart.ChartFrame: Esta clase implementa un marco
para mostrar por pantalla el gráfico.
org.jfree.chart.ChartPanel: La clase ChartPanel implementa un
componente Swing para mostrar un objeto JFreeChart.
org.jfree.chart.JFreeChart: La clase JFreeChart es una clase
para el graficado implementada utilizando la API Java 2D. La
versión actual soporta diagramas de barras, gráficos lineales,
diagramas de tarta y representaciones XY (incluyendo series
temporales). JFreeChart coordina varios objetos para realizar la
representación, incluyendo objetos de títulos, dibujado y un
conjunto de datos.
org.jfree.chart.plot.PlotOrientation: Esta clase es utilizada
para determinar la orientación del gráfico 2D (horizontal o
vertical).
35
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
•
•
•
•
•
org.jfree.chart.plot.XYPlot: Esta es una clase general para
graficar datos en formato de pares (x, y). Esta clase puede utilizar
datos de cualquier clase que implemente la interfaz XYDataset.
Esta clase hace uso deun XYItemRenderer para dibujar cada punto
en el gráfico. Por medio del uso de diferentes renderers se pueden
producir diferentes tipos de gráficos.
org.jfree.chart.renderer.xy.XYLineAndShapeRenderer: Esta
clase implementa un renderer que conecta puntos de datos con
líneas o dibuja la forma de cada punto. Este renderer está
diseñado para ser utilizado con la clase XYPlot.
org.jfree.data.Range: Esta clase representa un rango inmutable
de valores.
org.jfree.data.xy.XYSeries: Esta clase representa una serie de
cero o más elementos de datos en formato (x, y). Por defecto, los
elementos en la serie se clasifican en orden ascendente de X y se
permite duplicar valores de X. Tanto el ordenado como la
duplicación por defecto se pueden modificar en el constructor. Los
valores de Y pueden ser Null para representar valores que faltan.
org.jfree.data.xy.XYSeriesCollection: Esta clase representa
una colección de objetos XYSeries que pueden ser utilizados como
un conjunto de datos.
3.3.5 JTransforms
JTransforms constituye la primera librería FFT multiprocesador y de
código abierto escrita 100% en Java. Actualmente tiene disponibles los
siguientes tipos de transformaciones:
•
•
•
•
Discrete
Discrete
Discrete
Discrete
Fourier Transform (DFT)
Cosine Transform (DCT)
Sine Transform (DST)
Hartley Transform (DHT)
El código de esta librería viene derivado del General Purpose FFT
Package escrito por Takuya Ooura y del Java FFTPack escrito por Baoshe
Zang.
Algunos de los proyectos que hacen uso de la librería JTransforms son:
•
•
•
•
Music Reader: Un software que hace fácil la lectura de la música.
Spectro-Edit: Un software para la visualización del audio en un
gráfico tiempo-frecuencia.
YAPRNN: Un software para el reconocimiento de patrones en
redes neuronales.
ExpertEyes: Un software de código abierto para aplicaciones de
seguimiento de ojos.
Las características fundamentales de esta librería son las siguientes:
36
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
•
•
•
•
•
•
•
Rápida implementación de DFT, DCT, DST y DHT.
Transformaciones en 1, 2 y 3 dimensiones.
Tamaño de datos arbitrario.
Precisión normal y doble.
Variaciones
unidimensional
y
multidimensional
de
transformaciones 2D y 3D.
Multiprocesado automático si existe más de una CPU.
FFTs optimizadas para datos reales (un 40% más rápida que con
datos complejos).
Esta librería está distribuida bajo los términos de la licencia
MPL/LGPL/GPL. El uso principal que se le ha dado en nuestro desarrollo ha
sido el de calcular la FFT y la FFT inversa. Por tanto, la única clase utilizada
en nuestro código ha sido la siguiente:
•
3.4
edu.emory.mathcs.jtransforms.fft.DoubleFFT_1D: Calcula la
DFT unidimensional con datos de precisión Double reales y/o
complejos. El tamaño de los datos puede ser arbitrario, si bien
está optimizado para potencias de 2.
CLASES PROPIAS
Las clases propias están agrupadas en diferentes paquetes dependiendo
de la funcionalidad de cada una. La estructura de las mismas es la
siguiente:
Como se puede comprobar en la figura anterior, las clases están
agrupadas en 5 paquetes, siendo la funcionalidad de cada agrupación la
siguiente:
•
us.tds.algebra: En este paquete están agrupadas todas las
clases encargadas del cálculo a bajo nivel de las secuencias y las
37
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
•
•
•
•
distintas operaciones entre ellas. En este paquete están incluidas
las clases Sequence y SequenceGraphOperations.
us.tds.applet: En este paquete están agrupadas las clases
principales de la aplicación, las que se encargan de coordinar
todas las clases y mostrar la información al usuario de manera
amigable.
En
este
paquete
está
incluida
la
clase
AppletGUI_v1_00. En el caso de la aplicación autoejecutable,
estaría incluida también la clase ApplicationLauncher.
us.tds.chart: En este paquete están agrupadas las clases
encargadas de imprimir por pantalla las gráficas de las diferentes
secuencias. En este paquete está incluida la clase SequenceChart.
us.tds.graph: En este paquete están agrupadas las clases
encargadas de trabajar con el grafo mostrado en el Panel de
Operaciones. En este paquete está incluida la clase TDSGraph.
us.tds.utils: En este paquete están agrupadas las clases que, si
bien no son imprescindibles, sí que son útiles para realizar
determinadas funciones de importancia menor dentro de la
aplicación. En este paquete están incluidas las clases
EditableTableModel, NotEditableTableModel y TDSJTable.
3.4.1 Sequence
En esta clase se implementan las herramientas básicas para tratar con
secuencias, desde su almacenamiento y modificación hasta el cálculo de
operaciones básicas con secuencias.
Esta clase tiene tres constructores diferentes:
•
•
•
Sequence(int minTime, int maxTime, String type, Complex
param1, Complex param2, Complex param3, Complex
param4) : Construye un objeto Sequence con las características
determinadas por sus argumentos, tiempo mínimo, tiempo
máximo, tipo de secuencia y determinados parámetros en función
del tipo de secuencia.
Sequence(int size) : Construye un objeto Sequence con valores
ceros del tamaño descrito en el argumento.
Sequence() : Construye un objeto sequence con un único valor
cero en la posición cero temporal.
Las instancias de esta clase son dos:
•
time: Es un vector de enteros donde se almacena el valor
temporal de cada muestra, es decir, el valor de n. Esta instancia
es privada.
38
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
•
•
value: Es un vector de complejos donde se almacenan los valores
que toma la secuencia, es decir el valor de x(n). Esta instancia
también es privada.
sequenceType: Es una variable tipo cadena de texto donde se
almacena el tipo de secuencia que es, si temporal o de frecuencia.
Esta instancia también es privada.
Al ser las tres instancias anteriores privadas, la única manera de acceder
a sus valores es a través de los métodos proporcionados en esta clase.
Además de los métodos encargados de transformar las dos instancias de
esta clase, existen otros métodos encargados de realizar operaciones con
secuencias como sumar, multiplicar, calcular la FFT, etc.
Los métodos que componen esta clase se presentan a continuación.
Modificador y tipo
Método
Sequence
Sequence
boolean
boolean
Sequence
Sequence
void
Sequence
Sequence
Sequence
double[]
Sequence
Sequence
Sequence
Sequence
double
double
double
double
int
double
double
double
double
int
int
org.apache.commons.mat
h3.complex.Complex
Sequence
Sequence
add(Sequence sequence1)
antisymmetricConjugatePart()
checkSequenceOverflow()
checkString(java.lang.String valuesString)
circularTimeInvert(int N)
circularTimeTranslate(int time_translation, int N)
clearSequence()
conjugate()
convolve(Sequence sequence1)
convolveCircular(Sequence sequence1, int N)
getComplexArrayFromSequenceForFFT(int N)
getFFT(int points, boolean pointsAuto)
getFFT(int points, int N)
getInverseFFT(int points, boolean pointsAuto)
getInverseFFT(int points, int N)
getMaxImaginaryValue()
getMaxModuleValue()
getMaxPhaseValue()
getMaxRealValue()
getMaxTime()
getMinImaginaryValue()
getMinModuleValue()
getMinPhaseValue()
getMinRealValue()
getMinTime()
getNearestPowerOf2(int input)
getNumericValueOfSingleString(java.lang.String values
String)
getPolarSequence()
getSequenceFromComplexArrayForFFT(double[] array)
Sequence
getSequenceFromString(java.lang.String valuesString)
39
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
Modificador y tipo
java.lang.String
int
java.lang.String
org.apache.commons.mat
h3.complex.Complex
org.apache.commons.mat
h3.complex.Complex
double
boolean
boolean
boolean
Sequence
Sequence
Sequence
void
boolean
void
void
void
void
void
Sequence
Sequence
Sequence
Método
getSequenceType()
getSize()
getStringFromSequence()
getSummation()
getValueAt(int time_data)
idealLPFilterSequence(double x, double wc)
isFrequencySequenceType()
isSequenceTypeSet()
isTimeSequenceType()
multiplicateByNumber(org.apache.commons.math3.co
mplex.Complex factor)
multiplicateBySequence(Sequence sequence1)
power(org.apache.commons.math3.complex.Complex
power)
printSequence()
sequenceIsEmpty()
setCopyOf(Sequence sequence1)
setSameSequenceTypeAs(Sequence sequence)
setSequenceTypeAsFrequency()
setSequenceTypeAsTime()
setValueAt(org.apache.commons.math3.complex.Com
plex value_data, int time_data)
symmetricConjugatePart()
timeInvert()
timeTranslate(int time_translation)
Por lo demás, poco más se puede añadir de esta clase que, constituye el
álgebra básica con el que se realizan los cálculos con secuencias. Claro está,
con esta clase tan sólo se podría construir un programa simple de cálculo
por línea de comando. Para realizar cálculos mediante interfaz gráfica habría
que construir otros objetos a más alto nivel con los que trabajar. Es por ello
por lo que se crea la siguiente clase.
3.4.2 SequenceGraphOperations
Esta clase, como su propio nombre indica, está pensada para integrar las
operaciones con secuencias en el entorno de trabajo gráfico de nuestra
aplicación.
La clase SequenceGraphOperations implementa el núcleo de los bloques
funcionales del grafo de la aplicación, integrando las operaciones de dicho
bloque funcional, el número de entradas/salidas, los valores de las
secuencias de entrada/salida y los propios atributos de dichos bloques
funcionales.
Los constructores de esta clase son dos:
40
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
•
•
SequenceGraphOperations(): Este constructor crea un objeto
vacío, por lo que para darle forma, habrá que introducir los
cambios a través de los múltiples métodos de esta clase.
SequenceGraphOperations(String type, String typeNode,
int inputsNumber, int outputsNumber): Este constructor crea
un objeto del tipo y número de entradas/salidas indicado en los
argumentos. El argumento type hace referencia al tipo de bloque
funcional (Sink, Source, Intermediate), mientras que el
argumento typeNode hace referencia al tipo de operación que
implementa. Dependiendo del tipo de operación tendrá asociados
unos atributos u otros y un tipo de operación interna u otra.
Por su parte, las instancias de esta clase son las siguientes:
•
•
•
•
attributes: Es un vector de vectores con dos columnas, la
primera para indicar el atributo y la segunda para indicar el valor
del atributo. Cada atributo tiene una etiqueta única en la primera
columna que resulta identificativa.
inputs: Es un vector de secuencias (Sequence). En este vector se
guardan las secuencias de entrada al bloque funcional.
outputs: Es un vector de secuencias (Sequence). En este vector
se guardan los resultados de realizar los cálculos propios del
bloque funcional.
internalSequence: Es una secuencia (Sequence). En esta
variable se guardan las secuencias características de un bloque
funcional que no puedan actuar como entradas o salidas del
mismo, es decir, que sean inherentes al propio bloque funcional,
por ejemplo, para un filtro, en esta variable se guardaría la
respuesta impulsional del filtro.
Una vez descritos los constructores e instancias, daremos paso a la
descripción de los métodos de esta clase.
Modificador y tipo
Sequence
boolean
boolean
java.lang.String
boolean
boolean
boolean
boolean
boolean
boolean
boolean
boolean
boolean
org.apache.commons.math
Método
calculate()
checkOverflow()
checkSequenceTypeMismatch()
getAttribute(java.lang.String type)
getAttributeAutoPointsFFT()
getAttributeAutoXImaginary()
getAttributeAutoXModule()
getAttributeAutoXPhase()
getAttributeAutoXReal()
getAttributeAutoYImaginary()
getAttributeAutoYModule()
getAttributeAutoYPhase()
getAttributeAutoYReal()
getAttributeComplexConstant(int number)
41
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
Modificador y tipo
3.complex.Complex
int
java.awt.Color
double
java.lang.String
java.lang.String
java.awt.Color
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
double
java.awt.Color
java.lang.String
java.lang.String
java.awt.Color
java.awt.Color
java.lang.String
java.lang.String
java.awt.Color
int
java.awt.Color
double
java.lang.String
java.lang.String
java.awt.Color
boolean
java.lang.String
java.lang.String
java.lang.String
java.lang.String
Sequence
Sequence
int
int
Sequence
void
void
int
void
Método
getAttributeDelay()
getAttributeImaginaryBackgroundColor()
getAttributeImaginaryConstant(int number)
getAttributeImaginaryLabelX()
getAttributeImaginaryLabelY()
getAttributeImaginaryLineColor()
getAttributeMaxXImaginary()
getAttributeMaxXModule()
getAttributeMaxXPhase()
getAttributeMaxXReal()
getAttributeMaxYImaginary()
getAttributeMaxYModule()
getAttributeMaxYPhase()
getAttributeMaxYReal()
getAttributeMinXImaginary()
getAttributeMinXModule()
getAttributeMinXPhase()
getAttributeMinXReal()
getAttributeMinYImaginary()
getAttributeMinYModule()
getAttributeMinYPhase()
getAttributeMinYReal()
getAttributeModuleBackgroundColor()
getAttributeModuleLabelX()
getAttributeModuleLabelY()
getAttributeModuleLineColor()
getAttributePhaseBackgroundColor()
getAttributePhaseLabelX()
getAttributePhaseLabelY()
getAttributePhaseLineColor()
getAttributePointsFFT()
getAttributeRealBackgroundColor()
getAttributeRealConstant(int number)
getAttributeRealLabelX()
getAttributeRealLabelY()
getAttributeRealLineColor()
getAttributeSequenceCustomized()
getAttributeSequenceType()
getAttributeType()
getAttributeTypeNode()
getAttributeValue()
getInput(int input)
getInternalSequence()
getNumberOfInputs()
getNumberOfOutputs()
getOutput(int output)
initializeToZero()
printAttributes()
searchAttribute(java.lang.String type)
setAttribute(java.lang.String type,
java.lang.String value)
42
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
Modificador y tipo
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
void
Método
setAttributeAutoPointsFFT(boolean state)
setAttributeAutoXImaginary(boolean state)
setAttributeAutoXModule(boolean state)
setAttributeAutoXPhase(boolean state)
setAttributeAutoXReal(boolean state)
setAttributeAutoYImaginary(boolean state)
setAttributeAutoYModule(boolean state)
setAttributeAutoYPhase(boolean state)
setAttributeAutoYReal(boolean state)
setAttributeComplexConstant(org.apache.commons.ma
th3.complex.Complex complexConstant, int number)
setAttributeComplexConstant(double realConstant,
double imaginaryConstant, int number)
setAttributeDelay(int delay)
setAttributeImaginaryBackgroundColor(java.awt.Color
color)
setAttributeImaginaryConstant(double imaginaryConst
ant, int number)
setAttributeImaginaryLabelX(java.lang.String label)
setAttributeImaginaryLabelY(java.lang.String label)
setAttributeImaginaryLineColor(java.awt.Color color)
setAttributeMaxXImaginary(double value)
setAttributeMaxXModule(double value)
setAttributeMaxXPhase(double value)
setAttributeMaxXReal(double value)
setAttributeMaxYImaginary(double value)
setAttributeMaxYModule(double value)
setAttributeMaxYPhase(double value)
setAttributeMaxYReal(double value)
setAttributeMinXImaginary(double value)
setAttributeMinXModule(double value)
setAttributeMinXPhase(double value)
setAttributeMinXReal(double value)
setAttributeMinYImaginary(double value)
setAttributeMinYModule(double value)
setAttributeMinYPhase(double value)
setAttributeMinYReal(double value)
setAttributeModuleBackgroundColor(java.awt.Color col
or)
setAttributeModuleLabelX(java.lang.String label)
setAttributeModuleLabelY(java.lang.String label)
setAttributeModuleLineColor(java.awt.Color color)
setAttributePhaseBackgroundColor(java.awt.Color color
)
setAttributePhaseLabelX(java.lang.String label)
setAttributePhaseLabelY(java.lang.String label)
setAttributePhaseLineColor(java.awt.Color color)
setAttributePointsFFT(int value)
setAttributeRealBackgroundColor(java.awt.Color color)
setAttributeRealConstant(double realConstant,
int number)
43
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
Modificador y tipo
void
void
void
void
void
Método
setAttributeRealLabelX(java.lang.String label)
setAttributeRealLabelY(java.lang.String label)
setAttributeRealLineColor(java.awt.Color color)
setAttributeSequenceCustomized(boolean customized)
setAttributeSequenceType(java.lang.String sequenceT
ype)
setAttributeType(java.lang.String type)
setAttributeTypeNode(java.lang.String typeNode)
setAttributeValue(java.lang.String value)
setInput(int input, Sequence sequence)
setInternalSequence(Sequence sequence)
setOutput(int output, Sequence sequence)
void
void
void
int
void
int
Como se puede comprobar, existen muchos métodos del tipo
setAttribute y getAttribute. Estos métodos se utilizan para modificar el
vector attributes de una manera segura y controlada, no permitiendo al
usuario que realice modificaciones indeseadas o que puedan provocar error.
Por otro lado, además de estos métodos, los principales son los
siguientes:
•
•
•
setInput/setOutput/setInternalSequence: Estos métodos
establecen el valor de la secuencia de entrada/salida/interna.
getInput/getOutput/getInternalSequence: Estos métodos
devuelven el valor de la secuencia de entrada/salida/interna.
calculate: Este método es el núcleo principal de la clase ya que
es el que realiza el cálculo asociado al bloque funcional con las
entradas y lo inserta en el vector de salidas.
El ciclo de funcionamiento a nivel interno de esta clase sería el siguiente:
1.
2.
3.
4.
5.
Crear el objeto
Establecer los atributos fundamentales
Establecer secuencias de entrada
Realizar el cálculo interno
Obtener secuencias de salida
3.4.3 SequenceChart
El cometido principal de esta clase es el de servir como soporte a las
operaciones de representación de gráficas a través de la librería JFreeChart.
Es una clase de segundo nivel, de soporte a otras clases que trabajan
directamente con la clase principal.
Su constructor es único, SequenceChart(), y crea el objeto sin más. No
están definidas instancias para esta clase, ya que como hemos explicado
anteriormente, tan sólo sirve de interfaz de cara a la librería JFreeChart.
44
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
Esta clase ofrece una interfaz amigable a la hora de realizar las
representaciones de gráficas. Tanto es así que están definidos tan sólo
cuatro métodos:
Modificador y tipo
org.jfree.chart.JFreeChart
org.jfree.chart.JFreeChart
org.jfree.chart.JFreeChart
org.jfree.chart.JFreeChart
Método
createImaginaryChart(java.lang.String imaginary_title,
java.lang.String imaginary_x_axis_label,
java.lang.String imaginary_y_axis_label, Sequence seq
uence,
java.awt.Color lineColor,
java.awt.Color backgroundColor,
boolean autoX,
boolean autoY,
double minX,
double maxX,
double minY, double maxY)
createModuleChart(java.lang.String module_title,
java.lang.String module_x_axis_label,
java.lang.String module_y_axis_label, Sequence seque
nce,
java.awt.Color lineColor,
java.awt.Color backgroundColor,
boolean autoX,
boolean autoY,
double minX,
double maxX,
double minY, double maxY)
createPhaseChart(java.lang.String phase_title,
java.lang.String phase_x_axis_label,
java.lang.String phase_y_axis_label, Sequence sequen
ce,
java.awt.Color lineColor,
java.awt.Color backgroundColor,
boolean autoX,
boolean autoY,
double minX,
double maxX,
double minY, double maxY)
createRealChart(java.lang.String real_title,
java.lang.String real_x_axis_label,
java.lang.String real_y_axis_label, Sequence sequence
,
java.awt.Color lineColor,
java.awt.Color backgroundColor,
boolean autoX,
boolean autoY,
double minX,
double maxX,
double minY, double maxY)
Estos cuatro métodos devuelven un objeto tipo JFreeChart ya construido,
tan sólo para ser insertado en un ChartFrame. Los argumentos que se le
pasan a cada uno de estos cuatro métodos son todos similares: título del
gráfico, etiqueta de ejes X e Y, la secuencia, el color de líneas y de fondo,
los valores máximos y mínimos de ejes entre los cuales representar y si
estos valores pueden ser calculados automáticamente o no.
Cabe reseñar, como nota curiosa, que en la librería JFreeChart no existe
ningún gráfico del tipo secuencia utilizado en esta aplicación. Para realizar
esta representación se ha tenido que utilizar un pequeño truco; se ha
utilizado un gráfico tipo XY con dos series de datos, por un lado una serie
con representación gráfica en formato punto y sin línea y otras tantas series
como puntos existiesen con representación gráfica en formato de línea con
el objetivo de hacer el “cuerpo” de cada punto.
Los valores de la serie de puntos no han tenido que ser modificados, ya
que por cada par (x,y) se generaba un punto aislado; sin embargo, para
45
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
conseguir representar las líneas verticales sin conexión entre todas ellas, se
han creado tantas series como puntos existiesen, siendo dos los valores de
cada una de estas series, (x,y) y (0,y).
Una vez superpuestas todas las series en la gráfica y coloreándolas con
el mismo color, da la sensación de que el gráfico es de tipo secuencia, como
se puede observar en la siguiente figura.
3.4.4 TDSGraph
Es en esta clase donde reside, por así decirlo, el cerebro de la aplicación.
No es la clase principal de la aplicación, ya que ese papel le corresponde a
la clase AppletGUI_v1_00, pero sí que es la clase más importante.
Esta clase extiende a mxGraph, que es la clase generadora de grafos de
la librería JGraphX y, por tanto, hereda de la clase padre todos los
constructores, instancias y métodos.
Además de todo esto, también se han definido nuevas instancias y
métodos a esta clase para enlazarla con el cálculo de secuencias y bloques
funcionales desarrollado en las clases anteriormente descritas.
Las instancias definidas son las siguientes:
•
•
•
•
•
style: En este objeto de tipo Map se guardan los atributos del
estilo de representación gráfica de las aristas del grafo.
parent: En este objeto se guarda el objeto Padre del grafo, es
decir, la celda de la cual cuelgan todos los elementos del grafo
como aristas y vértices.
PORT_DIAMETER y PORT_RADIUS: Son dos constantes que
determinan el tamaño de los puertos de los bloques funcionales.
vertexVector: En este vector se guardan todos los vértices que
componen el grafo.
edgesToPortsMatrix: En este vector de vectores se guardan los
orígenes y destinos de todas las aristas del grafo, teniendo como
elemento origen y destino el puerto al que están conectadas las
aristas. La primera columna identifica al origen y la segunda al
destino
46
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
•
•
•
•
•
•
edgesToVertexMatrix: Este vector de vectores tiene la misma
filosofía que el anterior, guarda los vértices origen y destino de
todas las aristas del grafo. Además incluye también el número de
salida y de entrada al que están conectadas estas aristas dentro
de cada uno de los bloques funcionales. El formato es columna 0,
origen, columna 1, destino, columna 2, número de salida,
columna 3, número de entrada.
operationsMatrix: En este vector de vectores se guarda la
información relativa a cada uno de los bloques funcionales
añadidos al grafo. La estructura de la información guardada es,
por orden de columnas, Cell (la identificación del vértice del
bloque funcional), SequenceGraphOperations (el objeto de
operación asociado al bloque funcional), TypeNode (Source, Sink,
Intermediate), TypeOperation (Multiplication, Convolution,etc).
sourcePathMatrix: En este vector de vectores se guarda la
información relativa a caminos encontrados desde los vértices
fuente hasta los vértices sumidero o hasta encontrar un lazo. En
las filas se guardan cada uno de los caminos, mientras que en las
columnas se guarda la identificación del vértice en formato
numérico (según la matriz de adyacencia).
sinkPathMatrix: Este vector de vectores tiene la misma función
que el anterior solo que el recorrido de los caminos es el inverso,
desde los nodos sumidero hasta los nodos fuente o hasta
encontrar un lazo. La estructura de la información dentro de la
instancia es la misma.
adjacenceMatrix: En este array bidimensional se guarda la
información relativa a la matriz de adyacencias del grafo a nivel
de vértice (no a nivel de puerto). Las filas denotan el vértice
origen, mientras que las columnas denotan los vértices destino. Si
el elemento es cero, significa que no hay conectividad entre origen
y destino. Si el elemento es mayor que cero, hay tantas aristas
entre el vértice origen y destino como indique el elemento.
iterationsNumber: En este entero se guarda el número de
iteraciones a realizar en el momento del cálculo en caso de existir
lazos en el grafo.
Por su parte, los métodos definidos en esta clase son los siguientes:
Modificador y tipo
java.lang.String
java.lang.String
void
java.lang.String
int
void
void
boolean
Método
analyseGraph()
analysis()
calculateOperations()
checkOperations()
countTypeOfVertex(java.lang.String type)
deleteCell(com.mxgraph.model.mxCell selectedCell)
deleteLineInOperationsMatrix(com.mxgraph.model.mx
Cell vertex)
errorOfOperationConnectionsNumber()
47
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
Modificador y tipo
boolean
boolean
boolean
boolean
void
java.lang.String
SequenceGraphOperations
java.lang.String
java.lang.String
void
void
int
int
int
int
int
Sequence
void
void
java.lang.String
void
void
void
com.mxgraph.model.mxCel
l
void
void
boolean
boolean
boolean
boolean
boolean
int
boolean
boolean
boolean
void
void
Método
errorOfOperationsNotConnectedToSink()
errorOfOperationsNotConnectedToSource()
errorOfSinkConnectionsNumber()
errorOfSourceConnectionsNumber()
getAdjacenceMatrix()
getCellAttribute(com.mxgraph.model.mxCell cell,
java.lang.String attribute)
getCellSequenceGraphOperation(com.mxgraph.model.
mxCell cell)
getCellType(com.mxgraph.model.mxCell cell)
getCellTypeNode(com.mxgraph.model.mxCell cell)
getEdgesToPortsMatrix()
getEdgesToVertexMatrix()
getInputNumberFromEdgesToVertexMatrix(com.mxgra
ph.model.mxCell source,
com.mxgraph.model.mxCell terminal,
int lastInputNumber)
getInputPortNumber(com.mxgraph.model.mxCell cell)
getIterationsNumber()
getOutputNumberFromEdgesToVertexMatrix(com.mxgr
aph.model.mxCell source,
com.mxgraph.model.mxCell terminal,
int lastOutputNumber)
getOutputPortNumber(com.mxgraph.model.mxCell cell
)
getOutputSequence(com.mxgraph.model.mxCell cell)
getSinkPathMatrix()
getSourcePathMatrix()
getToolTipForCell(java.lang.Object cell)
getVertexVector()
initGraph()
initializeOperationsToZero()
insertBox(java.lang.String name,
int inputs,
int outputs, int x, int y)
insertLineInOperationsMatrix(com.mxgraph.model.mx
Cell vertex,SequenceGraphOperations sequenceGraph
Operation)
insertOperation(java.lang.String type,
int xPosition,
int yPosition)
isCellEditable(java.lang.Object cell)
isCellFoldable(java.lang.Object cell, boolean collapse)
isDeletableTheCell(com.mxgraph.model.mxCell cell)
isDoubleRepeatedElementInPath(int element,
java.util.Vector path)
isEdgeCorrect(com.mxgraph.model.mxCell cell)
isInEdgesToPortsMatrix(com.mxgraph.model.mxCell ce
ll, java.lang.String type)
isOnlyPlotCompare(com.mxgraph.model.mxCell cell)
isPlot(com.mxgraph.model.mxCell cell)
isRepeatedElementInPath(int element,
java.util.Vector path)
printAdjacenceMatrix()
printCells(java.lang.String label,
48
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
Modificador y tipo
void
void
void
void
void
void
int
void
void
void
void
void
void
void
void
boolean
boolean
boolean
boolean
void
Método
java.lang.Object[] cells)
printEdgesToPortsMatrix()
printEdgesToVertexMatrix()
printSinkPathMatrix()
printSourcePathMatrix()
printVertexVector()
refreshGraph()
searchVertexInOperationsMatrix(com.mxgraph.model.
mxCell vertex)
setCellAttribute(com.mxgraph.model.mxCell cell,
java.lang.String attribute,
java.lang.String attributeValue)
setOutputSequence(com.mxgraph.model.mxCell cell, S
equence sequence)
showCartesianPlot(com.mxgraph.model.mxCell cell)
showImaginaryPlot(com.mxgraph.model.mxCell cell)
showModulePlot(com.mxgraph.model.mxCell cell)
showPhasePlot(com.mxgraph.model.mxCell cell)
showPolarPlot(com.mxgraph.model.mxCell cell)
showRealPlot(com.mxgraph.model.mxCell cell)
sinkContainsBadLoop()
sinkContainsLoop()
sourceContainsBadLoop()
sourceContainsLoop()
updateData()
Esta lista de métodos como tal, puede darnos poca información del
funcionamiento de la aplicación, ya que es información totalmente inconexa
la que podemos deducir del nombre de los métodos. Así pues,
procederemos a explicar con un poco más de detenimiento el
funcionamiento de esta clase.
Cuando se añade un bloque funcional al grafo del Panel de Operaciones,
se desencadena una llamada al método insertOperation que, por un lado
realiza el dibujo del vértice con sus puertos de entrada y salida
predeterminados según el tipo de operación y, por otro, crea el objeto
SequenceGraphOperations asociado al tipo de operación del bloque
funcional. Toda esta información se añade a la instancia operationsMatrix.
En caso de que el bloque funcional sea eliminado, se hace una llamada a
deleteCell que elimina esa entrada de la operationsMatrix y del grafo del
Panel de Operaciones.
Cuando, en el proceso de ejecución normal de la aplicación, se quiere
visualizar un resultado por pantalla, bien a través de los Show Plots, o bien
a través del Print Numeric Values, se hace una llamada al método analysis
que realiza la función de cálculo en cuatro pasos:
1. Actualiza los datos (llamada a updateData).
2. Analiza el grafo (llamada a analyseGraph).
49
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
3. Si no hay error, calcula el resultado de las operaciones
(llamada a calculateOperations).
4. Comprueba si no hay errores de desbordamiento en las
operaciones (llamada a checkOperations).
Analicemos ahora más detenidamente qué hace cada uno de estos
cuatro métodos llamados.
3.4.4.1 updateData
Este método realiza la actualización de las instancias del grafo asociadas
a la morfología del mismo. Es decir, recoge los datos del estado actual del
grafo para poder analizarlo con detenimiento. Las instancias que se
actualizan son las siguientes:
•
•
•
•
•
edgesToPortsMatrix,
a
través
del
método
getEdgesToPortsMatrix.
edgesToVertexMatrix,
a
través
del
método
getEdgesToVertexMatrix.
adjacenceMatrix, a través del método getAdjacenceMatrix.
sourcePathMatrix, a través del método getSourcePathMatrix,
que realiza la búsqueda de caminos por el método de búsqueda en
anchura (BFS).
sinkPathMatrix, a través del método getSinkPathMatrix, que
realiza la búsqueda de caminos por el método de búsqueda en
anchura (BFS).
3.4.4.2 analyseGraph
Una vez actualizados los datos morfológicos del grafo, llega la hora de
analizarlos. El método analyseGraph se encarga de esta función.
Este método comprueba que todos los bloques funcionales estén
conectados, que no haya puertos sin conectar, que existan al menos una
fuente y un sumidero de información e incluso que los lazos que existan,
tengan un retraso incluido y que este sea distinto de cero.
En caso de encontrar error, este método devolverá una cadena de
caracteres con los errores encontrados.
50
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
3.4.4.3 calculateOperations
En caso de no haber encontrado error a la hora de analizar el grafo, se
realizará el cálculo de las operaciones contenidas en él. Es por ello por lo
que se realiza la llamada al método calculateOperations.
Este método sigue una pauta muy simple y es colocar todas las
secuencias de salida de los bloques operacionales en los puertos de entrada
indicados por la matriz de adyacencias y realizar el cálculo de cada bloque
funcional. Este paso se repite tantas veces como indique el número de
iteraciones.
El número de iteraciones depende del tipo de grafo. Si tenemos un grafo
sin lazos, el número de iteraciones se calcula teniendo en cuenta el camino
más largo entre una fuente y un sumidero. Si en el grafo se encuentra
algún lazo, el número de iteraciones es el predeterminado por la instancia
iterationsNumber de la clase.
3.4.4.4 checkOperations
Por último, una vez realizados todos los cálculos, llega el momento de
comprobar si ha habido desbordamiento en las operaciones. Este método
comprueba que ningún resultado de las operaciones contiene elementos que
son infinitos o NaN.
En caso de encontrar error devuelve una cadena de caracteres con el
error encontrado.
3.4.5 EditableTableModel y NotEditableTableModel
Ambas clases son clases de segundo nivel, es decir, que sirven de
soporte a otra clase de primer nivel, como es la TDSJTable, que trata
directamente con la clase principal.
Estas dos clases han sido creadas con el único objetivo de permitir
convertir una tabla de datos en editable y no editable de la manera más
rápida posible.
Ambas clases extienden a la clase DefaultTableModel, que es la clase
base de Java para la construcción de tablas de datos. Estas clases, al ser
extensiones, no tienen definidos constructores (ya que utilizan el propio de
la clase padre). Tan sólo tienen dos métodos (además de los propios del
padre) que se superponen a los de la clase padre:
51
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
Modificador y tipo
java.lang.Class
boolean
Método
getColumnClass(int col)
isCellEditable(int row, int column)
El método getColumnClass devuelve las clases según el formato
predeterminado para nuestras tablas de datos, es decir, la primera columna
es de tipo Integer, mientras que el resto son de tipo Double.
Por su parte, el método isCellEditable devuelve siempre verdadero o
siempre falso, dependiendo de si la clase es EditableTableModel o
NotEditableTableModel respectivamente. Es mediante este artificio que se
consigue una tabla de datos editable o no editable.
3.4.6 TDSJTable
La clase TDSJTable extiende a la clase JTable de Java. Esta clase se ha
creado con el objetivo de conseguir añadir, eliminar y extraer datos de
manera rápida de las tablas de datos utilizadas en la aplicación además de
poder hacerlas editables y no editables con total facilidad.
Esta clase, aunque hereda los constructores, métodos e instancias de la
clase padre, JTable, tiene definidos varios métodos más:
Modificador y tipo
static void
static void
static void
static
static
static
static
void
boolean
void
void
static void
Método
add2SequencesToTable(Sequence sequence1, Sequenc
e sequence2, javax.swing.JTable table)
addSequenceToTable(Sequence sequence,
javax.swing.JTable table)
addTableToSequence(Sequence sequence,
javax.swing.JTable table)
cleanTable(javax.swing.JTable table)
errorTableValues(javax.swing.JTable table)
setTableEditable(javax.swing.JTable table)
setTableLimits(javax.swing.JTable table,
int minSet,
int maxSet)
setTableNotEditable(javax.swing.JTable table)
Como se puede observar, los métodos son autodescriptivos, por lo que
no nos extenderemos más en la explicación y remitiremos al lector
interesado a la documentación de la aplicación (javadoc) para ampliar la
información.
52
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
3.4.7 AppletGUI_v1_02 y ApplicationLauncher
Estas son las clases principales del applet y la aplicación. Para el
primero, sólo es necesaria la clase AppletGUI_v1_02, para la aplicación,
además de la clase anterior, es necesaria la clase ApplicationLauncher.
El objeto de la clase ApplicationLauncher es el de crear un JFrame dentro
del lazo main que sirva de soporte para que la clase AppletGUI_v1_00 se
ejecute dentro de él.
Por su parte, la clase AppletGUI_v1_02 es la clase principal donde reside
toda la lógica de la aplicación. Es decir, se encarga de aglutinar todas las
partes funcionales en las que se divide el código y ofrecer al usuario una
interfaz amigable.
La programación de esta clase está basada en eventos. Quiere ello decir
que la aplicación salta de un estado a otro a través de los distintos eventos
provocados por el usuario como consecuencia de su interacción con la
aplicación, es decir, no sigue un proceso lineal de ejecución, sino que es el
usuario, en su libre albedrío, el que decide cómo se ejecuta la aplicación.
En esta clase también está contenido el formulario de la aplicación, que
es la “cara visible” de todo el código programado. Como se puede observar
en la siguiente figura, existen dos grandes grupos, por un lado el grupo
JApplet, que constituye la ventana principal donde se ejecuta el applet en el
navegador y, por otro lado, Other Components, que constituyen todas las
ventanas y cuadros de diálogos presentes en la ventana emergente de la
aplicación una vez esta se ejecuta.
53
SOFTWARE PARA CÁLCULO Y APRENDIZAJE DE SEÑALES
DISCRETAS
54
Descargar