viernes, 7 de diciembre de 2012

SPAUN, primer cerebro sintético que modela un cerebro biológico

Investigadores canadienses acaban de revelar que han dado uno de los pasos más monumentales hacia la creación de inteligencias artificiales, creando un sistema al que llaman Spaun (o SPAUN por las siglas en inglés de "Semantic Pointer Architecture Unified Network").

Spaun es nada más ni nada menos que el primer modelo a gran escala que trata de simular todo el funcionamiento de un cerebro, aunque de forma primitiva, pero lo asombroso de este modelo es que totalmente por su cuenta es capaz de ver, recordar, pensar, razonar y escribir números.

Y asombrosamente, su nivel de comprensión y deducción es casi tan bueno como el de seres humanos.

Por ejemplo, sin entrenamiento previo, si se le presenta a Spaun estas dos secuencias de números:
1 2 3
5 6 7

...y después se le presenta esta otra secuencia:
3 4 ?

...y se le pide que rellene el número que va en el "?", Spaun correctamente no solo identifica el número "5", sino que incluso provee la respuesta escribiéndola "a mano" (pues ha aprendido la forma en que se escriben los números).

Noten que esto es algo que se hace sin pre-programar a Spaun para que entienda estos conceptos, sino que son sus propios patrones de reconocimiento y razonamiento internos los que lo llevan a deducir, de forma autónoma, la respuesta.

En cuanto a cómo funciona Spaun, este fue construído no como una secuencia de programas "a fuerza bruta", sino que literalmente imitando un cerebro desde sus partes más primitivas. Spaun literalmente está compuesto de neuronas sintéticas que disparan cargas eléctricas, las cuales fluyen a través de neurotransmisores somo en cerebros biológicos.

Incluso se modelaron varias partes del cerebro humano como son aquellas regiones que descodifican señales visuales (pues a Spaun no se le proveen las preguntas en un programa digital, sino que este literalmente "ve" con ojos sintéticos las preguntas que se le escriben), o las regiones encargadas de procesar movimientos (para poder escribir por ejemplo), o de memorizar, etc.

Así que Spaun literalmente tiene que aprender no solo a entender el mundo por sus ojos, sino que deducir la simbología que aparece en su visión (como son los números escritos), y deducir su significado, así como extraer patrones, y después poder pensar por sí mismo el significado de toda esa información, y finalmente poder hacer hipótesis y buscar respuestas que termina expresando escribiéndolas.

Pero quizás tan asombroso como todo esto es el hecho de que Spaun cometió los mismos tipos de errores comunes a seres humanos. Por ejemplo, al igual que nosotros, es mucho mejor en recordar los primeros o últimos números de alguna secuencia aleatoria, que a recordar toda la secuencia, entre otras idiosincracias de los seres humanos biológicos.

Sin embargo, es bueno aclarar que este es apenas un primer paso, pues Spaun simula el equivalente a un segundo de actividad neuronal de un ser biológico, en varias horas, y por el momento sus poderes de razonamiento están limitados a simples números.

Pero por otro lado, el hecho de que ya poseamos tecnología que nos permite crear este tipo de complejidad, nos dice que estamos ciertamente cerca (entre 2 a 5 décadas) de organismos sintéticos que posiblemente contengan el nivel intelectual de humanos, y cuando ese tiempo llegue, llegaremos a la cúspide de este escenario(en cuyo proceso ya estamos), y el mundo nunca volverá a ser igual...




Fuente: http://eliax.com/index.cfm?post_id=9838

CÓDIGO PARA MÉTODO DE  BISECCIONES SUCESIVAS EN C++


