sábado, 31 de mayo de 2014

Cálculo de la determinante de una matriz de Orden n

En este artículo voy a mostrarles la manera de calcular la determinante de una matriz de orden n. Cuando la matriz es de orden 2 o 3, es sencillo calcular la determinante pero ya cuando hablamos de matrices de órdenes superiores, apoyarnos en algún algoritmo computacional es una excelente idea. Para éste ejemplo, vamos a calcular al determinante de la siguiente matriz:


La idea es convertir a la matriz mediante operaciones elementales en una matriz triangular equivalente, pues en este caso la determinante estará dada por el producto de todos los términos de la diagonal principal, multiplicada por -1 si se hizo un número impar de cambios.

El algoritmo es el siguiente:

1.- Buscamos la fila con el mayor elemento en valor absoluto de la primera columna. En nuestro ejemplo, el mayor elemento de 1, 2 y 1 es 2, ubicado en la segunda fila. Ahora intercambiamos la segunda fila con la primera obteniendo la siguiente matriz:


2.- Mediante operaciones elementales, hacemos ceros todos los elementos de la primera columna, excepto la primera fila.



Ahora hacemos cero la primera columna de la tercera fila.


3.- Ahora buscamos la fila con el mayor elemento en valor absoluto de la segunda columna, excepto la primera fila pues ya ha sido procesada. En este caso, como ambos son igual, no es necesario hacer un cambio.

4.- Mediante operaciones elementales hacemos ceros todos los elementos de la segunda columna pero sin alterar la primera y segunda fila. Con esto la matriz nos quedaría de la siguiente manera:


Ahora calculamos la matriz multiplicando los elementos de la diagonal. El resultado obtenido es -2 y como el número de cambios fue impar, entonces multiplicamos por .1 obteniendo 2 como resultado final. La implementación en Java de este algoritmo es la siguiente:

public class MatrizUtil {

    public static double[][] intercambiarFilasMatriz(double[][] matriz, int i, int j) {
        double temp;
        for (int k = 0; k < matriz[0].length; k++) {
            temp = matriz[i][k];
            matriz[i][k] = matriz[j][k];
            matriz[j][k] = temp;
        }
        return matriz;
    }

    public static void imprimirMatriz(double[][] matriz) {
        for (int i = 0; i < matriz.length; i++) {
            for (int j = 0; j < matriz[0].length; j++) {
                System.out.print(matriz[i][j] + " ");
            }
            System.out.println("");
        }
    }

    public static int pivoteMatriz(double[][] matriz, int i) {
        int piv = i;
        double v = matriz[i][i];
        for (int j = i + 1; j < matriz.length; j++) {
            if (Math.abs(matriz[j][i]) > v) {
                v = matriz[j][i];
                piv = j;
            }
        }
        return piv;
    }

    /**
     * 
     * @param m es una matriz cuadrada
     * @return 
     */
    public static int eliminaAdelante(double[][] m) {
        int numeroIntercambios = 0;
        int filaPivote = -1;
        for (int columnaEvaluada = 0; columnaEvaluada < m.length; columnaEvaluada++) {
            filaPivote = pivoteMatriz(m, columnaEvaluada);
            if (filaPivote != columnaEvaluada) {
                m = intercambiarFilasMatriz(m, columnaEvaluada, filaPivote);
                numeroIntercambios++;
            }
            for (int i = columnaEvaluada + 1; i < m.length; i++) {
                for (int j = columnaEvaluada + 1; j < m.length; j++) {
                    if (m[columnaEvaluada][columnaEvaluada] == 0) {
                        System.out.println("Error, división por cero");
                        System.exit(1);
                    } else {
                        m[i][j] = m[i][j] - (m[i][columnaEvaluada] * m[columnaEvaluada][j] / m[columnaEvaluada][columnaEvaluada]);
                    }
                }
                m[i][columnaEvaluada] = 0;
            }
        }
        return numeroIntercambios;
    }