#include <iostream>
#include <cmath>
using namespace std;
double f(double x);
double biseccion ( double a, double b, double tol, int maxlter);
int main()
{
    double a, b, tol, raiz;
    int maxlter;
    cout<< "por favor digite a:  ";
    cin>>a;
    cout<< "por favor digite b:  ";
    cin>>b;
    cout<< "por favor digite tol:  ";
    cin>>tol;
    cout<< "por favor digite maxlter:  ";
    cin>>maxlter;
    raiz=biseccion(a,b,tol,maxlter);
    cout<<"La raiz es: "<< raiz <<endl;
    system("pause");
    return 0;
}
 
 double f(double x)
 {
        return x*x*x+4*x*x-10;
 }
 double biseccion(double a, double b, double tol, int maxlter)
 {
        double c;
        int nolter=0;
        do
        {
            c=(a+b)/2;
            if(f(a)*f(c)<0)
            {
               b=c;
            }
            else
            {
               a=c;
            }
            cout<<nolter<<"\t"<<a<<"\t"<<b<<"\t"<<c<<"\t"<<f(c)<<endl;
            nolter++;
         }
         while((abs(f(c))>tol)&&(nolter<maxlter));
         return c;
 }

MÉTODO DE BISECCIONES SUCESIVAS

El método de bisecciones sucesivas se genera de un intervalo donde al tabular  se genera un cambio de signo con el cambio de signo se llega a la conclusión de que allí se genera un raíz, en ese momento se genera un intervalo, normalmente se toma el valor anterior al cual esta cambiando de signo y el valor en donde cambio de signo por lo tanto debe cumplir.
f(xa)f(xb) < 0

Una ves ya obteniendo los dos valores xa y xse genera un nuevo intervalo sumando
Xm= (xa – xb) / 2
ejemplo de la tabulación.

x
f(x)
xa
f(xa)     (+,-)
xm
f(xm)      + Significa que f(xm)f(xb) < 0
              - Significa que f(xm)f(xb) < 0
xb
f(xb)     (+,-)


COMPROBANDO EL MÉTODO CON LA SIGUIENTE FUNCIÓN.
f(x)=3 x Sen x-1

Colocamos algunos valores (cuales quiera) de preferencia cero y el otro valor otro superior al cero yo puse tres, estos valores son para que nos aproximemos a la raíz.

f(0)=3 (0) Sen(0) -1= -1             

f(3)=3 (3) Sen(3) -1= 0.2700800725             

Ahora calculamos el siguiente intervalo para acercarnos a la raíz, observar que los valores que obtuvimos son positivos y negativos (+,-).

Xm= (0+3) / 2=1.5

Para observar mejor los valores que se aproxima se recomienda tabular pero no es necesario.

X
F(X)
0
F(0)= -1
1.5
F(1.5)= 3.48872744
3
F(3)= 0.2700800725


Xm= (0+1.5) / 2=0.75
X
F(X)
0
F(0)= -1
0.75
F(0.75)= 0.5336872101
1.5
F(1.5)= 3.48872744

Xm= (0+0.75) / 2=0.375

X
F(X)
0
F(0)= -1
0.375
F(0.375)= -0.5879434048
0.75
F(0.75)= 0.5336872101


Xm= (0+0.375) / 2=0.1875

X
F(X)
0
F(0)= -1
0.1875
F(0.1875)= -0.8951481456
0.375
F(0.375)= -0.5879434048


Xm= (0+0.1875) / 2=0.09375

X
F(X)
0
F(0)= -1
0.09375
F(0.09375)= -0.9736714193
0.1875
F(0.1875)= -0.8951481456


Método de las aproximaciones sucesivas


Descripción

El método de las aproximaciones sucesivas es uno de los procedimientos más importantes y más sencillos de codificar. Supongamos la ecuación

donde f(x) es una función continua que se desea determinar sus raíces reales. Se sustituye f(x) por la ecuación equivalente

Se estima el valor aproximado de la raíz x0, y se sustituye en el segundo miembro de la ecuación para obtener x1.

Poniendo x1 como argumento de j(x), obtendremos un nuevo número x2, y así sucesivamente. Este proceso se puede sintetizar en la fórmula.
 (1)
Si esta secuencia es convergente es decir, tiende hacia un límite, la solución x es

FIG14_01.gif (2477 bytes)
El método de iteración se explica geométricamente mediante el gráfico de la figura. Se dibuja la curva y=j(x), y la recta y=x, bisectriz del primer cuadrante. La abscisa x del punto de intersección es la raíz buscada.
Un ejemplo típico es la de encontrar la raíz de la ecuación

Para encontrar la raíz, se comienza en el punto cualquiera de abscisa x0 dentro del intervalo (0, p/2), y se traza la línea vertical hasta que interseca la curva, luego, desde este punto, se traza una línea horizontal hasta que se alcanza la recta bisectriz, este punto tendrá por abscisa x1. Se traza de nuevo, una línea vertical hasta encontrar a la curva, y otra línea horizontal hasta encontrar la línea recta, el punto de intersección tiene de abscisa x2 , y así sucesivamente. Como podemos apreciar en la figura, la sucesión x1, x2, x3... tiende hacia la raíz x de la ecuación buscada.
Tal como nos sugiere la representación gráfica de la función en la figura, la raíz buscada está en el intervalo 0 a p/2. Tomamos una aproximación inicial a la raíz x0, en dicho intervalo y aplicamos la fórmula (1), su codificación no presenta grandes dificultades.
        double x=0.5;
        while(true){
            x=Math.cos(x);
        }

La condición de finalización

Primero, introducimos el valor inicial x, la primera aproximación, calculamos el valor del coseno de x, el valor devuelto (segunda aproximación), lo guardamos de nuevo en la variable x, y repetimos el proceso indefinidamente. El código aunque correcto, necesita terminarse en algún momento, cumpliendo una determinada condición. Cuando el valor absoluto del cociente entre la diferencia de dos términos consecutivos de la sucesión y uno de los términos, sea menor que cierta cantidad e.

Este criterio, no es completamente riguroso, pero es un buen punto de partida para el estudio de este método. Volvemos a escribir el código incluyendo la condición de terminación y dentro de una función denominada raiz, a la que se le pasa el valor inicial y que devuelve la raíz buscada
    final double ERROR=0.001;
    double raiz(double x0){
        double x1;
        while(true){
            x1=Math.cos(x0);
            if(Math.abs((x1-x0)/x1)<ERROR)   break;
            x0=x1;
        }
        return x0;
    }
En primer lugar, fijamos el valor de la constante e o ERROR. Introducimos la primera aproximación a la raíz, y la guardamos en la variable x0, calculamos su coseno y obtenemos la segunda aproximación, la guardamos en la variable x1. Verificamos si se cumple la condición de terminación. En el caso de que no se cumpla, x0 toma el valor de x1 y se repite el proceso. En el momento en que se cumpla la condición de terminación, se sale del bucle y la función devuelve la raíz buscada. Como podemos observar las variables x0 y x1 guardan dos términos consecutivos de la sucesión que tiende hacia la raíz de la función.

La clase que describe el procedimiento

Queremos que el procedimiento numérico sea independiente de la función f(x) cuya raíz deseamos averiguar. Para ello, creamos una clase base abstracta denominada Ecuacion con una función miembro raiz que defina el procedimiento numérico, y que deje sin definir la función f(x), declarándola abstracta, dejando a las clases derivadas de Ecuacion la definición de la función f(x) particular.
public abstract class Ecuacion {
    protected static final double ERROR=0.001;

    public double raiz(double x0){
        double x1;
        while(true){
            x1=f(x0);
            if(Math.abs(x1-x0)<ERROR)   break;
            x0=x1;
        }
        return x0;
    }