    public static double det(double[][] m) {
        int numeroIntercambios = MatrizUtil.eliminaAdelante(m);
        double det = 1;
        for (int i = 0; i < m.length; i++) {
            det *= m[i][i];
        }
        if (numeroIntercambios % 2 == 1) {
            det = -det;
        }
        return det;
    }
}
Ahora, podemos percatarnos que para convertir a cero algunos elementos de la matriz utilizamos una fórmula la cual se muestra a continuación:
m[i][j] = m[i][j] - (m[i][columnaEvaluada] * m[columnaEvaluada][j] / m[columnaEvaluada]
Esta fórmula se obtiene de la siguiente manera:

Dada la matriz:


Para convertir a 0 un determinado elemento debemos hacer la siguiente operación elemental: 


La constante obtenida se aplicará a toda la fila pues es una operación elemental, quedando de la fórmula tal como está en la implementación:


También les comparto el método main de prueba:
public static void main(String[] args) {
    double[][] matriz = {{1, 0, 2}, {2, 1, 1}, {1, 1, 1}};
    System.out.println(MatrizUtil.det(matriz));
}
Espero que este artículo les sea de utilidad, hasta una próxima publicación.

Divertida ola de eventos invade Facebook

Desde hace algunos días, cada mañana al despertar podía percatarme con muchos de mis amigos y contactos confirmaban sus asistencia a disparatados eventos de Facebook. Algunos menos graciosos que otros pero al final todos descabellados, el crear este tipo de eventos es la nueva moda en la red social más popular de Internet. Algo que he podido notar es que estos eventos no son organizados solamente en Perú (Saqueo a la tiendita de Don Pepe) sino que ya son muchos los países que forman parte de esta nueva tendencia viral; pero vayamos al origen del asunto.

Todo habría comenzado en Chile en donde el Movimiento Gremial de la Pontificia Universidad Católica de Chile organizó el evento "Almorzando con Cecilia Morel", el cual consiste en llevar tu propia comida y compartir una charla con la ex primera dama de Chile. A muchas personas les pareció algo ridículo y, modo de burla, comenzaron a crear invitaciones a desayunos y marchas falsas como parodia, según el Utero.pe.

Aquí les comparto algunos de los eventos más graciosos con los que, hasta ahora, me he topado:


Como toda tendencia, en algún momento se terminará y Facebook nos sorprenderá con alguna cosa nueva.

jueves, 29 de mayo de 2014

Verificar la disponibilidad de los webservices del SRI

Muchas veces, mientras desarrollamos nuestras aplicaciones de facturación electrónica, precisamos de saber el estado de los servicios web del SRI. En este artículo les presento una manera de poder verificar su disponibilidad para poder emitir nuestros comprobantes bajo un tipo de emisión normal o en contingencia, según sea el caso. Luego de haber creado nuestro cliente proxy, podemos hacer uso de las clases que se generan para poder determinar el estado de conexión mediante el siguiente método:
public static Object getWebService(String wsdlLocation) {
    try {
        QName qname = new QName("http://ec.gob.sri.ws.recepcion", "RecepcionComprobantesService");
        URL url = new URL(wsdlLocation);
        RecepcionComprobantesService service = new RecepcionComprobantesService(url, qname);
        return null;
    } catch (MalformedURLException ex) {
        return ex;
    } catch (WebServiceException ws) {
        return ws;
    }
}

public static boolean existeConexion(String url) {
    int i = 0;
    boolean respuesta = false;
    while (i < 3) {
        Object obj = getWebService(url);
        if (obj  == null) {
            return true;
        }
        if ((obj  instanceof WebServiceException)) {
            respuesta = false;
        }
        i++;
    }
    return respuesta;
}
El código podemos ejecutarlo de la siguiente manera:
public static void main(String[] args) {
    System.out.println(existeConexion("https://celcer.sri.gob.ec/comprobantes-electronicos-ws/RecepcionComprobantes?wsdl"));
}
Espero que este método les sea de utilidad. No se olviden de seguirnos a través de nuestra página en Facebook.

martes, 27 de mayo de 2014

Implementación en Java de un perceptrón simple

Un perceptrón es la unidad básica de inferencia, siendo capaz de realizar tareas de clasificación de forma automática. En la red podemos encontrar bastante información relacionada al perceptrón simple, sin embargo en este artículo vamos a poner énfasis en su implementación utilizando el lenguaje Java. La arquitectura básica de un perceptrón es la que se muestra a continuación:


Vamos a describir el algoritmo que emplearemos para implementar nuestro perceptrón simple. En primer lugar vamos a conocer cuáles son las entradas; la siguiente imagen muestra los inputs de nuestro algoritmo.


La constante de proporcionalidad η es un parámetro positivo que se llama tasa de aprendizaje puesto que cuanto mayor es, más se modifica el peso sináptico y viceversa. Es decir, es el parámetro que controla el proceso de aprendizaje. Cuando es muy pequeño la red aprende poco a poco. Cuando se toma constante en todas las iteraciones, η(k) =η > 0 tendremos la regla de adaptación con incremento fijo.

También podemos notar que tanto los vectores de pesos como de valores de entrada tienen como cantidad de elementos a n+1. Esto se debe a que hemos agregado al nivel de umbral como una entrada más. El umbral se puede considerar como el peso sináptico correspondiente a un nuevo sensor de entrada que tiene siempre una entrada igual a Xn+1=−1 y como peso sináptico el valor del umbral.

Ahora vamos a empezar con la inicialización de variables. Recordemos que es muy importante incializar nuestro vector de pesos siempre con valores diferentes en cada ejecución del programa.


Y el proceso queda descrito de la siguiente manera:


Y ahora la codificación:
public class Perceptron {

    private double[] pesos;
    private double[] objetivos;
    private double[][] entradas;
    private int numeroEntradas;
    private static final double TASA_APRENDIZAJE = 0.5d;

    public double[][] getEntradas() {
        return entradas;
    }

    public void setEntradas(double[][] entradas) {
        this.entradas = entradas;
        this.numeroEntradas = entradas[0].length;
    }

    public double[] getObjetivos() {
        return objetivos;
    }

    public void setObjetivos(double[] objetivos) {
        this.objetivos = objetivos;
    }

    public double[] getPesos() {
        return pesos;
    }

    public void setPesos(double[] pesos) {
        this.pesos = pesos;
    }

    /**
     * Inicializar los pesos sinápticos con números aleatorios del intervalo [-1, 1]
     */
    public void inicializarPesos() {
        pesos = new double[numeroEntradas];
        for (int i = 0; i < numeroEntradas; i++) {
            pesos[i] = Math.random();
        }
    }

    public void imprimirPesos() {
        for (int i = 0; i < numeroEntradas; i++) {
            System.out.println("W[" + i + "] = " + pesos[i]);
        }
    }

    /**
     * wj(k+1)=wj(k)+&#951;[z(k)&#8722;y(k)]xj(k), j =1,2,...,n+1
     */
    public void recalcularPesos(int posicionEntrada, double y) {
        for (int i = 0; i < pesos.length; i++) {
            pesos[i] = pesos[i] + TASA_APRENDIZAJE * (objetivos[posicionEntrada] - y) * entradas[posicionEntrada][i];
        }
    }

    public void entrenar() {
        int indice = 0;
        double yi = 0;
        while (indice < entradas.length) {
            double suma = 0;
            for (int i = 0; i < numeroEntradas; i++) {
                suma += (pesos[i] * entradas[indice][i]);//&#8721; x[i] * W[i] 
            }
            yi = suma >= 0 ? 1 : -1;
            if (yi == objetivos[indice]) {
                //Correcto
                for (int i = 0; i < numeroEntradas; i++) {
                    System.out.print(entradas[indice][i] + "t");
                }
                System.out.print(" => Esperada = " + objetivos[indice] + ", Calculada = " + yi + "n");
            } else {
                //Incorrecto
                for (int i = 0; i < numeroEntradas; i++) {
                    System.out.print(entradas[indice][i] + "t");
                }
                System.out.print(" => Esperada = " + objetivos[indice] + ", Calculada = " + yi + " [Error]n");
                System.out.println("Corrección de pesos");
                recalcularPesos(indice, yi);
                imprimirPesos();
                System.out.println("--");
                indice = -1;
            }
            indice++;
        }
    }
}
Ahora hagamos una prueba con entrenando a nuestro perceptrón para que reconozca la función lógico OR, tal como se tabula a continuación:

Para esto desarrollamos una clase de prueba.
public class Test {

    public static void main(String[] args) {
        Perceptron p = new Perceptron();
        //Salidas esperadas
        double[] objetivos = {1, 1, 1, -1};
        //Entradas
        //x1, x2, &#952;
        double[][] entradas = {
            {1, 1, -1},
            {1, -1, -1},
            {-1, 1, -1},
            {-1, -1, -1}
        };
        p.setEntradas(entradas);
        p.setObjetivos(objetivos);
        p.inicializarPesos();
        p.entrenar();
        System.out.println("********** Pesos Finales **********");
        p.imprimirPesos();
    }
}
Obteniendo el siguiente resultado:
1.0 1.0 -1.0  => Esperada = 1.0, Calculada = 1.0
1.0 -1.0 -1.0  => Esperada = 1.0, Calculada = -1.0 [Error]
Corrección de pesos
W[0] = 1.9944020684085446
W[1] = -0.4272180776608493
W[2] = -0.3794857322622548
--
1.0 1.0 -1.0  => Esperada = 1.0, Calculada = 1.0
1.0 -1.0 -1.0  => Esperada = 1.0, Calculada = 1.0
-1.0 1.0 -1.0  => Esperada = 1.0, Calculada = -1.0 [Error]
Corrección de pesos
W[0] = 0.9944020684085446
W[1] = 0.5727819223391507
W[2] = -1.3794857322622547
--
1.0 1.0 -1.0  => Esperada = 1.0, Calculada = 1.0
1.0 -1.0 -1.0  => Esperada = 1.0, Calculada = 1.0
-1.0 1.0 -1.0  => Esperada = 1.0, Calculada = 1.0
-1.0 -1.0 -1.0  => Esperada = -1.0, Calculada = -1.0
********** Pesos Finales **********
W[0] = 0.9944020684085446
W[1] = 0.5727819223391507
W[2] = -1.3794857322622547
Con los pesos finales, tenemos a nuestra red neuronal entrenada. Los campos de aplicación del perceptrón simple son muy reducidos pues su aprendizaje llega a un estado de convergencia solo cuando los elementos separables y los no separables pueden ser llevados a un plot en el cual puedan ser separados por un hiperplano. En la siguiente imagen, el caso a sí puede ser aprendido por un perceptrón simple mientras que el caso b no podría ser aprendido por un solo perceptrón. 


Espero que este articulo les sea de utilidad. Cualquier consulta, no duden en comentarla.

sábado, 24 de mayo de 2014

Creación de un datasource en Websphere Application Server

IBM WebSphere Application Server (WAS, servidor de aplicaciones WebSphere),un servidor de aplicaciones de software, es el producto estrella dentro de la familia WebSphere de IBM. WAS está construido usando estándares abiertos tales como J2EE, XML, y Servicios Web[1].
En éste artículo veremos, paso a paso, la manera cómo crear un origen de datos en este servidor de aplicaciones.


Entramos a seguridad luego seguridad global.


Luego jaas y datos de autenticación de j2c.


Aquí le damos click en nuevo.


Y se desplega una ventana donde llenar data para autenticar con el Server.


Le damos aceptar y luego nos lleva a la pantalla anterior donde le damos guardar.


Luego nos vamos a recursos → jdbc → proveedores de jdbc.


Click en nuevo y llenamos el formulario, en este caso es una db oracle.


Click en siguiente y nos aparece una pantalla donde debemos dar la ruta para el jar oracle, en este caso uso oracle6.jar y lo ubicaremos en el disco D.


Click en siguiente y veremos la configuración.


Click en finalizar y luego en la nueva ventana click en guardar.


Luego en jdbc → origenes de datos.


Click en nuevo y llenamos el formulario


Click en siguiente y elegir un proveedor de jdbc, en este caso ya tengo 2 y puedo usar cualquiera.


Click en siguiente y ahora nos pedirá la ruta de nuestra base de datos en el campo valor colocamos toda la ruta.


Click en siguiente y sólo llenamos el primer y ultimo campo.


Click en siguiente.


Click en finalizar y en la nueva pantalla guardar.


Y ya tenemos configurado nuestro Websphere Application Server. Gracias a nuestro colaborador Larry Valderrama.

jueves, 22 de mayo de 2014

Introducción a Scheme y la Programación Funcional

Scheme es un lenguaje de programación basado en el paradigma funcional, es uno de los dialectos más conocidos de Lisp y la esencia de su implementación se basa en el siguiente principio: "Los lenguajes no se deberían desarrollar añadiendo muchas características, sino quitando las debilidades y las limitaciones que hacen que las características adicionales parezcan necesarias". Para poder comprender a este lenguaje es importante entender el concepto de lista que, si bien es cierto no es la única estrucutura de datos, sí es la más importante.

En este primer artículo mostraré el uso de algunos conceptos básicos como son los operadores, las condicionales y la recursión, los cuales servirán para familiarizarnos un poco con la sintaxis de Scheme.

1.- El clásico ejemplo del factorial de un número
En este ejemplo podemos apreciar el uso de la ejecución condicional a través de la función cond cuya sintaxis es la siguiente:

(cond (<condition1> <result1>)
(<condition2> <resultt2>) …
(<conditionn> <resultn>)
(else <else-result>) ;optional else clause
)
(define (factorial n)
  (cond ((= n 1) 1)
        (else (* n (factorial (- n 1))))
        )
  )
2.- Sumatoria desde 1 hasta n
(define (suma n)
  (cond ((= n 0) 0)
        (else (+ n (suma (- n 1))))
    )
  )
3.- Valor absoluto
(define (valor_absoluto x)
  (cond ((< x 0) (* -1 x))
        (else x)
        )
  )
4.- Longitud de una lista
(define (longitud x)
  (cond ((null? x) 0)
        (else (+ 1 (longitud (cdr x))))
  )
  )
5.- Sumatoria de los elementos de una lista
La función car devuelve el primer elemento de una lista.
(define (suma_lista x)
  (cond ((null? x) 0)
        (else (+ (car x) (suma_lista (cdr x))))
    )
  )
6.- Concatenación de dos listas
(define (concatenar x y)
  (cond ((null? x) y)
        (else (cons (car x)
                    (concatenar (cdr x) y)
               )
              )
        )
 )
7.- Determinar si un elemento es atómico
(define (atom? x)
 (cond ((symbol? x) #t)
 ((number? x) #t)
 ((char? x) #t)
 ((string? x) #t)
 ((null? x) #t)
 (else #f)
 )
 )
8.- Contar la cantidad de elementos atómicos de una lista
(define (cantidad_elementos_atomicos x)
  (cond ((null? x) 0)
        ((atom? x) 1)
        (else (+ (cantidad_elementos_atomicos (car x)) (cantidad_elementos_atomicos (cdr x))
                 )
              )
    )
  )
En un siguiente artículo hablaremos acerca del lenguaje de programación Racket, el cual usaremos para implementar fractales.