    abstract public double f(double x);
}
Las clases derivadas denominadas Funcion1 y Funcion2 definen la función f(x)
public class Funcion1 extends Ecuacion{
    public double f(double x){
        return Math.cos(x);
    }
}
public class Funcion2 extends Ecuacion{
    public double f(double x){
        return Math.pow(x+1, 1.0/3);
    }
}
Creamos objetos de las clases derivadas y llamamos desde ellos a la función raiz que describe el procedimiento numérico
        Funcion1 f1=new Funcion1();
        System.out.println("solucion1 "+f1.raiz(0.5));
        System.out.println("solucion1 "+f1.raiz(0.9));
        Funcion2 f2=new Funcion2();
        System.out.println("solucion1 "+f2.raiz(0.5));
En las dos primeras llamadas a la función raiz comprobamos que la solución buscada no depende del valor inicial de partida x0, que en el primer caso es 0.5 y en el segundo caso es 0.9.

El criterio de convergencia

No todas las ecuaciones pueden resolverse por este método, solamente si el valor absoluto de la derivada de la función j(x) en la vecindad de la raíz x es menor que la unidad (la pendiente de la recta bisectriz del primer cuadrante es uno). En la figura, podemos ver como es imposible encontrar la solución marcada por un puntito negro en la intersección entre la curva y la recta bisectriz del primer cuadrante, ya que la sucesión xi diverge.
FIG14_02.gif (3042 bytes)
Por ejemplo, la ecuación

tiene una raíz en el intervalo (1, 2) ya que f(1)=-1<0 y f(2)=5>0. Esta ecuación puede escribirse de la forma

En este caso,

y por tanto,

en consecuencia, no se cumplen las condiciones de convergencia del proceso de iteración. Si escribimos la ecuación en la forma

como podrá verificar fácilmente el lector, cumple las condiciones de convergencia, obteniéndose rápidamente un valor aproximado de la raíz buscada.

Ejemplos

Resolver por el método de aproximaciones sucesivas las siguientes ecuaciones. Primero hay que ponerlas de la forma x=f(x).






martes, 11 de septiembre de 2012

Bueno esta vez les dejo el link de una noticia por demas interesante, Cientificos de North Carolina State University en EEUU, transformaron unas cucarachas en seres bionicos, esta noticia es por demas muy interesante por las aplicaciones que podrai darsele, el link es tomado del blog de Eliax, no esta demas recomendarselos ya que siempre esta a la vanguardia en noticias sobre tecnologia.

http://eliax.com/index.cfm?post_id=9660

Errores

Bueno aqui les dejo un link sobre errores que me proporciono un amigo que tambien tiene un blog similar al mio:
http://users.dsic.upv.es/asignaturas/eui/cnu/prac/p3/cnu-p3.pdf

Teoria del error: epsilon de la maquina

Este es le primer tema que tratamos en la clase de metodos numericos, al parecer un tema bastante comun, pero bastante desconocido en general incluso para nosotros que estamos estudiando una ingenieria, bueno en general la definicion seria masomenos esta:


El epsilon es el número decimal más pequeño que, sumado a 1, la computadora nos arroja un valor diferente de 1, es decir, que no es redondeado.



Para comprobar esto hicimos varios experimentos en el salon y laboratorio entre ellos: la calculadora, un ipod, hoja de calculo y un programa en c++.

Un ejemplo facil de realizar en cualquier calculadora por si desean ver esto seria el siguiente:

1.-Vamos a su calculadora e introducen el numero 1 y luego teclean =.
2.-A continuacion presionan el boton ANS y lo dividen entre dos: ANS/2 .
3.-A continuacion presionen la tecla =, repitan este proceso varias veces, despues sumen 1 y dependiendo de que calcudora utilizen en un momento dado la suma le dara 1.

Esto resulta un poco extraño ¿No creen? , si su calculadora sigue marcando un numero, porque al sumarle el 1, sigue dando exactamanete uno, esto es por una aproximacion o redondeo que depende de la capacidad que tenga su maquina.

En mi calculadora que es una Casio fx-991ES despues de presionar la tecla = 31 veces por fin obtengo el epsilon de la maquina, resulta curioso que al realizarlo en un Ipod se obtenga mas presicion en los datos.